diff --git a/.gn b/.gn index 89f22ef..4aa9891 100644 --- a/.gn +++ b/.gn
@@ -128,9 +128,7 @@ "//extensions/browser/api/test:*", # 1 error "//extensions/browser/api/usb:*", # 12 errors "//extensions/browser/api/virtual_keyboard_private:*", # 2 errors - "//extensions/browser/api/vpn_provider:*", # 13 errors "//extensions/browser/api/web_request:*", # 37 errors - "//extensions/browser/api/webcam_private:*", # 8 errors "//extensions/browser/api:*", # 7 errors "//extensions/browser/updater:*", # 31 errors "//extensions/browser:*", # 20 errors
diff --git a/BUILD.gn b/BUILD.gn index d224910..46462a3 100644 --- a/BUILD.gn +++ b/BUILD.gn
@@ -81,6 +81,8 @@ "//services/service_manager/public/cpp", "//skia:skia_unittests", "//sql:sql_unittests", + "//third_party/angle/src/tests:angle_end2end_tests", + "//third_party/angle/src/tests:angle_white_box_tests", "//third_party/flatbuffers:flatbuffers_unittests", "//third_party/liburlpattern:liburlpattern_unittests", "//tools/binary_size:binary_size_trybot_py", @@ -190,7 +192,6 @@ "//mojo:mojo_unittests", "//net:net_perftests", "//storage:storage_unittests", - "//third_party/angle/src/tests:angle_end2end_tests", "//third_party/angle/src/tests:angle_unittests", "//third_party/blink/common:blink_common_unittests", "//third_party/blink/renderer/controller:blink_unittests", @@ -241,7 +242,6 @@ "//google_apis/gcm:mcs_probe", "//media/capture:capture_unittests", "//media/cast:cast_unittests", - "//third_party/angle/src/tests:angle_white_box_tests", "//third_party/catapult/telemetry:bitmaptools($host_toolchain)", ] } else if (is_ios) { @@ -482,7 +482,7 @@ } } - if (is_ios || is_win || (is_linux || is_chromeos_lacros)) { + if (is_ios || is_win || (is_linux || is_chromeos_lacros) || is_fuchsia) { deps += [ "//base:base_i18n_perftests", "//google_apis:google_apis_unittests",
diff --git a/DEPS b/DEPS index 6cadb8b..2ede054 100644 --- a/DEPS +++ b/DEPS
@@ -203,7 +203,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '2779617a24693e22ad550b0b15467568c5a4a1ee', + 'v8_revision': '43ed322b6a782285f8fcfbaadd3926c371c3a60b', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -211,11 +211,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': 'c600e47812c88d45087582122dbb004851ae966b', + 'angle_revision': 'de32c3d2de006a2c8d2acfa829634fcf2d1564ab', # 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': '009667d5f97c46652d9a804b3579e28fd692a43e', + 'swiftshader_revision': '3549479dc4ccd92ef3b9e179080dcec1a430b01d', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. @@ -266,7 +266,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': '43761d2e076c2c0d8e14a136c830c899b9fa17f4', + 'catapult_revision': 'd1a3011cd91205aa96b74b5dfc227d391e88108d', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -274,7 +274,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': '6f4e54f003dd3094626dd026fbb4c4fcbb7b52d6', + 'devtools_frontend_revision': 'd08c5531762807570b5a929d3496eae8632bf2b5', # 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. @@ -314,11 +314,11 @@ # 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': '99c3a691c23dbd75075eb852d2f6a1c569148826', + 'dawn_revision': 'ea26a8ce553fe2efa94830f3d7326072487bde3f', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'quiche_revision': '425c25a8ad2d190f61531fd46e0a65050cc1b98a', + 'quiche_revision': '002828690efcb43cecc5972d695d49b0953d2ad9', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ios_webkit # and whatever else without interference from each other. @@ -364,7 +364,7 @@ # revisions. # GN CIPD package version. - 'gn_version': 'git_revision:0d67e272bdb8145f87d238bc0b2cb8bf80ccec90', + 'gn_version': 'git_revision:595e3be7c8381d4eeefce62a63ec12bae9ce5140', # Also, if you change these, update buildtools/DEPS too. Also update the # libc++ svn_revision in //buildtools/deps_revisions.gni. @@ -893,7 +893,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'c1aa4ecfcc8cbbbcf21e1b77125aa602339846ec', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '82b992a1656d7d1cd0ee3cbea8ff609ffdfed380', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), @@ -1249,7 +1249,7 @@ Var('chromium_git') + '/external/github.com/cisco/openh264' + '@' + '3dd5b80bc4f172dd82925bb259cb7c82348409c5', 'src/third_party/openscreen/src': - Var('chromium_git') + '/openscreen' + '@' + 'f9e9052e7e6f1f75212737926b267a0e41621892', + Var('chromium_git') + '/openscreen' + '@' + '6051838253185d8478f5fa4d70c96ef6c0241f94', 'src/third_party/openxr/src': { 'url': Var('chromium_git') + '/external/github.com/KhronosGroup/OpenXR-SDK' + '@' + '97cfe495bb7a3853266b646d1c79e169387f9c7a', @@ -1266,7 +1266,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + 'bdc7f626dbce0778814d8987aef3402113ca6241', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '53a231c0ae868366179bd560b68a2f5f4b166541', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1518,7 +1518,7 @@ Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '3c2fe3888658d82b47ca831d59a2e07579619c2d', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + 'ad0be281a41cc402c247c23206eba81be73ab401', + Var('webrtc_git') + '/src.git' + '@' + '1c5e63e5451374783aaf0259f5c23d3688a5b2ff', 'src/third_party/libgifcodec': Var('skia_git') + '/libgifcodec' + '@'+ Var('libgifcodec_revision'), @@ -1590,7 +1590,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@d0ccd38b2dfb8aa50214dd87000a8c30cb37258f', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@6f7379c80b03c2f1aac2182807e684f7694accbd', 'condition': 'checkout_src_internal', },
diff --git a/WATCHLISTS b/WATCHLISTS index a47f5c55..283209c 100644 --- a/WATCHLISTS +++ b/WATCHLISTS
@@ -118,6 +118,7 @@ 'filepath': 'chrome/browser/apps/app_service/'\ '|chrome/browser/ui/app_list/app_service/'\ '|chrome/browser/ui/ash/launcher/app_service/'\ + '|chrome/browser/ui/views/apps/app_dialog/' \ '|components/services/app_service/', }, 'app_shortcuts': { @@ -1038,6 +1039,10 @@ 'fuchsia': { 'filepath': 'fuchsia', }, + 'full_restore': { + 'filepath': 'chrome/browser/chromeos/full_restore/|' \ + 'components/full_restore/' + }, 'fuzzing': { 'filepath': 'fuzz|Fuzz', }, @@ -2517,6 +2522,7 @@ 'thestig@chromium.org'], 'fsp': ['mtomasz+watch@chromium.org'], 'fuchsia': ['fuchsia-reviews@chromium.org'], + 'full_restore': ['nancylingwang@chromium.org'], 'fuzzing': ['fuzzing@chromium.org'], 'gamepad': ['mattreynolds+watch@chromium.org'], 'gcm': ['peter@chromium.org'],
diff --git a/android_webview/expectations/system_webview_bundle.AndroidManifest.expected b/android_webview/expectations/system_webview_bundle.AndroidManifest.expected index 73dcc3b..3e78591 100644 --- a/android_webview/expectations/system_webview_bundle.AndroidManifest.expected +++ b/android_webview/expectations/system_webview_bundle.AndroidManifest.expected
@@ -1,5 +1,6 @@ <?xml version="1.0" ?> <manifest + android:isolatedSplits="true" package="com.android.webview" platformBuildVersionCode="30" platformBuildVersionName="11"
diff --git a/android_webview/expectations/trichrome_webview_bundle.AndroidManifest.expected b/android_webview/expectations/trichrome_webview_bundle.AndroidManifest.expected index 2861c0cc..a867c69 100644 --- a/android_webview/expectations/trichrome_webview_bundle.AndroidManifest.expected +++ b/android_webview/expectations/trichrome_webview_bundle.AndroidManifest.expected
@@ -1,5 +1,6 @@ <?xml version="1.0" ?> <manifest + android:isolatedSplits="true" package="com.android.webview" platformBuildVersionCode="30" platformBuildVersionName="11"
diff --git a/android_webview/system_webview_apk_tmpl.gni b/android_webview/system_webview_apk_tmpl.gni index fa280ae..58304b8 100644 --- a/android_webview/system_webview_apk_tmpl.gni +++ b/android_webview/system_webview_apk_tmpl.gni
@@ -59,6 +59,13 @@ "//android_webview:android_webview_no_weblayer_java", "//weblayer/browser/java:base_module_java", ] + if (defined(invoker.expected_android_manifest)) { + _bundle_target_gen_dir = + get_label_info(invoker.bundle_target, "target_gen_dir") + _bundle_name = get_label_info(invoker.bundle_target, "name") + extra_verification_manifest = "${_bundle_target_gen_dir}/${_bundle_name}__weblayer_bundle_module_manifest/AndroidManifest.xml" + extra_verification_manifest_dep = "${invoker.bundle_target}__weblayer_bundle_module__merge_manifests" + } } else { deps += [ "//android_webview:android_webview_java" ] }
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index b6b069c..869928b 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -1308,8 +1308,6 @@ "system/status_area_widget_delegate.h", "system/supervised/supervised_icon_string.cc", "system/supervised/supervised_icon_string.h", - "system/supervised/supervised_notification_controller.cc", - "system/supervised/supervised_notification_controller.h", "system/system_notification_controller.cc", "system/system_notification_controller.h", "system/time/time_tray_item_view.cc", @@ -2251,7 +2249,6 @@ "system/session/logout_confirmation_controller_unittest.cc", "system/session/session_limit_notification_controller_unittest.cc", "system/status_area_widget_unittest.cc", - "system/supervised/supervised_notification_controller_unittest.cc", "system/time/time_view_unittest.cc", "system/toast/toast_manager_unittest.cc", "system/tracing_notification_controller_unittest.cc",
diff --git a/ash/ambient/ambient_controller.cc b/ash/ambient/ambient_controller.cc index a2bd92c..81913f6 100644 --- a/ash/ambient/ambient_controller.cc +++ b/ash/ambient/ambient_controller.cc
@@ -253,7 +253,6 @@ } } else { DCHECK(visibility == AmbientUiVisibility::kClosed); - GetAmbientBackendModel()->ResetImageFailures(); inactivity_timer_.Stop(); user_activity_observer_.Reset(); power_status_observer_.Reset(); @@ -314,6 +313,11 @@ } } +void AmbientController::OnFirstSessionStarted() { + if (IsAmbientModeEnabled()) + ambient_photo_controller_.ScheduleFetchBackupImages(); +} + void AmbientController::OnActiveUserPrefServiceChanged( PrefService* pref_service) { if (!AmbientClient::Get()->IsAmbientModeAllowed() || @@ -445,6 +449,7 @@ DVLOG(1) << __func__; ambient_ui_model_.SetUiVisibility(AmbientUiVisibility::kClosed); + GetAmbientBackendModel()->ResetImageFailures(); } void AmbientController::ToggleInSessionUi() { @@ -504,6 +509,10 @@ } void AmbientController::OnEnabledPrefChanged() { + // TODO(b/176094707) conditionally create/destroy photo_controller and cache + // if Ambient is enabled + ambient_photo_controller_.InitCache(); + if (IsAmbientModeEnabled()) { DVLOG(1) << "Ambient mode enabled"; @@ -530,11 +539,10 @@ OnLockScreenBackgroundTimeoutPrefChanged(); OnPhotoRefreshIntervalPrefChanged(); - ambient_photo_controller_ = std::make_unique<AmbientPhotoController>(); - ambient_ui_model_observer_.Observe(&ambient_ui_model_); - ambient_backend_model_observer_.Observe(GetAmbientBackendModel()); + ambient_backend_model_observer_.Observe( + ambient_photo_controller_.ambient_backend_model()); auto* power_manager_client = chromeos::PowerManagerClient::Get(); DCHECK(power_manager_client); @@ -556,8 +564,6 @@ pref_change_registrar_->Remove(pref_name); } - ambient_photo_controller_.reset(); - ambient_ui_model_observer_.Reset(); ambient_backend_model_observer_.Reset(); power_manager_client_observer_.Reset(); @@ -624,8 +630,7 @@ } AmbientBackendModel* AmbientController::GetAmbientBackendModel() { - DCHECK(ambient_photo_controller_); - return ambient_photo_controller_->ambient_backend_model(); + return ambient_photo_controller_.ambient_backend_model(); } void AmbientController::OnImagesReady() { @@ -680,13 +685,11 @@ } void AmbientController::StartRefreshingImages() { - DCHECK(ambient_photo_controller_); - ambient_photo_controller_->StartScreenUpdate(); + ambient_photo_controller_.StartScreenUpdate(); } void AmbientController::StopRefreshingImages() { - DCHECK(ambient_photo_controller_); - ambient_photo_controller_->StopScreenUpdate(); + ambient_photo_controller_.StopScreenUpdate(); } void AmbientController::set_backend_controller_for_testing(
diff --git a/ash/ambient/ambient_controller.h b/ash/ambient/ambient_controller.h index c2cb6afea..c756e4c2 100644 --- a/ash/ambient/ambient_controller.h +++ b/ash/ambient/ambient_controller.h
@@ -65,6 +65,7 @@ // SessionObserver: void OnLockStateChanged(bool locked) override; + void OnFirstSessionStarted() override; void OnActiveUserPrefServiceChanged(PrefService* pref_service) override; // PowerStatus::Observer: @@ -118,7 +119,7 @@ } AmbientPhotoController* ambient_photo_controller() { - return ambient_photo_controller_.get(); + return &ambient_photo_controller_; } AmbientUiModel* ambient_ui_model() { return &ambient_ui_model_; } @@ -175,7 +176,7 @@ AmbientAccessTokenController access_token_controller_; std::unique_ptr<AmbientBackendController> ambient_backend_controller_; - std::unique_ptr<AmbientPhotoController> ambient_photo_controller_; + AmbientPhotoController ambient_photo_controller_; // Monitors the device inactivity and controls the auto-show of ambient. base::OneShotTimer inactivity_timer_;
diff --git a/ash/ambient/ambient_photo_controller.cc b/ash/ambient/ambient_photo_controller.cc index b935972..e414d18 100644 --- a/ash/ambient/ambient_photo_controller.cc +++ b/ash/ambient/ambient_photo_controller.cc
@@ -104,14 +104,9 @@ AmbientPhotoController::AmbientPhotoController() : fetch_topic_retry_backoff_(&kFetchTopicRetryBackoffPolicy), resume_fetch_image_backoff_(&kResumeFetchImageBackoffPolicy), - photo_cache_(AmbientPhotoCache::Create(GetCacheRootPath().Append( - FILE_PATH_LITERAL(kAmbientModeCacheDirectoryName)))), - backup_photo_cache_(AmbientPhotoCache::Create(GetCacheRootPath().Append( - FILE_PATH_LITERAL(kAmbientModeBackupCacheDirectoryName)))), task_runner_( base::ThreadPool::CreateSequencedTaskRunner(GetTaskTraits())) { ambient_backend_model_observer_.Add(&ambient_backend_model_); - ScheduleFetchBackupImages(); } AmbientPhotoController::~AmbientPhotoController() = default; @@ -144,6 +139,18 @@ weak_factory_.InvalidateWeakPtrs(); } +void AmbientPhotoController::ScheduleFetchBackupImages() { + if (backup_photo_refresh_timer_.IsRunning()) + return; + + backup_photo_refresh_timer_.Start( + FROM_HERE, + std::max(kBackupPhotoRefreshDelay, + resume_fetch_image_backoff_.GetTimeUntilRelease()), + base::BindOnce(&AmbientPhotoController::FetchBackupImages, + weak_factory_.GetWeakPtr())); +} + void AmbientPhotoController::OnTopicsChanged() { if (ambient_backend_model_.topics().size() < kMaxNumberOfCachedImages) ScheduleFetchTopics(/*backoff=*/false); @@ -180,6 +187,17 @@ backup_photo_cache_->Clear(); } +void AmbientPhotoController::InitCache() { + if (!photo_cache_) { + photo_cache_ = AmbientPhotoCache::Create(GetCacheRootPath().Append( + FILE_PATH_LITERAL(kAmbientModeCacheDirectoryName))); + } + if (!backup_photo_cache_) { + backup_photo_cache_ = AmbientPhotoCache::Create(GetCacheRootPath().Append( + FILE_PATH_LITERAL(kAmbientModeBackupCacheDirectoryName))); + } +} + void AmbientPhotoController::ScheduleFetchTopics(bool backoff) { // If retry, using the backoff delay, otherwise the default delay. const base::TimeDelta delay = @@ -199,19 +217,6 @@ weak_factory_.GetWeakPtr())); } -void AmbientPhotoController::ScheduleFetchBackupImages() { - DVLOG(3) << __func__; - if (backup_photo_refresh_timer_.IsRunning()) - return; - - backup_photo_refresh_timer_.Start( - FROM_HERE, - std::max(kBackupPhotoRefreshDelay, - resume_fetch_image_backoff_.GetTimeUntilRelease()), - base::BindOnce(&AmbientPhotoController::FetchBackupImages, - weak_factory_.GetWeakPtr())); -} - void AmbientPhotoController::FetchBackupImages() { const auto& backup_photo_urls = GetBackupPhotoUrls(); backup_retries_to_read_from_cache_ = backup_photo_urls.size();
diff --git a/ash/ambient/ambient_photo_controller.h b/ash/ambient/ambient_photo_controller.h index d5446ba..81f1abcf 100644 --- a/ash/ambient/ambient_photo_controller.h +++ b/ash/ambient/ambient_photo_controller.h
@@ -58,6 +58,8 @@ void StartScreenUpdate(); void StopScreenUpdate(); + void ScheduleFetchBackupImages(); + AmbientBackendModel* ambient_backend_model() { return &ambient_backend_model_; } @@ -66,7 +68,7 @@ return photo_refresh_timer_; } - base::OneShotTimer& backup_photo_refresh_timer_for_testing() { + const base::OneShotTimer& backup_photo_refresh_timer_for_testing() const { return backup_photo_refresh_timer_; } @@ -76,9 +78,10 @@ // Clear cache when Settings changes. void ClearCache(); + void InitCache(); + private: friend class AmbientAshTestBase; - friend class AmbientPhotoControllerTest; void FetchTopics(); @@ -88,8 +91,6 @@ void ScheduleRefreshImage(); - void ScheduleFetchBackupImages(); - // Download backup cache images. void FetchBackupImages();
diff --git a/ash/ambient/ambient_photo_controller_unittest.cc b/ash/ambient/ambient_photo_controller_unittest.cc index 925ed78..748588da9 100644 --- a/ash/ambient/ambient_photo_controller_unittest.cc +++ b/ash/ambient/ambient_photo_controller_unittest.cc
@@ -80,10 +80,6 @@ loop.QuitClosure()); loop.Run(); } - - void ScheduleFetchBackupImages() { - photo_controller()->ScheduleFetchBackupImages(); - } }; // Test that topics are downloaded when starting screen update. @@ -286,7 +282,7 @@ std::string expected_data = "backup data"; SetBackupDownloadPhotoData(expected_data); - ScheduleFetchBackupImages(); + photo_controller()->ScheduleFetchBackupImages(); EXPECT_TRUE( photo_controller()->backup_photo_refresh_timer_for_testing().IsRunning()); @@ -312,7 +308,7 @@ } TEST_F(AmbientPhotoControllerTest, ShouldResetTimerWhenBackupImagesFail) { - ScheduleFetchBackupImages(); + photo_controller()->ScheduleFetchBackupImages(); EXPECT_TRUE( photo_controller()->backup_photo_refresh_timer_for_testing().IsRunning()); @@ -330,7 +326,7 @@ TEST_F(AmbientPhotoControllerTest, ShouldStartDownloadBackupImagesOnAmbientModeStart) { - ScheduleFetchBackupImages(); + photo_controller()->ScheduleFetchBackupImages(); EXPECT_TRUE( photo_controller()->backup_photo_refresh_timer_for_testing().IsRunning());
diff --git a/ash/ambient/test/ambient_ash_test_base.cc b/ash/ambient/test/ambient_ash_test_base.cc index 3eae4f68..ed10e79 100644 --- a/ash/ambient/test/ambient_ash_test_base.cc +++ b/ash/ambient/test/ambient_ash_test_base.cc
@@ -185,6 +185,10 @@ ambient_controller()->set_backend_controller_for_testing(nullptr); ambient_controller()->set_backend_controller_for_testing( std::make_unique<FakeAmbientBackendControllerImpl>()); + photo_controller()->set_photo_cache_for_testing( + std::make_unique<TestAmbientPhotoCacheImpl>()); + photo_controller()->set_backup_photo_cache_for_testing( + std::make_unique<TestAmbientPhotoCacheImpl>()); token_controller()->SetTokenUsageBufferForTesting( base::TimeDelta::FromSeconds(30)); SetAmbientModeEnabled(true); @@ -198,14 +202,6 @@ void AmbientAshTestBase::SetAmbientModeEnabled(bool enabled) { Shell::Get()->session_controller()->GetActivePrefService()->SetBoolean( ambient::prefs::kAmbientModeEnabled, enabled); - - if (enabled) { - photo_controller()->set_photo_cache_for_testing( - std::make_unique<TestAmbientPhotoCacheImpl>()); - photo_controller()->set_backup_photo_cache_for_testing( - std::make_unique<TestAmbientPhotoCacheImpl>()); - photo_controller()->backup_photo_refresh_timer_for_testing().Stop(); - } } void AmbientAshTestBase::ShowAmbientScreen() {
diff --git a/ash/ambient/ui/assistant_response_container_view.cc b/ash/ambient/ui/assistant_response_container_view.cc index 759b461b..9ebc8ebb 100644 --- a/ash/ambient/ui/assistant_response_container_view.cc +++ b/ash/ambient/ui/assistant_response_container_view.cc
@@ -15,6 +15,7 @@ #include "ash/assistant/ui/main_stage/assistant_text_element_view.h" #include "ash/assistant/ui/main_stage/element_animator.h" #include "ui/views/layout/box_layout.h" +#include "ui/views/metadata/metadata_impl_macros.h" namespace ash { @@ -34,10 +35,6 @@ AssistantResponseContainerView::~AssistantResponseContainerView() = default; -const char* AssistantResponseContainerView::GetClassName() const { - return "AssistantResponseContainerView"; -} - gfx::Size AssistantResponseContainerView::CalculatePreferredSize() const { return gfx::Size(kPreferredWidthDip, content_view()->GetHeightForWidth(kPreferredWidthDip)); @@ -88,4 +85,7 @@ std::make_unique<AssistantErrorElementView>(error_element)); } +BEGIN_METADATA(AssistantResponseContainerView, AnimatedContainerView) +END_METADATA + } // namespace ash
diff --git a/ash/ambient/ui/assistant_response_container_view.h b/ash/ambient/ui/assistant_response_container_view.h index 01aac1d..31b58d8 100644 --- a/ash/ambient/ui/assistant_response_container_view.h +++ b/ash/ambient/ui/assistant_response_container_view.h
@@ -8,7 +8,6 @@ #include <memory> #include "ash/assistant/ui/main_stage/animated_container_view.h" -#include "base/macros.h" namespace ash { @@ -18,11 +17,16 @@ class AssistantResponseContainerView : public AnimatedContainerView { public: + METADATA_HEADER(AssistantResponseContainerView); + explicit AssistantResponseContainerView(AssistantViewDelegate* delegate); + AssistantResponseContainerView(const AssistantResponseContainerView&) = + delete; + AssistantResponseContainerView& operator=( + const AssistantResponseContainerView&) = delete; ~AssistantResponseContainerView() override; // AnimatedContainerView: - const char* GetClassName() const override; gfx::Size CalculatePreferredSize() const override; void OnContentsPreferredSizeChanged(views::View* content_view) override; @@ -34,8 +38,6 @@ // AnimatedContainerView: std::unique_ptr<ElementAnimator> HandleUiElement( const AssistantUiElement* ui_element) override; - - DISALLOW_COPY_AND_ASSIGN(AssistantResponseContainerView); }; } // namespace ash
diff --git a/ash/ambient/ui/glanceable_info_view.cc b/ash/ambient/ui/glanceable_info_view.cc index 9dac125..52bfce2 100644 --- a/ash/ambient/ui/glanceable_info_view.cc +++ b/ash/ambient/ui/glanceable_info_view.cc
@@ -30,6 +30,7 @@ #include "ui/views/controls/image_view.h" #include "ui/views/controls/label.h" #include "ui/views/layout/box_layout.h" +#include "ui/views/metadata/metadata_impl_macros.h" #include "ui/views/view.h" namespace ash { @@ -86,11 +87,6 @@ } GlanceableInfoView::~GlanceableInfoView() = default; - -const char* GlanceableInfoView::GetClassName() const { - return "GlanceableInfoView"; -} - void GlanceableInfoView::OnWeatherInfoUpdated() { Show(); } @@ -174,4 +170,7 @@ 0, 0, GetTimeFontDescent() - GetTemperatureFontDescent(), 0)); } +BEGIN_METADATA(GlanceableInfoView, views::View) +END_METADATA + } // namespace ash
diff --git a/ash/ambient/ui/glanceable_info_view.h b/ash/ambient/ui/glanceable_info_view.h index 10516c07..23fb212 100644 --- a/ash/ambient/ui/glanceable_info_view.h +++ b/ash/ambient/ui/glanceable_info_view.h
@@ -27,14 +27,13 @@ class GlanceableInfoView : public views::View, public AmbientBackendModelObserver { public: + METADATA_HEADER(GlanceableInfoView); + explicit GlanceableInfoView(AmbientViewDelegate* delegate); GlanceableInfoView(const GlanceableInfoView&) = delete; GlanceableInfoView& operator=(const GlanceableInfoView&) = delete; ~GlanceableInfoView() override; - // views::View: - const char* GetClassName() const override; - // AmbientBackendModelObserver: void OnWeatherInfoUpdated() override;
diff --git a/ash/ambient/ui/media_string_view.cc b/ash/ambient/ui/media_string_view.cc index c03c396..0660680 100644 --- a/ash/ambient/ui/media_string_view.cc +++ b/ash/ambient/ui/media_string_view.cc
@@ -36,6 +36,7 @@ #include "ui/views/layout/box_layout.h" #include "ui/views/layout/flex_layout.h" #include "ui/views/layout/flex_layout_types.h" +#include "ui/views/metadata/metadata_impl_macros.h" namespace ash { @@ -45,7 +46,7 @@ // zones. class FadeoutLayerDelegate : public ui::LayerDelegate { public: - explicit FadeoutLayerDelegate() : layer_(ui::LAYER_TEXTURED) { + FadeoutLayerDelegate() : layer_(ui::LAYER_TEXTURED) { layer_.set_delegate(this); layer_.SetFillsBoundsOpaquely(false); } @@ -124,10 +125,6 @@ MediaStringView::~MediaStringView() = default; -const char* MediaStringView::GetClassName() const { - return "MediaStringView"; -} - void MediaStringView::OnViewBoundsChanged(views::View* observed_view) { UpdateMaskLayer(); } @@ -344,4 +341,7 @@ } } +BEGIN_METADATA(MediaStringView, views::View) +END_METADATA + } // namespace ash
diff --git a/ash/ambient/ui/media_string_view.h b/ash/ambient/ui/media_string_view.h index fe71978..0ce2a4ff 100644 --- a/ash/ambient/ui/media_string_view.h +++ b/ash/ambient/ui/media_string_view.h
@@ -34,14 +34,13 @@ public media_session::mojom::MediaControllerObserver, public ui::ImplicitAnimationObserver { public: + METADATA_HEADER(MediaStringView); + MediaStringView(); MediaStringView(const MediaStringView&) = delete; MediaStringView& operator=(const MediaStringView&) = delete; ~MediaStringView() override; - // views::View: - const char* GetClassName() const override; - // views::ViewObserver: void OnViewBoundsChanged(views::View* observed_view) override;
diff --git a/ash/ambient/ui/photo_view.cc b/ash/ambient/ui/photo_view.cc index df7fc45e..1fbeffe 100644 --- a/ash/ambient/ui/photo_view.cc +++ b/ash/ambient/ui/photo_view.cc
@@ -22,6 +22,7 @@ #include "ui/compositor/scoped_layer_animation_settings.h" #include "ui/views/controls/image_view.h" #include "ui/views/layout/fill_layout.h" +#include "ui/views/metadata/metadata_impl_macros.h" namespace ash { @@ -46,10 +47,6 @@ PhotoView::~PhotoView() = default; -const char* PhotoView::GetClassName() const { - return "PhotoView"; -} - void PhotoView::OnImageAdded() { // If NeedToAnimate() is true, will start transition animation and // UpdateImages() when animation completes. Otherwise, update images @@ -152,4 +149,7 @@ return image_views_.at(image_index_)->GetCurrentImage(); } +BEGIN_METADATA(PhotoView, views::View) +END_METADATA + } // namespace ash
diff --git a/ash/ambient/ui/photo_view.h b/ash/ambient/ui/photo_view.h index 9d6aae7..c2c39bd 100644 --- a/ash/ambient/ui/photo_view.h +++ b/ash/ambient/ui/photo_view.h
@@ -32,14 +32,13 @@ public AmbientBackendModelObserver, public ui::ImplicitAnimationObserver { public: + METADATA_HEADER(PhotoView); + explicit PhotoView(AmbientViewDelegate* delegate); PhotoView(const PhotoView&) = delete; PhotoView& operator=(PhotoView&) = delete; ~PhotoView() override; - // views::View: - const char* GetClassName() const override; - // AmbientBackendModelObserver: void OnImageAdded() override;
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd index f160b19..a8cf9de 100644 --- a/ash/ash_strings.grd +++ b/ash/ash_strings.grd
@@ -1226,16 +1226,9 @@ <message name="IDS_ASH_PHONE_HUB_ENABLE_HOTSPOT_NO_RECEPTION_STATE_TOOLTIP" desc="Tooltip message that indicates to the user that the Enable Hotspot feature is disabled because their phone does not have mobile data."> Your phone must have mobile data to provide a hotspot </message> - - <message name="IDS_ASH_STYLUS_BATTERY_LOW_LABEL"> + <message name="IDS_ASH_STYLUS_BATTERY_LOW_LABEL" desc="The label next to the stylus battery indicator when the battery level is below 24%"> Low </message> - <message name="IDS_ASH_STYLUS_BATTERY_MED_LABEL"> - Med - </message> - <message name="IDS_ASH_STYLUS_BATTERY_HI_LABEL"> - Hi - </message> <message name="IDS_ASH_STYLUS_TOOLS_CAPTURE_REGION_ACTION" desc="Title of the capture region action in the stylus tools (a pop-up panel next to the status tray). This causes a partial screenshot to be taken (the user selects an area of the screen to take a screenshot of)."> Capture region </message> @@ -1359,6 +1352,9 @@ <message name="IDS_ASH_OVERVIEW_WINDOW_CLOSING_A11Y_ALERT" desc="The accessibility alert read by screen readers to alert the user that a window in overview mode is closing."> Window <ph name="WINDOW_TITILE">$1<ex>1</ex></ph> closed. </message> + <message name="IDS_ASH_OVERVIEW_VISIBLE_ON_ALL_DESKS_TOAST" desc="The text for the toast that appears when user tries to drag a visible on all desks window to a desk."> + Already assigned to all desks. + </message> <!-- Virtual Desks --> <message name="IDS_ASH_DESKS_NEW_DESK_BUTTON" desc="The label of the new virtual desk (a.k.a. workspaces) button."> @@ -3165,6 +3161,9 @@ </message> <!-- Capture Mode --> + <message name="IDS_ASH_SCREEN_CAPTURE_HDCP_BLOCKED_MESSAGE" desc="The text of the notification that informs the user the screen recording is blocked due to existence of protected content."> + Screen capture is not allowed while protected content is present + </message> <message name="IDS_ASH_SCREEN_CAPTURE_DISABLED_TITLE" desc="The title of the notification when capture mode is disabled."> Screen capture is blocked </message>
diff --git a/ash/ash_strings_grd/IDS_ASH_OVERVIEW_VISIBLE_ON_ALL_DESKS_TOAST.png.sha1 b/ash/ash_strings_grd/IDS_ASH_OVERVIEW_VISIBLE_ON_ALL_DESKS_TOAST.png.sha1 new file mode 100644 index 0000000..9f9a621 --- /dev/null +++ b/ash/ash_strings_grd/IDS_ASH_OVERVIEW_VISIBLE_ON_ALL_DESKS_TOAST.png.sha1
@@ -0,0 +1 @@ +0feb78aa3efb3b45ffd5e7ec3c2ad58b3a51026a \ No newline at end of file
diff --git a/ash/ash_strings_grd/IDS_ASH_SCREEN_CAPTURE_HDCP_BLOCKED_MESSAGE.png.sha1 b/ash/ash_strings_grd/IDS_ASH_SCREEN_CAPTURE_HDCP_BLOCKED_MESSAGE.png.sha1 new file mode 100644 index 0000000..cde6887 --- /dev/null +++ b/ash/ash_strings_grd/IDS_ASH_SCREEN_CAPTURE_HDCP_BLOCKED_MESSAGE.png.sha1
@@ -0,0 +1 @@ +fe2d0b79ce066bd00acca7ec224ca239cfa1e8a9 \ No newline at end of file
diff --git a/ash/ash_strings_grd/IDS_ASH_STYLUS_BATTERY_HI_LABEL.png.sha1 b/ash/ash_strings_grd/IDS_ASH_STYLUS_BATTERY_HI_LABEL.png.sha1 deleted file mode 100644 index 4254ac3..0000000 --- a/ash/ash_strings_grd/IDS_ASH_STYLUS_BATTERY_HI_LABEL.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -f9dfa5adb30c929b0694cbf46ed7893fee05d1fb \ No newline at end of file
diff --git a/ash/ash_strings_grd/IDS_ASH_STYLUS_BATTERY_MED_LABEL.png.sha1 b/ash/ash_strings_grd/IDS_ASH_STYLUS_BATTERY_MED_LABEL.png.sha1 deleted file mode 100644 index f9b12a6..0000000 --- a/ash/ash_strings_grd/IDS_ASH_STYLUS_BATTERY_MED_LABEL.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -a2bda703b9e32c023a76e2845d05b1c17718630e \ No newline at end of file
diff --git a/ash/capture_mode/capture_mode_controller.cc b/ash/capture_mode/capture_mode_controller.cc index ea45c251..70ff0b8 100644 --- a/ash/capture_mode/capture_mode_controller.cc +++ b/ash/capture_mode/capture_mode_controller.cc
@@ -45,6 +45,7 @@ #include "ui/base/clipboard/clipboard_data.h" #include "ui/base/clipboard/clipboard_non_backed.h" #include "ui/base/l10n/l10n_util.h" +#include "ui/display/types/display_constants.h" #include "ui/message_center/message_center.h" #include "ui/message_center/public/cpp/notification.h" #include "ui/message_center/public/cpp/notification_delegate.h" @@ -158,78 +159,69 @@ // Shows a Capture Mode related notification with the given parameters. void ShowNotification( - const base::string16& title, - const base::string16& message, + const std::string& notification_id, + int title_id, + int message_id, const message_center::RichNotificationData& optional_fields, - scoped_refptr<message_center::NotificationDelegate> delegate) { + scoped_refptr<message_center::NotificationDelegate> delegate, + message_center::SystemNotificationWarningLevel warning_level = + message_center::SystemNotificationWarningLevel::NORMAL, + const gfx::VectorIcon& notification_icon = kCaptureModeIcon) { const auto type = optional_fields.image.IsEmpty() ? message_center::NOTIFICATION_TYPE_SIMPLE : message_center::NOTIFICATION_TYPE_IMAGE; std::unique_ptr<message_center::Notification> notification = CreateSystemNotification( - type, kScreenCaptureNotificationId, title, message, + type, notification_id, l10n_util::GetStringUTF16(title_id), + l10n_util::GetStringUTF16(message_id), l10n_util::GetStringUTF16(IDS_ASH_SCREEN_CAPTURE_DISPLAY_SOURCE), GURL(), message_center::NotifierId( message_center::NotifierType::SYSTEM_COMPONENT, kScreenCaptureNotifierId), - optional_fields, delegate, kCaptureModeIcon, - message_center::SystemNotificationWarningLevel::NORMAL); + optional_fields, delegate, notification_icon, warning_level); // Remove the previous notification before showing the new one if there is // any. auto* message_center = message_center::MessageCenter::Get(); - message_center->RemoveNotification(kScreenCaptureNotificationId, + message_center->RemoveNotification(notification_id, /*by_user=*/false); message_center->AddNotification(std::move(notification)); } // Shows a notification informing the user that Capture Mode operations are -// currently disabled. -void ShowDisabledNotification() { - std::unique_ptr<message_center::Notification> notification = - CreateSystemNotification( - message_center::NOTIFICATION_TYPE_SIMPLE, - kScreenCaptureNotificationId, - l10n_util::GetStringUTF16(IDS_ASH_SCREEN_CAPTURE_DISABLED_TITLE), - l10n_util::GetStringUTF16(IDS_ASH_SCREEN_CAPTURE_DISABLED_MESSAGE), - /*display_source=*/base::string16(), GURL(), - message_center::NotifierId( - message_center::NotifierType::SYSTEM_COMPONENT, - kScreenCaptureNotifierId), - /*optional_fields=*/{}, /*delegate=*/nullptr, - vector_icons::kBusinessIcon, - message_center::SystemNotificationWarningLevel::CRITICAL_WARNING); - message_center::MessageCenter::Get()->AddNotification( - std::move(notification)); +// currently disabled. If |for_hdcp| is true, then this was due to a content- +// enforced protection, otherwise it was due to DLP which is admin enforced. +void ShowDisabledNotification(bool for_hdcp) { + ShowNotification( + kScreenCaptureNotificationId, IDS_ASH_SCREEN_CAPTURE_DISABLED_TITLE, + for_hdcp ? IDS_ASH_SCREEN_CAPTURE_HDCP_BLOCKED_MESSAGE + : IDS_ASH_SCREEN_CAPTURE_DISABLED_MESSAGE, + /*optional_fields=*/{}, /*delegate=*/nullptr, + message_center::SystemNotificationWarningLevel::CRITICAL_WARNING, + for_hdcp ? kCaptureModeIcon : vector_icons::kBusinessIcon); } // Shows a notification informing the user that a Capture Mode operation has // failed. void ShowFailureNotification() { - ShowNotification( - l10n_util::GetStringUTF16(IDS_ASH_SCREEN_CAPTURE_FAILURE_TITLE), - l10n_util::GetStringUTF16(IDS_ASH_SCREEN_CAPTURE_FAILURE_MESSAGE), - /*optional_fields=*/{}, /*delegate=*/nullptr); + ShowNotification(kScreenCaptureStoppedNotificationId, + IDS_ASH_SCREEN_CAPTURE_FAILURE_TITLE, + IDS_ASH_SCREEN_CAPTURE_FAILURE_MESSAGE, + /*optional_fields=*/{}, /*delegate=*/nullptr); } -// Shows a notification informing the user that video recording was stopped. -void ShowVideoRecordingStoppedNotification() { - std::unique_ptr<message_center::Notification> notification = - CreateSystemNotification( - message_center::NOTIFICATION_TYPE_SIMPLE, - kScreenCaptureStoppedNotificationId, - l10n_util::GetStringUTF16(IDS_ASH_SCREEN_CAPTURE_STOPPED_TITLE), - l10n_util::GetStringUTF16(IDS_ASH_SCREEN_CAPTURE_STOPPED_MESSAGE), - /*display_source=*/base::string16(), GURL(), - message_center::NotifierId( - message_center::NotifierType::SYSTEM_COMPONENT, - kScreenCaptureNotifierId), - /*optional_fields=*/{}, /*delegate=*/nullptr, - vector_icons::kBusinessIcon, - message_center::SystemNotificationWarningLevel::CRITICAL_WARNING); - message_center::MessageCenter::Get()->AddNotification( - std::move(notification)); +// Shows a notification informing the user that video recording was stopped. If +// |for_hdcp| is true, then this was due to a content-enforced protection, +// otherwise it was due to DLP which is admin enforced. +void ShowVideoRecordingStoppedNotification(bool for_hdcp) { + ShowNotification( + kScreenCaptureStoppedNotificationId, IDS_ASH_SCREEN_CAPTURE_STOPPED_TITLE, + for_hdcp ? IDS_ASH_SCREEN_CAPTURE_HDCP_BLOCKED_MESSAGE + : IDS_ASH_SCREEN_CAPTURE_DISABLED_MESSAGE, + /*optional_fields=*/{}, /*delegate=*/nullptr, + message_center::SystemNotificationWarningLevel::CRITICAL_WARNING, + for_hdcp ? kCaptureModeIcon : vector_icons::kBusinessIcon); } // Copies the bitmap representation of the given |image| to the clipboard. @@ -326,7 +318,7 @@ return; if (delegate_->IsCaptureModeInitRestricted()) { - ShowDisabledNotification(); + ShowDisabledNotification(/*for_hdcp=*/false); return; } @@ -345,12 +337,18 @@ kResetCaptureRegionDuration) { SetUserCaptureRegion(gfx::Rect(), /*by_user=*/false); } + + delegate_->OnSessionStateChanged(/*started=*/true); + capture_mode_session_ = std::make_unique<CaptureModeSession>(this); } void CaptureModeController::Stop() { DCHECK(IsActive()); + capture_mode_session_->ReportSessionHistograms(); capture_mode_session_.reset(); + + delegate_->OnSessionStateChanged(/*started=*/false); } void CaptureModeController::SetUserCaptureRegion(const gfx::Rect& region, @@ -362,7 +360,7 @@ void CaptureModeController::CaptureScreenshotsOfAllDisplays() { if (delegate_->IsCaptureModeInitRestricted()) { - ShowDisabledNotification(); + ShowDisabledNotification(/*for_hdcp=*/false); return; } // Get a vector of RootWindowControllers with primary root window at first. @@ -390,20 +388,23 @@ return; if (!IsCaptureAllowed(*capture_params)) { - ShowDisabledNotification(); + ShowDisabledNotification(/*for_hdcp=*/false); Stop(); return; } - DCHECK(capture_mode_session_); - capture_mode_session_->ReportSessionHistograms(); - if (type_ == CaptureModeType::kImage) { CaptureImage(*capture_params, BuildImagePath()); - } + } else { + // HDCP affects only video recording. + if (ShouldBlockRecordingForContentProtection(capture_params->window)) { + ShowDisabledNotification(/*for_hdcp=*/true); + Stop(); + return; + } - else CaptureVideo(*capture_params); + } } void CaptureModeController::EndVideoRecording(EndRecordingReason reason) { @@ -416,6 +417,31 @@ delegate_->OpenFeedbackDialog(); } +void CaptureModeController::SetWindowProtectionMask(aura::Window* window, + uint32_t protection_mask) { + if (protection_mask == display::CONTENT_PROTECTION_METHOD_NONE) + protected_windows_.erase(window); + else + protected_windows_[window] = protection_mask; + + RefreshContentProtection(); +} + +void CaptureModeController::RefreshContentProtection() { + if (!is_recording_in_progress_) + return; + + DCHECK(video_recording_watcher_); + if (ShouldBlockRecordingForContentProtection( + video_recording_watcher_->window_being_recorded())) { + // HDCP violation is also considered a failure, and we're not going to wait + // for any buffered frames in the recording service. + RecordEndRecordingReason(EndRecordingReason::kHdcpInterruption); + OnRecordingEnded(/*success=*/false); + ShowVideoRecordingStoppedNotification(/*for_hdcp=*/true); + } +} + void CaptureModeController::OnMuxerOutput(const std::string& chunk) { DCHECK(video_file_handler_); video_file_handler_.AsyncCall(&VideoFileHandler::AppendChunk) @@ -470,6 +496,22 @@ OnVideoRecordCountDownFinished(); } +bool CaptureModeController::ShouldBlockRecordingForContentProtection( + aura::Window* window) const { + if (window->IsRootWindow()) { + // Recording fullscreen or partial region of it. Block if this root has a + // window with protection. + for (const auto& iter : protected_windows_) { + if (iter.first->GetRootWindow() == window) + return true; + } + + return false; + } + + return protected_windows_.contains(window); +} + void CaptureModeController::EndSessionOrRecording(EndRecordingReason reason) { if (IsActive()) { // Suspend or user session changes can happen while the capture mode session @@ -767,14 +809,11 @@ const gfx::Image& preview_image, const CaptureModeType type) { const bool for_video = type == CaptureModeType::kVideo; - const base::string16 title = l10n_util::GetStringUTF16( - for_video ? IDS_ASH_SCREEN_CAPTURE_RECORDING_TITLE - : IDS_ASH_SCREEN_CAPTURE_SCREENSHOT_TITLE); - const base::string16 message = - for_video && low_disk_space_threshold_reached_ - ? l10n_util::GetStringUTF16( - IDS_ASH_SCREEN_CAPTURE_LOW_DISK_SPACE_MESSAGE) - : l10n_util::GetStringUTF16(IDS_ASH_SCREEN_CAPTURE_MESSAGE); + const int title_id = for_video ? IDS_ASH_SCREEN_CAPTURE_RECORDING_TITLE + : IDS_ASH_SCREEN_CAPTURE_SCREENSHOT_TITLE; + const int message_id = for_video && low_disk_space_threshold_reached_ + ? IDS_ASH_SCREEN_CAPTURE_LOW_DISK_SPACE_MESSAGE + : IDS_ASH_SCREEN_CAPTURE_MESSAGE; message_center::RichNotificationData optional_fields; message_center::ButtonInfo edit_button( @@ -788,7 +827,7 @@ optional_fields.image = preview_image; ShowNotification( - title, message, optional_fields, + kScreenCaptureNotificationId, title_id, message_id, optional_fields, base::MakeRefCounted<message_center::HandleNotificationClickDelegate>( base::BindRepeating(&CaptureModeController::HandleNotificationClicked, weak_ptr_factory_.GetWeakPtr(), @@ -897,6 +936,18 @@ if (!capture_params) return; + // During the 3-second count down, screen content might have changed such that + // admin-restricted or HDCP content became present. We must check again. + if (!IsCaptureAllowed(*capture_params)) { + ShowDisabledNotification(/*for_hdcp=*/false); + return; + } + + if (ShouldBlockRecordingForContentProtection(capture_params->window)) { + ShowDisabledNotification(/*for_hdcp=*/true); + return; + } + // We enable the software-composited cursor, in order for the video capturer // to be able to record it. is_recording_in_progress_ = true; @@ -941,7 +992,7 @@ } void CaptureModeController::InterruptVideoRecording() { - ShowVideoRecordingStoppedNotification(); + ShowVideoRecordingStoppedNotification(/*for_hdcp=*/false); EndVideoRecording(EndRecordingReason::kDlpInterruption); }
diff --git a/ash/capture_mode/capture_mode_controller.h b/ash/capture_mode/capture_mode_controller.h index 02b45bd1..b5a3ed15 100644 --- a/ash/capture_mode/capture_mode_controller.h +++ b/ash/capture_mode/capture_mode_controller.h
@@ -95,6 +95,20 @@ // Called when the feedback button on the capture bar is pressed. void OpenFeedbackDialog(); + // Sets the |protection_mask| that is currently set on the given |window|. If + // the |protection_mask| is |display::CONTENT_PROTECTION_METHOD_NONE|, then + // the window will no longer be tracked. + // Note that content protection (a.k.a. HDCP (High-bandwidth Digital Content + // Protection)) is different from DLP (Data Leak Prevention). The latter is + // enforced by admins and applies to both image and video capture, whereas + // the former is enforced by apps and content providers and is applied only to + // video capture. + void SetWindowProtectionMask(aura::Window* window, uint32_t protection_mask); + + // If a video recording is in progress, it will end if so required by content + // protection. + void RefreshContentProtection(); + // recording::mojom::RecordingServiceClient: void OnMuxerOutput(const std::string& chunk) override; void OnRecordingEnded(bool success) override; @@ -114,6 +128,10 @@ private: friend class CaptureModeTestApi; + // Returns true if screen recording needs to be blocked due to protected + // content. |window| is the window being recorded or desired to be recorded. + bool ShouldBlockRecordingForContentProtection(aura::Window* window) const; + // Used by user session change, and suspend events to end the capture mode // session if it's active, or stop the video recording if one is in progress. void EndSessionOrRecording(EndRecordingReason reason); @@ -276,6 +294,13 @@ // Watches events that lead to ending video recording. std::unique_ptr<VideoRecordingWatcher> video_recording_watcher_; + // Tracks the windows that currently have content protection enabled, so that + // we prevent them from being video recorded. Each window is mapped to its + // cureently-set protection_mask. Windows in this map are only the ones that + // have protection masks other than |display::CONTENT_PROTECTION_METHOD_NONE|. + base::flat_map<aura::Window*, /*protection_mask*/ uint32_t> + protected_windows_; + // If set, it will be called when either an image or video file is saved. base::OnceCallback<void(const base::FilePath&)> on_file_saved_callback_;
diff --git a/ash/capture_mode/capture_mode_metrics.h b/ash/capture_mode/capture_mode_metrics.h index 462ad32..a1daa23 100644 --- a/ash/capture_mode/capture_mode_metrics.h +++ b/ash/capture_mode/capture_mode_metrics.h
@@ -25,7 +25,8 @@ kFileIoError, kDlpInterruption, kLowDiskSpace, - kMaxValue = kLowDiskSpace, + kHdcpInterruption, + kMaxValue = kHdcpInterruption, }; // Enumeration of capture bar buttons that can be pressed while in capture mode.
diff --git a/ash/capture_mode/capture_mode_session.cc b/ash/capture_mode/capture_mode_session.cc index e1cf721..7587118 100644 --- a/ash/capture_mode/capture_mode_session.cc +++ b/ash/capture_mode/capture_mode_session.cc
@@ -23,6 +23,7 @@ #include "base/memory/ptr_util.h" #include "base/stl_util.h" #include "cc/paint/paint_flags.h" +#include "ui/aura/client/capture_client.h" #include "ui/aura/window.h" #include "ui/base/cursor/cursor_factory.h" #include "ui/base/cursor/cursor_util.h" @@ -445,12 +446,28 @@ UpdateRootWindowDimmers(); + // A context menu may have input capture when entering a session. Remove + // capture from it, otherwise subsequent mouse events will cause it to close, + // and then we won't be able to take a screenshot of the menu. Store it so we + // can return capture to it when exiting the session. + auto* capture_client = aura::client::GetCaptureClient(current_root_); + input_capture_window_ = capture_client->GetCaptureWindow(); + if (input_capture_window_) { + capture_client->ReleaseCapture(input_capture_window_); + input_capture_window_->AddObserver(this); + } + TabletModeController::Get()->AddObserver(this); current_root_->AddObserver(this); display::Screen::GetScreen()->AddObserver(this); } CaptureModeSession::~CaptureModeSession() { + if (input_capture_window_) { + input_capture_window_->RemoveObserver(this); + aura::client::GetCaptureClient(current_root_) + ->SetCapture(input_capture_window_); + } display::Screen::GetScreen()->RemoveObserver(this); current_root_->RemoveObserver(this); TabletModeController::Get()->RemoveObserver(this); @@ -655,6 +672,11 @@ } void CaptureModeSession::OnWindowDestroying(aura::Window* window) { + if (window == input_capture_window_) { + input_capture_window_->RemoveObserver(this); + input_capture_window_ = nullptr; + return; + } DCHECK_EQ(current_root_, window); MaybeChangeRoot(Shell::GetPrimaryRootWindow()); }
diff --git a/ash/capture_mode/capture_mode_session.h b/ash/capture_mode/capture_mode_session.h index 7c8f42b..f288354 100644 --- a/ash/capture_mode/capture_mode_session.h +++ b/ash/capture_mode/capture_mode_session.h
@@ -305,6 +305,10 @@ // The current focused fine tune position. This changes as user tabs while a // in capture region mode. FineTunePosition focused_fine_tune_position_ = FineTunePosition::kNone; + + // The window which had input capture prior to entering the session. It may be + // null if no such window existed. + aura::Window* input_capture_window_ = nullptr; }; } // namespace ash
diff --git a/ash/capture_mode/capture_mode_unittests.cc b/ash/capture_mode/capture_mode_unittests.cc index 194f61e..5051d2b 100644 --- a/ash/capture_mode/capture_mode_unittests.cc +++ b/ash/capture_mode/capture_mode_unittests.cc
@@ -17,11 +17,13 @@ #include "ash/capture_mode/capture_mode_util.h" #include "ash/capture_mode/stop_recording_button_tray.h" #include "ash/display/cursor_window_controller.h" +#include "ash/display/output_protection_delegate.h" #include "ash/display/screen_orientation_controller_test_api.h" #include "ash/display/window_tree_host_manager.h" #include "ash/home_screen/home_screen_controller.h" #include "ash/magnifier/magnifier_glass.h" #include "ash/public/cpp/ash_features.h" +#include "ash/public/cpp/capture_mode_test_api.h" #include "ash/root_window_controller.h" #include "ash/shell.h" #include "ash/system/status_area_widget.h" @@ -29,6 +31,8 @@ #include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "ash/wm/tablet_mode/tablet_mode_controller_test_api.h" #include "ash/wm/window_state.h" +#include "ash/wm/window_util.h" +#include "base/callback_helpers.h" #include "base/run_loop.h" #include "base/scoped_observation.h" #include "base/test/bind.h" @@ -39,6 +43,7 @@ #include "components/account_id/account_id.h" #include "ui/aura/window_tracker.h" #include "ui/compositor/scoped_animation_duration_scale_mode.h" +#include "ui/display/types/display_constants.h" #include "ui/events/keycodes/keyboard_codes_posix.h" #include "ui/events/test/event_generator.h" #include "ui/gfx/geometry/insets.h" @@ -319,6 +324,14 @@ loop.Run(); } + void WaitForCaptureFileToBeSaved() { + base::RunLoop run_loop; + CaptureModeTestApi().SetOnCaptureFileSavedCallback( + base::BindLambdaForTesting( + [&run_loop](const base::FilePath& path) { run_loop.Quit(); })); + run_loop.Run(); + } + private: base::test::ScopedFeatureList scoped_feature_list_; }; @@ -1500,6 +1513,171 @@ EXPECT_FALSE(window->subtree_capture_id().is_valid()); } +// Tests the behavior of screen recording with the presence of HDCP secure +// content on the screen in all capture mode sources (fullscreen, region, and +// window) depending on the test param. +class CaptureModeHdcpTest + : public CaptureModeTest, + public ::testing::WithParamInterface<CaptureModeSource> { + public: + CaptureModeHdcpTest() = default; + ~CaptureModeHdcpTest() override = default; + + // CaptureModeTest: + void SetUp() override { + CaptureModeTest::SetUp(); + window_ = CreateTestWindow(gfx::Rect(200, 200)); + protection_delegate_ = + std::make_unique<OutputProtectionDelegate>(window_.get()); + CaptureModeController::Get()->SetUserCaptureRegion(gfx::Rect(20, 50), + /*by_user=*/true); + } + + void TearDown() override { + protection_delegate_.reset(); + window_.reset(); + CaptureModeTest::TearDown(); + } + + // Enters the capture mode session. + void StartSessionForVideo() { + StartCaptureSession(GetParam(), CaptureModeType::kVideo); + } + + // Starts video recording from the capture mode source set by the test param. + void StartRecording() { + auto* controller = CaptureModeController::Get(); + ASSERT_TRUE(controller->IsActive()); + + switch (GetParam()) { + case CaptureModeSource::kFullscreen: + case CaptureModeSource::kRegion: + controller->StartVideoRecordingImmediatelyForTesting(); + break; + + case CaptureModeSource::kWindow: + // Window capture mode selects the window under the cursor as the + // capture source. + auto* event_generator = GetEventGenerator(); + event_generator->MoveMouseToCenterOf(window_.get()); + controller->StartVideoRecordingImmediatelyForTesting(); + break; + } + } + + protected: + std::unique_ptr<aura::Window> window_; + std::unique_ptr<OutputProtectionDelegate> protection_delegate_; +}; + +TEST_P(CaptureModeHdcpTest, WindowBecomesProtectedWhileRecording) { + StartSessionForVideo(); + StartRecording(); + + auto* controller = CaptureModeController::Get(); + EXPECT_TRUE(controller->is_recording_in_progress()); + + // The window becomes HDCP protected, which should end video recording. + base::HistogramTester histogram_tester; + protection_delegate_->SetProtection(display::CONTENT_PROTECTION_METHOD_HDCP, + base::DoNothing()); + + EXPECT_FALSE(controller->is_recording_in_progress()); + histogram_tester.ExpectBucketCount( + kEndRecordingReasonInClamshellHistogramName, + EndRecordingReason::kHdcpInterruption, 1); +} + +TEST_P(CaptureModeHdcpTest, ProtectedWindowDestruction) { + auto window_2 = CreateTestWindow(gfx::Rect(100, 50)); + OutputProtectionDelegate protection_delegate_2(window_2.get()); + protection_delegate_2.SetProtection(display::CONTENT_PROTECTION_METHOD_HDCP, + base::DoNothing()); + + StartSessionForVideo(); + StartRecording(); + + // Recording cannot start because of another protected window on the screen, + // except when we're capturing a different |window_|. + auto* controller = CaptureModeController::Get(); + EXPECT_FALSE(controller->IsActive()); + if (GetParam() == CaptureModeSource::kWindow) { + EXPECT_TRUE(controller->is_recording_in_progress()); + controller->EndVideoRecording(EndRecordingReason::kStopRecordingButton); + EXPECT_FALSE(controller->is_recording_in_progress()); + // Wait for the video file to be saved so that we can start a new recording. + WaitForCaptureFileToBeSaved(); + } else { + EXPECT_FALSE(controller->is_recording_in_progress()); + } + + // When the protected window is destroyed, it's possbile now to record from + // all capture sources. + window_2.reset(); + StartSessionForVideo(); + StartRecording(); + + EXPECT_FALSE(controller->IsActive()); + EXPECT_TRUE(controller->is_recording_in_progress()); +} + +TEST_P(CaptureModeHdcpTest, WindowBecomesProtectedBeforeRecording) { + protection_delegate_->SetProtection(display::CONTENT_PROTECTION_METHOD_HDCP, + base::DoNothing()); + StartSessionForVideo(); + StartRecording(); + + // Recording cannot even start. + auto* controller = CaptureModeController::Get(); + EXPECT_FALSE(controller->is_recording_in_progress()); + EXPECT_FALSE(controller->IsActive()); +} + +TEST_P(CaptureModeHdcpTest, ProtectedWindowInMultiDisplay) { + UpdateDisplay("400x400,401+0-400x400"); + auto roots = Shell::GetAllRootWindows(); + ASSERT_EQ(2u, roots.size()); + protection_delegate_->SetProtection(display::CONTENT_PROTECTION_METHOD_HDCP, + base::DoNothing()); + + // Move the cursor to the secondary display before starting the session to + // make sure the session starts on that display. + auto* event_generator = GetEventGenerator(); + MoveMouseToAndUpdateCursorDisplay(roots[1]->GetBoundsInScreen().CenterPoint(), + event_generator); + StartSessionForVideo(); + // Also, make sure the selected region is in the secondary display. + auto* controller = CaptureModeController::Get(); + EXPECT_EQ(controller->capture_mode_session()->current_root(), roots[1]); + StartRecording(); + + // Recording should be able to start (since the protected window is on the + // first display) unless the protected window itself is the one being + // recorded. + if (GetParam() == CaptureModeSource::kWindow) { + EXPECT_FALSE(controller->is_recording_in_progress()); + } else { + EXPECT_TRUE(controller->is_recording_in_progress()); + + // Moving the protected window to the display being recorded should + // terminate the recording. + base::HistogramTester histogram_tester; + window_util::MoveWindowToDisplay(window_.get(), + roots[1]->GetHost()->GetDisplayId()); + ASSERT_EQ(window_->GetRootWindow(), roots[1]); + EXPECT_FALSE(controller->is_recording_in_progress()); + histogram_tester.ExpectBucketCount( + kEndRecordingReasonInClamshellHistogramName, + EndRecordingReason::kHdcpInterruption, 1); + } +} + +INSTANTIATE_TEST_SUITE_P(All, + CaptureModeHdcpTest, + testing::Values(CaptureModeSource::kFullscreen, + CaptureModeSource::kRegion, + CaptureModeSource::kWindow)); + TEST_F(CaptureModeTest, ClosingWindowBeingRecorded) { auto window = CreateTestWindow(gfx::Rect(200, 200)); StartCaptureSession(CaptureModeSource::kWindow, CaptureModeType::kVideo);
diff --git a/ash/capture_mode/test_capture_mode_delegate.cc b/ash/capture_mode/test_capture_mode_delegate.cc index 4d606e5..1689abc 100644 --- a/ash/capture_mode/test_capture_mode_delegate.cc +++ b/ash/capture_mode/test_capture_mode_delegate.cc
@@ -121,4 +121,6 @@ void TestCaptureModeDelegate::BindAudioStreamFactory( mojo::PendingReceiver<audio::mojom::StreamFactory> receiver) {} +void TestCaptureModeDelegate::OnSessionStateChanged(bool started) {} + } // namespace ash
diff --git a/ash/capture_mode/test_capture_mode_delegate.h b/ash/capture_mode/test_capture_mode_delegate.h index 88503048..572d249 100644 --- a/ash/capture_mode/test_capture_mode_delegate.h +++ b/ash/capture_mode/test_capture_mode_delegate.h
@@ -41,6 +41,7 @@ override; void BindAudioStreamFactory( mojo::PendingReceiver<audio::mojom::StreamFactory> receiver) override; + void OnSessionStateChanged(bool started) override; private: std::unique_ptr<FakeRecordingService> fake_service_;
diff --git a/ash/clipboard/clipboard_history.cc b/ash/clipboard/clipboard_history.cc index 5891cbb6..2965c00 100644 --- a/ash/clipboard/clipboard_history.cc +++ b/ash/clipboard/clipboard_history.cc
@@ -6,6 +6,7 @@ #include "ash/clipboard/clipboard_history_util.h" #include "ash/clipboard/clipboard_nudge_controller.h" +#include "base/metrics/histogram_functions.h" #include "base/stl_util.h" #include "base/threading/sequenced_task_runner_handle.h" #include "ui/base/clipboard/clipboard_monitor.h" @@ -66,8 +67,6 @@ if (!ClipboardHistoryUtil::IsEnabledInCurrentMode()) return; - // TODO(newcomer): Prevent Clipboard from recording metrics when pausing - // observation. if (num_pause_ > 0) return; @@ -87,6 +86,15 @@ return; } + // Debounce calls to `OnClipboardOperation()`. Certain surfaces + // (Omnibox) may Read/Write to the clipboard multiple times in one user + // initiated operation. + clipboard_histogram_weak_factory_.InvalidateWeakPtrs(); + base::SequencedTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(&ClipboardHistory::OnClipboardOperation, + clipboard_histogram_weak_factory_.GetWeakPtr(), + /*copy=*/true)); + // We post commit |clipboard_data| at the end of the current task sequence to // debounce the case where multiple copies are programmatically performed. // Since only the most recent copy will be at the top of the clipboard, the @@ -102,6 +110,39 @@ commit_data_weak_factory_.GetWeakPtr(), *clipboard_data)); } +void ClipboardHistory::OnClipboardDataRead() { + if (num_pause_ > 0) + return; + + // Debounce calls to `OnClipboardOperation()`. Certain surfaces + // (Omnibox) may Read/Write to the clipboard multiple times in one user + // initiated operation. + clipboard_histogram_weak_factory_.InvalidateWeakPtrs(); + base::SequencedTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(&ClipboardHistory::OnClipboardOperation, + clipboard_histogram_weak_factory_.GetWeakPtr(), + /*copy=*/false)); +} + +void ClipboardHistory::OnClipboardOperation(bool copy) { + if (copy) { + consecutive_copies_++; + if (consecutive_pastes_ > 0) { + base::UmaHistogramCounts100("Ash.Clipboard.ConsecutivePastes", + consecutive_pastes_); + consecutive_pastes_ = 0; + } + return; + } + + consecutive_pastes_++; + if (consecutive_copies_ > 0) { + base::UmaHistogramCounts100("Ash.Clipboard.ConsecutiveCopies", + consecutive_copies_); + consecutive_copies_ = 0; + } +} + base::WeakPtr<ClipboardHistory> ClipboardHistory::GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
diff --git a/ash/clipboard/clipboard_history.h b/ash/clipboard/clipboard_history.h index d2ce410..8a2ffb5c 100644 --- a/ash/clipboard/clipboard_history.h +++ b/ash/clipboard/clipboard_history.h
@@ -56,8 +56,9 @@ // do nothing. void RemoveItemForId(const base::UnguessableToken& id); - // ClipboardMonitor: + // ui::ClipboardObserver: void OnClipboardDataChanged() override; + void OnClipboardDataRead() override; base::WeakPtr<ClipboardHistory> GetWeakPtr(); @@ -73,9 +74,18 @@ void Pause(); void Resume(); + // Keeps track of consecutive clipboard operations and records metrics. + void OnClipboardOperation(bool copy); + // The count of pauses. size_t num_pause_ = 0; + // The number of consecutive copies, reset after a paste. + int consecutive_copies_ = 0; + + // The number of consecutive pastes, reset after a copy. + int consecutive_pastes_ = 0; + // The history of data copied to the Clipboard. Items of the list are sorted // by recency. std::list<ClipboardHistoryItem> history_list_; @@ -84,9 +94,14 @@ // ClipboardHistory. mutable base::ObserverList<Observer> observers_; - // Factory to create WeakPtrs used to debounce calls to CommitData(). + // Factory to create WeakPtrs used to debounce calls to `CommitData()`. base::WeakPtrFactory<ClipboardHistory> commit_data_weak_factory_{this}; + // Factory to create WeakPtrs used to debounce calls to + // `OnClipboardOperation()`. + base::WeakPtrFactory<ClipboardHistory> clipboard_histogram_weak_factory_{ + this}; + // Factory to create WeakPtrs for ClipboardHistory. base::WeakPtrFactory<ClipboardHistory> weak_factory_{this}; };
diff --git a/ash/clipboard/clipboard_history_controller_impl.cc b/ash/clipboard/clipboard_history_controller_impl.cc index 90fc252..7dc8caf 100644 --- a/ash/clipboard/clipboard_history_controller_impl.cc +++ b/ash/clipboard/clipboard_history_controller_impl.cc
@@ -260,9 +260,25 @@ accelerator_target_->OnMenuShown(); // The first menu item should be selected as default after the clipboard - // history menu shows. - context_menu_->SelectMenuItemWithCommandId( - ClipboardHistoryUtil::kFirstItemCommandId); + // history menu shows. Note that the menu item is selected asynchronously + // to avoid the interference from synthesized mouse events. + menu_task_timer_.Start( + FROM_HERE, base::TimeDelta(), + base::BindOnce( + [](const base::WeakPtr<ClipboardHistoryControllerImpl>& + controller_weak_ptr) { + if (!controller_weak_ptr) + return; + + controller_weak_ptr->context_menu_->SelectMenuItemWithCommandId( + ClipboardHistoryUtil::kFirstItemCommandId); + if (controller_weak_ptr->initial_item_selected_callback_for_test_) { + controller_weak_ptr->initial_item_selected_callback_for_test_ + .Run(); + } + }, + weak_ptr_factory_.GetWeakPtr())); + for (auto& observer : observers_) observer.OnClipboardHistoryMenuShown(); } @@ -567,14 +583,15 @@ // Reset `context_menu_` in the asynchronous way. Because the menu may be // accessed after `OnMenuClosed()` is called. - base::SequencedTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce( - [](const base::WeakPtr<ClipboardHistoryControllerImpl>& - controller_weak_ptr) { - if (controller_weak_ptr) - controller_weak_ptr->context_menu_.reset(); - }, - weak_ptr_factory_.GetWeakPtr())); + menu_task_timer_.Start( + FROM_HERE, base::TimeDelta(), + base::BindOnce( + [](const base::WeakPtr<ClipboardHistoryControllerImpl>& + controller_weak_ptr) { + if (controller_weak_ptr) + controller_weak_ptr->context_menu_.reset(); + }, + weak_ptr_factory_.GetWeakPtr())); } } // namespace ash
diff --git a/ash/clipboard/clipboard_history_controller_impl.h b/ash/clipboard/clipboard_history_controller_impl.h index 23aa497453..6ddde181 100644 --- a/ash/clipboard/clipboard_history_controller_impl.h +++ b/ash/clipboard/clipboard_history_controller_impl.h
@@ -12,9 +12,11 @@ #include "ash/clipboard/clipboard_history.h" #include "ash/clipboard/clipboard_history_item.h" #include "ash/public/cpp/clipboard_history_controller.h" +#include "base/callback.h" #include "base/memory/weak_ptr.h" #include "base/observer_list.h" #include "base/optional.h" +#include "base/timer/timer.h" namespace gfx { class Rect; @@ -71,6 +73,11 @@ return context_menu_.get(); } + void set_initial_item_selected_callback_for_test( + base::RepeatingClosure new_callback) { + initial_item_selected_callback_for_test_ = new_callback; + } + private: class AcceleratorTarget; class MenuDelegate; @@ -141,6 +148,15 @@ // Whether a paste is currently being performed. bool currently_pasting_ = false; + // Used to post asynchronous tasks when opening or closing the clipboard + // history menu. Note that those tasks have data races between each other. + // The timer can guarantee that at most one task is alive. + base::OneShotTimer menu_task_timer_; + + // Called when the first item view is selected after the clipboard history + // menu opens. + base::RepeatingClosure initial_item_selected_callback_for_test_; + base::WeakPtrFactory<ClipboardHistoryControllerImpl> weak_ptr_factory_{this}; };
diff --git a/ash/clipboard/clipboard_history_controller_unittest.cc b/ash/clipboard/clipboard_history_controller_unittest.cc index adb3e6bf..05effb5 100644 --- a/ash/clipboard/clipboard_history_controller_unittest.cc +++ b/ash/clipboard/clipboard_history_controller_unittest.cc
@@ -187,7 +187,6 @@ } kTestCases[] = {{user_manager::USER_TYPE_REGULAR, true}, {user_manager::USER_TYPE_GUEST, true}, {user_manager::USER_TYPE_PUBLIC_ACCOUNT, false}, - {user_manager::USER_TYPE_SUPERVISED, true}, {user_manager::USER_TYPE_KIOSK_APP, false}, {user_manager::USER_TYPE_CHILD, true}, {user_manager::USER_TYPE_ARC_KIOSK_APP, false},
diff --git a/ash/clipboard/clipboard_history_util.cc b/ash/clipboard/clipboard_history_util.cc index 04cf7e6..241ca44 100644 --- a/ash/clipboard/clipboard_history_util.cc +++ b/ash/clipboard/clipboard_history_util.cc
@@ -123,7 +123,7 @@ return false; case LoginStatus::USER: case LoginStatus::GUEST: - case LoginStatus::SUPERVISED: + case LoginStatus::CHILD: return true; } }
diff --git a/ash/display/display_prefs.cc b/ash/display/display_prefs.cc index a856436..60d754e 100644 --- a/ash/display/display_prefs.cc +++ b/ash/display/display_prefs.cc
@@ -187,7 +187,7 @@ return false; return *user_type == user_manager::USER_TYPE_REGULAR || *user_type == user_manager::USER_TYPE_CHILD || - *user_type == user_manager::USER_TYPE_SUPERVISED || + *user_type == user_manager::USER_TYPE_SUPERVISED_DEPRECATED || *user_type == user_manager::USER_TYPE_KIOSK_APP; }
diff --git a/ash/display/output_protection_delegate.cc b/ash/display/output_protection_delegate.cc index d96d2606a..3caedee 100644 --- a/ash/display/output_protection_delegate.cc +++ b/ash/display/output_protection_delegate.cc
@@ -4,6 +4,8 @@ #include "ash/display/output_protection_delegate.h" +#include "ash/capture_mode/capture_mode_controller.h" +#include "ash/public/cpp/ash_features.h" #include "ash/shell.h" #include "base/callback_helpers.h" #include "ui/display/display.h" @@ -20,6 +22,14 @@ return Shell::Get()->display_configurator()->content_protection_manager(); } +void MaybeSetCaptureModeWindowProtection(aura::Window* window, + uint32_t protection_mask) { + if (features::IsCaptureModeEnabled()) { + CaptureModeController::Get()->SetWindowProtectionMask(window, + protection_mask); + } +} + } // namespace struct OutputProtectionDelegate::ClientIdHolder { @@ -48,6 +58,8 @@ display::Screen::GetScreen()->RemoveObserver(this); window_->RemoveObserver(this); + MaybeSetCaptureModeWindowProtection(window_, + display::CONTENT_PROTECTION_METHOD_NONE); } void OutputProtectionDelegate::OnDisplayMetricsChanged( @@ -76,6 +88,8 @@ DCHECK_EQ(window, window_); display::Screen::GetScreen()->RemoveObserver(this); window_->RemoveObserver(this); + MaybeSetCaptureModeWindowProtection(window_, + display::CONTENT_PROTECTION_METHOD_NONE); window_ = nullptr; } @@ -93,6 +107,13 @@ void OutputProtectionDelegate::SetProtection(uint32_t protection_mask, SetProtectionCallback callback) { + protection_mask_ = protection_mask; + + // Capture mode screen recording doesn't rely on display protection, and hence + // must be informed with the new window's protection. + if (window_) + MaybeSetCaptureModeWindowProtection(window_, protection_mask); + if (!RegisterClientIfNecessary()) { std::move(callback).Run(/*success=*/false); return; @@ -100,7 +121,6 @@ manager()->ApplyContentProtection(client_->id, display_id_, protection_mask, std::move(callback)); - protection_mask_ = protection_mask; } void OutputProtectionDelegate::OnWindowMayHaveMovedToAnotherDisplay() { @@ -118,6 +138,11 @@ manager()->ApplyContentProtection(client_->id, display_id_, display::CONTENT_PROTECTION_METHOD_NONE, base::DoNothing()); + + // The window may have moved to a display that is currently being recorded, + // so we need to refresh Capture Mode's content protection. + if (features::IsCaptureModeEnabled()) + CaptureModeController::Get()->RefreshContentProtection(); } display_id_ = new_display_id; }
diff --git a/ash/login/ui/lock_contents_view.cc b/ash/login/ui/lock_contents_view.cc index 54df7423..a036e83 100644 --- a/ash/login/ui/lock_contents_view.cc +++ b/ash/login/ui/lock_contents_view.cc
@@ -1993,8 +1993,10 @@ Shell::Get()->login_screen_controller()->OnFocusPod(big_user_account_id); UpdateEasyUnlockIconForUser(big_user_account_id); - // http://crbug/866790: After Supervised Users are deprecated, remove this. - if (big_user.basic_user_info.type == user_manager::USER_TYPE_SUPERVISED) { + // TODO(crbug/1164090): After Supervised Users are deprecated, remove this. + if (big_user.basic_user_info.type == + user_manager::USER_TYPE_SUPERVISED_DEPRECATED) { + // TODO(crbug/1164090): Remove this string and the associated screenshot. base::string16 message = l10n_util::GetStringUTF16( IDS_ASH_LOGIN_POD_LEGACY_SUPERVISED_EXPIRATION_WARNING); // Shows supervised user deprecation message as a persistent error bubble.
diff --git a/ash/login/ui/lock_contents_view.h b/ash/login/ui/lock_contents_view.h index f085dee..ad318b4 100644 --- a/ash/login/ui/lock_contents_view.h +++ b/ash/login/ui/lock_contents_view.h
@@ -470,6 +470,7 @@ // Bubble for displaying warning banner message. LoginErrorBubble* warning_banner_bubble_; // Bubble for displaying supervised user deprecation message. + // TODO(crbug/1164090): Remove this. LoginErrorBubble* supervised_user_deprecation_bubble_; // Bottom status indicator displaying entreprise domain or ADB enabled alert
diff --git a/ash/login/ui/login_password_view.cc b/ash/login/ui/login_password_view.cc index b613081..4ced3391 100644 --- a/ash/login/ui/login_password_view.cc +++ b/ash/login/ui/login_password_view.cc
@@ -941,14 +941,22 @@ } if (handled_should_show) { + // If the view that is currently handled should be shown, we immediately + // show it; if the other view should be shown as well, we make it invisible + // for the moment and start a cyclic animation that will show these two + // views alternatively. handled_view->SetVisible(true); if (other_should_show) { other_view->SetVisible(false); left_icon_->ScheduleAnimation(handled_view, other_view); } } else { + // If the view that is currently handled should now be invisible, we + // immediately hide it and we abort the cyclic animation if it was running. + // We also make the other view visible if needed, as its current state + // may depend on how long the animation has been running. left_icon_->AbortAnimationIfAny(); - other_view->SetVisible(should_show_easy_unlock_); + other_view->SetVisible(other_should_show); handled_view->SetVisible(false); } password_row_->Layout();
diff --git a/ash/login/ui/login_password_view_test.cc b/ash/login/ui/login_password_view_test.cc index 0b42156..23568c5 100644 --- a/ash/login/ui/login_password_view_test.cc +++ b/ash/login/ui/login_password_view_test.cc
@@ -356,6 +356,12 @@ base::string16() /*accessibility_label*/); EXPECT_TRUE(test_api.easy_unlock_icon()->GetVisible()); EXPECT_FALSE(test_api.capslock_icon()->GetVisible()); + + // Hide the easy unlock icon, the capslock icon should be shown. + view_->SetEasyUnlockIcon(EasyUnlockIconId::NONE, + base::string16() /*accessibility_label*/); + EXPECT_FALSE(test_api.easy_unlock_icon()->GetVisible()); + EXPECT_TRUE(test_api.capslock_icon()->GetVisible()); } // Verifies that the password textfield clears after a delay when the display
diff --git a/ash/login/ui/login_user_menu_view.cc b/ash/login/ui/login_user_menu_view.cc index c9fb416..2a993959 100644 --- a/ash/login/ui/login_user_menu_view.cc +++ b/ash/login/ui/login_user_menu_view.cc
@@ -203,7 +203,8 @@ user_manager::UserType type = user.basic_user_info.type; base::string16 part1 = l10n_util::GetStringUTF16( IDS_ASH_LOGIN_POD_NON_OWNER_USER_REMOVE_WARNING_PART_1); - if (type == user_manager::UserType::USER_TYPE_SUPERVISED) { + // TODO(crbug/1164090): Remove this section and the strings. + if (type == user_manager::UserType::USER_TYPE_SUPERVISED_DEPRECATED) { part1 = l10n_util::GetStringFUTF16( IDS_ASH_LOGIN_POD_LEGACY_SUPERVISED_USER_REMOVE_WARNING, base::UTF8ToUTF16(kLegacySupervisedUserManagementDisplayURL));
diff --git a/ash/login_status.h b/ash/login_status.h index 6d835e65..560729a 100644 --- a/ash/login_status.h +++ b/ash/login_status.h
@@ -13,7 +13,7 @@ USER, // A regular user is logged in GUEST, // A guest is logged in (i.e. incognito) PUBLIC, // A public account is logged in - SUPERVISED, // A supervised user is logged in + CHILD, // A Family Link user is logged in KIOSK_APP // In kiosk mode for Chrome app, ARC, or PWA. };
diff --git a/ash/public/cpp/capture_mode_delegate.h b/ash/public/cpp/capture_mode_delegate.h index 71a964c..7ef1a9f 100644 --- a/ash/public/cpp/capture_mode_delegate.h +++ b/ash/public/cpp/capture_mode_delegate.h
@@ -85,6 +85,9 @@ // Binds the given audio StreamFactory |receiver| to the audio service. virtual void BindAudioStreamFactory( mojo::PendingReceiver<audio::mojom::StreamFactory> receiver) = 0; + + // Called when a capture mode session starts or stops. + virtual void OnSessionStateChanged(bool started) = 0; }; } // namespace ash
diff --git a/ash/public/cpp/test/shell_test_api.h b/ash/public/cpp/test/shell_test_api.h index a0d6891..5fa468ba 100644 --- a/ash/public/cpp/test/shell_test_api.h +++ b/ash/public/cpp/test/shell_test_api.h
@@ -116,6 +116,14 @@ // It returns nullptr when app-list is not shown. PaginationModel* GetAppListPaginationModel(); + // Shows the context menu associated with the primary root window at point (1, + // 1). + void ShowContextMenu(); + + // Returns true if the context menu associated with the primary root window is + // shown. + bool IsContextMenuShown() const; + private: Shell* shell_; // not owned
diff --git a/ash/rotator/screen_rotation_animator.cc b/ash/rotator/screen_rotation_animator.cc index 13f2cef0..5c28d86 100644 --- a/ash/rotator/screen_rotation_animator.cc +++ b/ash/rotator/screen_rotation_animator.cc
@@ -360,11 +360,10 @@ std::unique_ptr<ui::LayerTreeOwner> ScreenRotationAnimator::CopyLayerTree( std::unique_ptr<viz::CopyOutputResult> result) { + DCHECK_EQ(result->size(), + GetScreenRotationContainer(root_window_)->layer()->size()); std::unique_ptr<ui::Layer> copy_layer = CreateLayerFromCopyOutputResult(std::move(result)); - const gfx::Rect rect( - GetScreenRotationContainer(root_window_)->layer()->size()); - copy_layer->SetBounds(rect); // TODO(crbug.com/1040279): This is a workaround and should be removed once // the issue is fixed. copy_layer->SetFillsBoundsOpaquely(false);
diff --git a/ash/rotator/screen_rotation_animator_unittest.cc b/ash/rotator/screen_rotation_animator_unittest.cc index 6eec862cc..ed6e3cf 100644 --- a/ash/rotator/screen_rotation_animator_unittest.cc +++ b/ash/rotator/screen_rotation_animator_unittest.cc
@@ -539,7 +539,12 @@ // request callback called, it should stop rotating. TEST_F(ScreenRotationAnimatorSmoothAnimationTest, RemoveExternalSecondaryDisplayBeforeSecondCopyCallback) { - UpdateDisplay("640x480,800x600"); + { + // Disable wallpaper animation on a secondary display. + ui::ScopedAnimationDurationScaleMode disable( + ui::ScopedAnimationDurationScaleMode::ZERO_DURATION); + UpdateDisplay("640x480,800x600"); + } EXPECT_EQ(2U, display_manager()->GetNumDisplays()); const int64_t primary_display_id = display_manager()->GetDisplayAt(0).id();
diff --git a/ash/session/session_controller_impl.cc b/ash/session/session_controller_impl.cc index 2476f14..1c40040 100644 --- a/ash/session/session_controller_impl.cc +++ b/ash/session/session_controller_impl.cc
@@ -158,23 +158,15 @@ return (*it).get(); } -bool SessionControllerImpl::IsUserSupervised() const { +bool SessionControllerImpl::IsUserChildOrDeprecatedSupervised() const { if (!IsActiveUserSessionStarted()) return false; user_manager::UserType active_user_type = GetUserSession(0)->user_info.type; - return active_user_type == user_manager::USER_TYPE_SUPERVISED || + return active_user_type == user_manager::USER_TYPE_SUPERVISED_DEPRECATED || active_user_type == user_manager::USER_TYPE_CHILD; } -bool SessionControllerImpl::IsUserLegacySupervised() const { - if (!IsActiveUserSessionStarted()) - return false; - - user_manager::UserType active_user_type = GetUserSession(0)->user_info.type; - return active_user_type == user_manager::USER_TYPE_SUPERVISED; -} - bool SessionControllerImpl::IsUserChild() const { if (!IsActiveUserSessionStarted()) return false; @@ -567,12 +559,10 @@ return LoginStatus::GUEST; case user_manager::USER_TYPE_PUBLIC_ACCOUNT: return LoginStatus::PUBLIC; - case user_manager::USER_TYPE_SUPERVISED: - return LoginStatus::SUPERVISED; case user_manager::USER_TYPE_KIOSK_APP: return LoginStatus::KIOSK_APP; case user_manager::USER_TYPE_CHILD: - return LoginStatus::SUPERVISED; + return LoginStatus::CHILD; case user_manager::USER_TYPE_ARC_KIOSK_APP: return LoginStatus::KIOSK_APP; case user_manager::USER_TYPE_ACTIVE_DIRECTORY: @@ -581,6 +571,7 @@ case user_manager::USER_TYPE_WEB_KIOSK_APP: return LoginStatus::KIOSK_APP; case user_manager::NUM_USER_TYPES: + case user_manager::USER_TYPE_SUPERVISED_DEPRECATED: // Avoid having a "default" case so the compiler catches new enum values. NOTREACHED(); return LoginStatus::USER;
diff --git a/ash/session/session_controller_impl.h b/ash/session/session_controller_impl.h index 02cf66d..cc0c009 100644 --- a/ash/session/session_controller_impl.h +++ b/ash/session/session_controller_impl.h
@@ -106,12 +106,10 @@ // Gets the primary user session. const UserSession* GetPrimaryUserSession() const; - // Returns true if the current user is supervised: has legacy supervised - // account or kid account. - bool IsUserSupervised() const; - - // Returns true if the current user is legacy supervised. - bool IsUserLegacySupervised() const; + // Returns true if the current user is supervised: has deprecated legacy + // supervised account or kid account. + // TODO(crbug/1155729): Remove and replace all calls with IsUserChild(). + bool IsUserChildOrDeprecatedSupervised() const; // Returns true if the current user is a child account. bool IsUserChild() const;
diff --git a/ash/session/session_controller_impl_unittest.cc b/ash/session/session_controller_impl_unittest.cc index 8904def..b3a5fa5 100644 --- a/ash/session/session_controller_impl_unittest.cc +++ b/ash/session/session_controller_impl_unittest.cc
@@ -294,9 +294,8 @@ {user_manager::USER_TYPE_REGULAR, LoginStatus::USER}, {user_manager::USER_TYPE_GUEST, LoginStatus::GUEST}, {user_manager::USER_TYPE_PUBLIC_ACCOUNT, LoginStatus::PUBLIC}, - {user_manager::USER_TYPE_SUPERVISED, LoginStatus::SUPERVISED}, {user_manager::USER_TYPE_KIOSK_APP, LoginStatus::KIOSK_APP}, - {user_manager::USER_TYPE_CHILD, LoginStatus::SUPERVISED}, + {user_manager::USER_TYPE_CHILD, LoginStatus::CHILD}, {user_manager::USER_TYPE_ARC_KIOSK_APP, LoginStatus::KIOSK_APP}, {user_manager::USER_TYPE_WEB_KIOSK_APP, LoginStatus::KIOSK_APP} // TODO: Add USER_TYPE_ACTIVE_DIRECTORY if we add a status for it. @@ -408,15 +407,6 @@ } } -TEST_F(SessionControllerImplTest, IsUserSupervised) { - UserSession session; - session.session_id = 1u; - session.user_info.type = user_manager::USER_TYPE_SUPERVISED; - controller()->UpdateUserSession(session); - - EXPECT_TRUE(controller()->IsUserSupervised()); -} - TEST_F(SessionControllerImplTest, IsUserChild) { UserSession session; session.session_id = 1u; @@ -426,7 +416,7 @@ EXPECT_TRUE(controller()->IsUserChild()); // Child accounts are supervised. - EXPECT_TRUE(controller()->IsUserSupervised()); + EXPECT_TRUE(controller()->IsUserChildOrDeprecatedSupervised()); } using SessionControllerImplPrefsTest = NoSessionAshTestBase;
diff --git a/ash/shell_test_api.cc b/ash/shell_test_api.cc index d2b28d1..7ee941eb 100644 --- a/ash/shell_test_api.cc +++ b/ash/shell_test_api.cc
@@ -252,4 +252,13 @@ return view->GetAppsPaginationModel(); } +void ShellTestApi::ShowContextMenu() { + Shell::GetPrimaryRootWindowController()->ShowContextMenu( + gfx::Point(1, 1), ui::MENU_SOURCE_MOUSE); +} + +bool ShellTestApi::IsContextMenuShown() const { + return Shell::GetPrimaryRootWindowController()->IsContextMenuShown(); +} + } // namespace ash
diff --git a/ash/system/bluetooth/bluetooth_power_controller.cc b/ash/system/bluetooth/bluetooth_power_controller.cc index f34d9a1..64211ae 100644 --- a/ash/system/bluetooth/bluetooth_power_controller.cc +++ b/ash/system/bluetooth/bluetooth_power_controller.cc
@@ -294,7 +294,7 @@ user_manager::UserType user_type) const { return user_type == user_manager::USER_TYPE_REGULAR || user_type == user_manager::USER_TYPE_CHILD || - user_type == user_manager::USER_TYPE_SUPERVISED || + user_type == user_manager::USER_TYPE_SUPERVISED_DEPRECATED || user_type == user_manager::USER_TYPE_ACTIVE_DIRECTORY; }
diff --git a/ash/system/dark_mode/dark_mode_feature_pod_controller.cc b/ash/system/dark_mode/dark_mode_feature_pod_controller.cc index a6b7734..fe20ab9 100644 --- a/ash/system/dark_mode/dark_mode_feature_pod_controller.cc +++ b/ash/system/dark_mode/dark_mode_feature_pod_controller.cc
@@ -33,6 +33,7 @@ button_->SetLabel(l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_DARK_THEME)); button_->SetLabelTooltip(l10n_util::GetStringUTF16( IDS_ASH_STATUS_TRAY_DARK_THEME_SETTINGS_TOOLTIP)); + button_->ShowDetailedViewArrow(); // TODO(minch): Add the logic for login screen. button_->SetVisible( Shell::Get()->session_controller()->IsActiveUserSessionStarted());
diff --git a/ash/system/palette/palette_tray.cc b/ash/system/palette/palette_tray.cc index 4cc28e53..61afa9e 100644 --- a/ash/system/palette/palette_tray.cc +++ b/ash/system/palette/palette_tray.cc
@@ -97,11 +97,14 @@ icon_ = AddChildView(std::make_unique<views::ImageView>()); icon_->SetImage(delegate->GetBatteryImage()); - label_ = AddChildView(std::make_unique<views::Label>( - l10n_util::GetStringUTF16(delegate->GetLabelIdForBatteryLevel()))); - label_->SetEnabledColor(delegate->GetColorForBatteryLevel()); - TrayPopupUtils::SetLabelFontList(label_, - TrayPopupUtils::FontStyle::kSmallTitle); + + if (delegate->IsBatteryLevelLow()) { + label_ = AddChildView(std::make_unique<views::Label>( + l10n_util::GetStringUTF16(IDS_ASH_STYLUS_BATTERY_LOW_LABEL))); + label_->SetEnabledColor(delegate->GetColorForBatteryLevel()); + TrayPopupUtils::SetLabelFontList(label_, + TrayPopupUtils::FontStyle::kSmallTitle); + } } private:
diff --git a/ash/system/palette/stylus_battery_delegate.cc b/ash/system/palette/stylus_battery_delegate.cc index 7568066..92a27eb 100644 --- a/ash/system/palette/stylus_battery_delegate.cc +++ b/ash/system/palette/stylus_battery_delegate.cc
@@ -15,10 +15,8 @@ namespace ash { namespace { -// Battery percentage thresholds to used to label the battery level -// as Hi, Med or Low. +// Battery percentage threshold used to label the battery level as Low. constexpr int kStylusLowBatteryThreshold = 24; -constexpr int kStylusMediumBatteryThreshold = 71; } // namespace StylusBatteryDelegate::StylusBatteryDelegate() { @@ -34,17 +32,7 @@ AshColorProvider::ContentLayerType::kIconColorAlert); } return AshColorProvider::Get()->GetContentLayerColor( - AshColorProvider::ContentLayerType::kIconColorPositive); -} - -int StylusBatteryDelegate::GetLabelIdForBatteryLevel() const { - if (battery_level_ <= kStylusLowBatteryThreshold) { - return IDS_ASH_STYLUS_BATTERY_LOW_LABEL; - } - if (battery_level_ <= kStylusMediumBatteryThreshold) { - return IDS_ASH_STYLUS_BATTERY_MED_LABEL; - } - return IDS_ASH_STYLUS_BATTERY_HI_LABEL; + AshColorProvider::ContentLayerType::kIconColorPrimary); } gfx::ImageSkia StylusBatteryDelegate::GetBatteryImage() const { @@ -58,6 +46,10 @@ icon_fg_color); } +bool StylusBatteryDelegate::IsBatteryLevelLow() const { + return battery_level_ <= kStylusLowBatteryThreshold; +} + void StylusBatteryDelegate::OnAddingBattery( const PeripheralBatteryListener::BatteryInfo& battery) { battery_level_ = battery.level;
diff --git a/ash/system/palette/stylus_battery_delegate.h b/ash/system/palette/stylus_battery_delegate.h index 33280c5..75c1145 100644 --- a/ash/system/palette/stylus_battery_delegate.h +++ b/ash/system/palette/stylus_battery_delegate.h
@@ -22,8 +22,8 @@ ~StylusBatteryDelegate() override; SkColor GetColorForBatteryLevel() const; - int GetLabelIdForBatteryLevel() const; gfx::ImageSkia GetBatteryImage() const; + bool IsBatteryLevelLow() const; base::Optional<uint8_t> battery_level() const { return battery_level_; }
diff --git a/ash/system/supervised/supervised_icon_string.cc b/ash/system/supervised/supervised_icon_string.cc index 356a4c76..a9ad29d 100644 --- a/ash/system/supervised/supervised_icon_string.cc +++ b/ash/system/supervised/supervised_icon_string.cc
@@ -19,8 +19,7 @@ SessionControllerImpl* session_controller = Shell::Get()->session_controller(); - if (session_controller->IsUserSupervised() && - session_controller->IsUserChild()) + if (session_controller->IsUserChild()) return kSystemMenuSupervisedUserIcon; return kSystemMenuLegacySupervisedUserIcon; @@ -29,7 +28,7 @@ base::string16 GetSupervisedUserMessage() { SessionControllerImpl* session_controller = Shell::Get()->session_controller(); - DCHECK(session_controller->IsUserSupervised()); + DCHECK(session_controller->IsUserChildOrDeprecatedSupervised()); DCHECK(session_controller->IsActiveUserSessionStarted()); // Get the active user session. @@ -41,6 +40,7 @@ UTF8ToUTF16(user_session->second_custodian_email); // Regular supervised user. The "manager" is the first custodian. + // TODO(crbug/1164090): Remove this section. if (!Shell::Get()->session_controller()->IsUserChild()) { return l10n_util::GetStringFUTF16(IDS_ASH_USER_IS_SUPERVISED_BY_NOTICE, first_custodian);
diff --git a/ash/system/supervised/supervised_notification_controller.cc b/ash/system/supervised/supervised_notification_controller.cc deleted file mode 100644 index fac6fe4..0000000 --- a/ash/system/supervised/supervised_notification_controller.cc +++ /dev/null
@@ -1,93 +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. - -#include "ash/system/supervised/supervised_notification_controller.h" - -#include "ash/public/cpp/notification_utils.h" -#include "ash/session/session_controller_impl.h" -#include "ash/shell.h" -#include "ash/strings/grit/ash_strings.h" -#include "ash/system/supervised/supervised_icon_string.h" -#include "chromeos/ui/vector_icons/vector_icons.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/message_center/message_center.h" -#include "ui/message_center/public/cpp/notification.h" -#include "ui/message_center/public/cpp/notification_delegate.h" - -using message_center::MessageCenter; -using message_center::Notification; - -namespace ash { - -namespace { -const char kNotifierSupervisedUser[] = "ash.locally-managed-user"; -} // namespace - -const char SupervisedNotificationController::kNotificationId[] = - "chrome://user/locally-managed"; - -SupervisedNotificationController::SupervisedNotificationController() = default; - -SupervisedNotificationController::~SupervisedNotificationController() = default; - -void SupervisedNotificationController::OnActiveUserSessionChanged( - const AccountId& account_id) { - OnUserSessionUpdated(account_id); -} - -void SupervisedNotificationController::OnUserSessionAdded( - const AccountId& account_id) { - OnUserSessionUpdated(account_id); -} - -void SupervisedNotificationController::OnUserSessionUpdated( - const AccountId& account_id) { - SessionControllerImpl* session_controller = - Shell::Get()->session_controller(); - if (!session_controller->IsUserSupervised()) - return; - - // Get the active user session. - DCHECK(session_controller->IsActiveUserSessionStarted()); - const UserSession* const user_session = session_controller->GetUserSession(0); - DCHECK(user_session); - - // Only respond to updates for the active user. - if (user_session->user_info.account_id != account_id) - return; - - // Show notifications when custodian data first becomes available on login - // and if the custodian data changes. - if (custodian_email_ == user_session->custodian_email && - second_custodian_email_ == user_session->second_custodian_email) { - return; - } - custodian_email_ = user_session->custodian_email; - second_custodian_email_ = user_session->second_custodian_email; - - CreateOrUpdateNotification(); -} - -// static -void SupervisedNotificationController::CreateOrUpdateNotification() { - // No notification for the child user. - if (Shell::Get()->session_controller()->IsUserChild()) - return; - - // Regular supervised user. - std::unique_ptr<Notification> notification = CreateSystemNotification( - message_center::NOTIFICATION_TYPE_SIMPLE, kNotificationId, - l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_SUPERVISED_LABEL), - GetSupervisedUserMessage(), base::string16() /* display_source */, GURL(), - message_center::NotifierId(message_center::NotifierType::SYSTEM_COMPONENT, - kNotifierSupervisedUser), - message_center::RichNotificationData(), nullptr, - chromeos::kNotificationSupervisedUserIcon, - message_center::SystemNotificationWarningLevel::NORMAL); - notification->SetSystemPriority(); - // AddNotification does an update if the notification already exists. - MessageCenter::Get()->AddNotification(std::move(notification)); -} - -} // namespace ash
diff --git a/ash/system/supervised/supervised_notification_controller.h b/ash/system/supervised/supervised_notification_controller.h deleted file mode 100644 index 989c051..0000000 --- a/ash/system/supervised/supervised_notification_controller.h +++ /dev/null
@@ -1,44 +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. - -#ifndef ASH_SYSTEM_SUPERVISED_SUPERVISED_NOTIFICATION_CONTROLLER_H_ -#define ASH_SYSTEM_SUPERVISED_SUPERVISED_NOTIFICATION_CONTROLLER_H_ - -#include <string> - -#include "ash/ash_export.h" -#include "ash/public/cpp/session/session_observer.h" -#include "base/strings/string16.h" - -namespace ash { - -// Controller class to manage supervised user notification. -class ASH_EXPORT SupervisedNotificationController : public SessionObserver { - public: - SupervisedNotificationController(); - ~SupervisedNotificationController() override; - - // SessionObserver: - void OnActiveUserSessionChanged(const AccountId& account_id) override; - void OnUserSessionAdded(const AccountId& account_id) override; - void OnUserSessionUpdated(const AccountId& account_id) override; - - private: - friend class SupervisedNotificationControllerTest; - - static const char kNotificationId[]; - - static void CreateOrUpdateNotification(); - - std::string custodian_email_; - std::string second_custodian_email_; - - ScopedSessionObserver scoped_session_observer_{this}; - - DISALLOW_COPY_AND_ASSIGN(SupervisedNotificationController); -}; - -} // namespace ash - -#endif // ASH_SYSTEM_SUPERVISED_SUPERVISED_NOTIFICATION_CONTROLLER_H_
diff --git a/ash/system/supervised/supervised_notification_controller_unittest.cc b/ash/system/supervised/supervised_notification_controller_unittest.cc deleted file mode 100644 index c6bb3897..0000000 --- a/ash/system/supervised/supervised_notification_controller_unittest.cc +++ /dev/null
@@ -1,95 +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. - -#include "ash/system/supervised/supervised_notification_controller.h" - -#include "ash/session/session_controller_impl.h" -#include "ash/session/test_session_controller_client.h" -#include "ash/shell.h" -#include "ash/test/ash_test_base.h" -#include "base/strings/utf_string_conversions.h" -#include "ui/message_center/message_center.h" -#include "ui/message_center/notification_list.h" -#include "ui/message_center/public/cpp/notification.h" -#include "ui/message_center/public/cpp/notification_types.h" - -using base::UTF8ToUTF16; -using message_center::NotificationList; - -namespace ash { - -// Tests handle creating their own sessions. -class SupervisedNotificationControllerTest : public NoSessionAshTestBase { - public: - SupervisedNotificationControllerTest() = default; - ~SupervisedNotificationControllerTest() override = default; - - protected: - message_center::Notification* GetPopup(); - - private: - DISALLOW_COPY_AND_ASSIGN(SupervisedNotificationControllerTest); -}; - -message_center::Notification* SupervisedNotificationControllerTest::GetPopup() { - NotificationList::PopupNotifications popups = - message_center::MessageCenter::Get()->GetPopupNotifications(); - for (NotificationList::PopupNotifications::const_iterator iter = - popups.begin(); - iter != popups.end(); ++iter) { - if ((*iter)->id() == SupervisedNotificationController::kNotificationId) - return *iter; - } - return NULL; -} - -// Verifies that when a supervised user logs in that a warning notification is -// shown and ash does not crash. -TEST_F(SupervisedNotificationControllerTest, SupervisedUserHasNotification) { - SessionControllerImpl* session = Shell::Get()->session_controller(); - ASSERT_EQ(LoginStatus::NOT_LOGGED_IN, session->login_status()); - ASSERT_FALSE(session->IsActiveUserSessionStarted()); - - // Simulate a supervised user logging in. - TestSessionControllerClient* client = GetSessionControllerClient(); - client->Reset(); - client->AddUserSession("child@test.com", user_manager::USER_TYPE_SUPERVISED); - client->SetSessionState(session_manager::SessionState::ACTIVE); - - // No notification because custodian email not available yet. - message_center::Notification* notification = GetPopup(); - EXPECT_FALSE(notification); - - const std::string custodian_email = "parent1@test.com"; - const std::string custodian_email2 = "parent2@test.com"; - - // Update the user session with the custodian data (which happens after the - // profile loads). - UserSession user_session = *session->GetUserSession(0); - user_session.custodian_email = custodian_email; - session->UpdateUserSession(std::move(user_session)); - - // Notification is shown. - notification = GetPopup(); - ASSERT_TRUE(notification); - EXPECT_EQ(static_cast<int>(message_center::SYSTEM_PRIORITY), - notification->rich_notification_data().priority); - EXPECT_NE(base::string16::npos, - notification->message().find(UTF8ToUTF16(custodian_email))); - - // Update the user session with new custodian data. - user_session = *session->GetUserSession(0); - user_session.custodian_email = custodian_email2; - session->UpdateUserSession(std::move(user_session)); - - // Notification is shown with updated message. - notification = GetPopup(); - ASSERT_TRUE(notification); - EXPECT_EQ(base::string16::npos, - notification->message().find(UTF8ToUTF16(custodian_email))); - EXPECT_NE(base::string16::npos, - notification->message().find(UTF8ToUTF16(custodian_email2))); -} - -} // namespace ash
diff --git a/ash/system/system_notification_controller.cc b/ash/system/system_notification_controller.cc index fdad6dc7..ce8dc644 100644 --- a/ash/system/system_notification_controller.cc +++ b/ash/system/system_notification_controller.cc
@@ -12,7 +12,6 @@ #include "ash/system/power/power_notification_controller.h" #include "ash/system/screen_security/screen_security_notification_controller.h" #include "ash/system/session/session_limit_notification_controller.h" -#include "ash/system/supervised/supervised_notification_controller.h" #include "ash/system/tracing_notification_controller.h" #include "ash/system/update/update_notification_controller.h" #include "ui/message_center/message_center.h" @@ -30,7 +29,6 @@ screen_security_( std::make_unique<ScreenSecurityNotificationController>()), session_limit_(std::make_unique<SessionLimitNotificationController>()), - supervised_(std::make_unique<SupervisedNotificationController>()), tracing_(std::make_unique<TracingNotificationController>()), update_(std::make_unique<UpdateNotificationController>()), wifi_toggle_(std::make_unique<WifiToggleNotificationController>()) {}
diff --git a/ash/system/system_notification_controller.h b/ash/system/system_notification_controller.h index cb36528f..0c087b3 100644 --- a/ash/system/system_notification_controller.h +++ b/ash/system/system_notification_controller.h
@@ -19,7 +19,6 @@ class PowerNotificationController; class ScreenSecurityNotificationController; class SessionLimitNotificationController; -class SupervisedNotificationController; class TracingNotificationController; class UpdateNotificationController; class WifiToggleNotificationController; @@ -41,7 +40,6 @@ const std::unique_ptr<PowerNotificationController> power_; const std::unique_ptr<ScreenSecurityNotificationController> screen_security_; const std::unique_ptr<SessionLimitNotificationController> session_limit_; - const std::unique_ptr<SupervisedNotificationController> supervised_; const std::unique_ptr<TracingNotificationController> tracing_; const std::unique_ptr<UpdateNotificationController> update_; const std::unique_ptr<WifiToggleNotificationController> wifi_toggle_;
diff --git a/ash/system/unified/unified_managed_device_view.cc b/ash/system/unified/unified_managed_device_view.cc index 7d2602d8..6751a00 100644 --- a/ash/system/unified/unified_managed_device_view.cc +++ b/ash/system/unified/unified_managed_device_view.cc
@@ -106,7 +106,7 @@ label_->SetText(managed_string); SetAccessibleName(managed_string); SetVisible(true); - } else if (session->IsUserSupervised()) { + } else if (session->IsUserChildOrDeprecatedSupervised()) { // Show supervised user UI (locally supervised or Family Link). icon_->SetImage(gfx::CreateVectorIcon(GetSupervisedUserIcon(), icon_color)); label_->SetText(GetSupervisedUserMessage());
diff --git a/ash/system/unified/unified_managed_device_view_unittest.cc b/ash/system/unified/unified_managed_device_view_unittest.cc index 61c09a8..d6e3e48 100644 --- a/ash/system/unified/unified_managed_device_view_unittest.cc +++ b/ash/system/unified/unified_managed_device_view_unittest.cc
@@ -74,7 +74,7 @@ using UnifiedManagedDeviceViewNoSessionTest = NoSessionAshTestBase; -TEST_F(UnifiedManagedDeviceViewNoSessionTest, SupervisedUserDevice) { +TEST_F(UnifiedManagedDeviceViewNoSessionTest, ChildUserDevice) { SessionControllerImpl* session = Shell::Get()->session_controller(); ASSERT_FALSE(session->IsActiveUserSessionStarted()); @@ -91,7 +91,7 @@ // Simulate a supervised user logging in. TestSessionControllerClient* client = GetSessionControllerClient(); client->Reset(); - client->AddUserSession("child@test.com", user_manager::USER_TYPE_SUPERVISED); + client->AddUserSession("child@test.com", user_manager::USER_TYPE_CHILD); client->SetSessionState(session_manager::SessionState::ACTIVE); UserSession user_session = *session->GetUserSession(0); user_session.custodian_email = "parent@test.com";
diff --git a/ash/system/unified/unified_system_info_view.cc b/ash/system/unified/unified_system_info_view.cc index d3fd01fb..00004f70 100644 --- a/ash/system/unified/unified_system_info_view.cc +++ b/ash/system/unified/unified_system_info_view.cc
@@ -377,8 +377,10 @@ : ManagedStateView(PressedCallback(), IDS_ASH_STATUS_TRAY_SUPERVISED_LABEL, GetSupervisedUserIcon()) { - SetVisible(Shell::Get()->session_controller()->IsUserSupervised()); - if (Shell::Get()->session_controller()->IsUserSupervised()) + bool visible = + Shell::Get()->session_controller()->IsUserChildOrDeprecatedSupervised(); + SetVisible(visible); + if (visible) SetTooltipText(GetSupervisedUserMessage()); // TODO(crbug/1026821) Add SupervisedUserView::ButtonPress() overload
diff --git a/ash/system/unified/unified_system_info_view.h b/ash/system/unified/unified_system_info_view.h index 7e6a77d..f27262e6 100644 --- a/ash/system/unified/unified_system_info_view.h +++ b/ash/system/unified/unified_system_info_view.h
@@ -33,8 +33,7 @@ FRIEND_TEST_ALL_PREFIXES(UnifiedSystemInfoViewTest, EnterpriseManagedVisible); FRIEND_TEST_ALL_PREFIXES(UnifiedSystemInfoViewTest, EnterpriseManagedVisibleForActiveDirectory); - FRIEND_TEST_ALL_PREFIXES(UnifiedSystemInfoViewNoSessionTest, - SupervisedVisible); + FRIEND_TEST_ALL_PREFIXES(UnifiedSystemInfoViewNoSessionTest, ChildVisible); // EnterpriseManagedView for unit testing. Owned by this view. Null if // kManagedDeviceUIRedesign is enabled.
diff --git a/ash/system/unified/unified_system_info_view_unittest.cc b/ash/system/unified/unified_system_info_view_unittest.cc index 13c564d..9b327a5 100644 --- a/ash/system/unified/unified_system_info_view_unittest.cc +++ b/ash/system/unified/unified_system_info_view_unittest.cc
@@ -83,7 +83,7 @@ using UnifiedSystemInfoViewNoSessionTest = NoSessionAshTestBase; -TEST_F(UnifiedSystemInfoViewNoSessionTest, SupervisedVisible) { +TEST_F(UnifiedSystemInfoViewNoSessionTest, ChildVisible) { base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitAndDisableFeature(features::kManagedDeviceUIRedesign); std::unique_ptr<UnifiedSystemTrayModel> model_ = @@ -103,7 +103,7 @@ // Simulate a supervised user logging in. TestSessionControllerClient* client = GetSessionControllerClient(); client->Reset(); - client->AddUserSession("child@test.com", user_manager::USER_TYPE_SUPERVISED); + client->AddUserSession("child@test.com", user_manager::USER_TYPE_CHILD); client->SetSessionState(session_manager::SessionState::ACTIVE); UserSession user_session = *session->GetUserSession(0); user_session.custodian_email = "parent@test.com";
diff --git a/ash/utility/layer_util.cc b/ash/utility/layer_util.cc index 45c2946..e4d30ad 100644 --- a/ash/utility/layer_util.cc +++ b/ash/utility/layer_util.cc
@@ -65,6 +65,7 @@ std::unique_ptr<ui::Layer> CreateLayerFromCopyOutputResult( std::unique_ptr<viz::CopyOutputResult> copy_result) { auto copy_layer = std::make_unique<ui::Layer>(); + copy_layer->SetBounds(gfx::Rect(copy_result->size())); CopyCopyOutputResultToLayer(std::move(copy_result), copy_layer.get()); return copy_layer; }
diff --git a/ash/wallpaper/wallpaper_controller_impl.cc b/ash/wallpaper/wallpaper_controller_impl.cc index 9b3c691..4ff6600 100644 --- a/ash/wallpaper/wallpaper_controller_impl.cc +++ b/ash/wallpaper/wallpaper_controller_impl.cc
@@ -1350,7 +1350,7 @@ // everything resets. user_manager::UserType active_user_type = active_user_session->user_info.type; return active_user_type == user_manager::USER_TYPE_REGULAR || - active_user_type == user_manager::USER_TYPE_SUPERVISED || + active_user_type == user_manager::USER_TYPE_SUPERVISED_DEPRECATED || active_user_type == user_manager::USER_TYPE_CHILD; }
diff --git a/ash/wm/desks/desks_controller.cc b/ash/wm/desks/desks_controller.cc index d9f2eb8..b33dd81 100644 --- a/ash/wm/desks/desks_controller.cc +++ b/ash/wm/desks/desks_controller.cc
@@ -496,7 +496,6 @@ if (source == DesksMoveWindowFromActiveDeskSource::kDragAndDrop) { // Since a visible on all desks window is on all desks, prevent users from // moving them manually in overview. - // TODO(chinsenj): Add a UX indication for users. return false; } else if (source == DesksMoveWindowFromActiveDeskSource::kShortcut) { window->SetProperty(aura::client::kVisibleOnAllWorkspacesKey, false); @@ -551,7 +550,7 @@ DCHECK(added); } -void DesksController::RemoveVisibleOnAllDesksWindow(aura::Window* window) { +void DesksController::MaybeRemoveVisibleOnAllDesksWindow(aura::Window* window) { visible_on_all_desks_windows_.erase(window); }
diff --git a/ash/wm/desks/desks_controller.h b/ash/wm/desks/desks_controller.h index 1ac014c8..ca36e92 100644 --- a/ash/wm/desks/desks_controller.h +++ b/ash/wm/desks/desks_controller.h
@@ -165,7 +165,7 @@ void AddVisibleOnAllDesksWindow(aura::Window* window); // Removes |window| if it is in |visible_on_all_desks_windows_|. - void RemoveVisibleOnAllDesksWindow(aura::Window* window); + void MaybeRemoveVisibleOnAllDesksWindow(aura::Window* window); // Reverts the name of the given |desk| to the default value (i.e. "Desk 1", // "Desk 2", ... etc.) according to its position in the |desks_| list, as if
diff --git a/ash/wm/desks/desks_unittests.cc b/ash/wm/desks/desks_unittests.cc index db25e162..4afef72 100644 --- a/ash/wm/desks/desks_unittests.cc +++ b/ash/wm/desks/desks_unittests.cc
@@ -4064,6 +4064,30 @@ EXPECT_TRUE(base::Contains(desk_2->windows(), window.get())); } +// Tests that when a window that is visible on all desks is destroyed it is +// removed from DesksController.visible_on_all_desks_windows_. +TEST_F(DesksBentoTest, VisibleOnAllDesksWindowDestruction) { + auto* controller = DesksController::Get(); + NewDesk(); + const Desk* desk_1 = controller->desks()[0].get(); + auto* root = Shell::GetPrimaryRootWindow(); + + auto window = CreateAppWindow(gfx::Rect(0, 0, 100, 100)); + auto* widget = views::Widget::GetWidgetForNativeWindow(window.get()); + + // Assign |window| to all desks. + widget->SetVisibleOnAllWorkspaces(true); + ASSERT_TRUE(window->GetProperty(aura::client::kVisibleOnAllWorkspacesKey)); + EXPECT_EQ(1u, controller->visible_on_all_desks_windows().size()); + EXPECT_EQ(1u, desk_1->GetDeskContainerForRoot(root)->children().size()); + + // Destroy |window|. It should be removed from + // DesksController.visible_on_all_desks_windows_. + window.reset(); + EXPECT_EQ(0u, controller->visible_on_all_desks_windows().size()); + EXPECT_EQ(0u, desk_1->GetDeskContainerForRoot(root)->children().size()); +} + // TODO(afakhry): Add more tests: // - Always on top windows are not tracked by any desk. // - Reusing containers when desks are removed and created.
diff --git a/ash/wm/overview/overview_grid.cc b/ash/wm/overview/overview_grid.cc index 573d4c2..701ed24 100644 --- a/ash/wm/overview/overview_grid.cc +++ b/ash/wm/overview/overview_grid.cc
@@ -22,6 +22,8 @@ #include "ash/rotator/screen_rotation_animator.h" #include "ash/screen_util.h" #include "ash/shell.h" +#include "ash/strings/grit/ash_strings.h" +#include "ash/system/toast/toast_manager_impl.h" #include "ash/wallpaper/wallpaper_controller_impl.h" #include "ash/wm/desks/desk_mini_view.h" #include "ash/wm/desks/desk_name_view.h" @@ -56,6 +58,7 @@ #include "base/numerics/safe_conversions.h" #include "base/strings/utf_string_conversions.h" #include "ui/aura/client/aura_constants.h" +#include "ui/base/l10n/l10n_util.h" #include "ui/compositor/layer_animation_observer.h" #include "ui/compositor/throughput_tracker.h" #include "ui/gfx/geometry/vector2d_f.h" @@ -90,6 +93,12 @@ constexpr base::TimeDelta kOcclusionUnpauseDurationForRotation = base::TimeDelta::FromMilliseconds(300); +// Toast id for the toast that is displayed when a user tries to move a window +// that is visible on all desks to another desk. +constexpr char kMoveVisibleOnAllDesksWindowToastId[] = + "ash.wm.overview.move_visible_on_all_desks_window_toast"; +constexpr int kToastDurationMs = 2500; + // Histogram names for overview enter/exit smoothness in clamshell, // tablet mode and splitview. constexpr char kOverviewEnterClamshellHistogram[] = @@ -1358,19 +1367,33 @@ OverviewItem* drag_item) { DCHECK(desks_util::ShouldDesksBarBeCreated()); + aura::Window* const dragged_window = drag_item->GetWindow(); + const bool dragged_window_is_visible_on_all_desks = + dragged_window && + dragged_window->GetProperty(aura::client::kVisibleOnAllWorkspacesKey); // End the drag for the DesksBarView. if (!IntersectsWithDesksBar(screen_location, - /*update_desks_bar_drag_details=*/true, + /*update_desks_bar_drag_details=*/ + !dragged_window_is_visible_on_all_desks, /*for_drop=*/true)) { return false; } + if (dragged_window_is_visible_on_all_desks) { + // Show toast since items that are visible on all desks should not be able + // to be unassigned during overview. + Shell::Get()->toast_manager()->Show(ToastData( + kMoveVisibleOnAllDesksWindowToastId, + l10n_util::GetStringUTF16(IDS_ASH_OVERVIEW_VISIBLE_ON_ALL_DESKS_TOAST), + kToastDurationMs, base::nullopt)); + return false; + } + auto* desks_controller = DesksController::Get(); for (auto* mini_view : desks_bar_view_->mini_views()) { if (!mini_view->IsPointOnMiniView(screen_location)) continue; - aura::Window* const dragged_window = drag_item->GetWindow(); Desk* const target_desk = mini_view->desk(); if (target_desk == desks_controller->active_desk()) return false;
diff --git a/ash/wm/overview/overview_window_drag_controller.cc b/ash/wm/overview/overview_window_drag_controller.cc index e942991..818961a5 100644 --- a/ash/wm/overview/overview_window_drag_controller.cc +++ b/ash/wm/overview/overview_window_drag_controller.cc
@@ -31,6 +31,7 @@ #include "base/metrics/histogram_functions.h" #include "base/numerics/ranges.h" #include "base/numerics/safe_conversions.h" +#include "ui/aura/client/aura_constants.h" #include "ui/aura/window.h" #include "ui/aura/window_observer.h" #include "ui/display/display.h" @@ -79,6 +80,13 @@ item->overview_grid()->IsDesksBarViewActive(); } +// Returns whether |item|'s window is visible on all desks. +bool DraggedItemIsVisibleOnAllDesks(OverviewItem* item) { + aura::Window* const dragged_window = item->GetWindow(); + return dragged_window && + dragged_window->GetProperty(aura::client::kVisibleOnAllWorkspacesKey); +} + // Returns the scaled-down size of the dragged item that should be used when // it's dragged over the DesksBarView that belongs to |overview_grid|. // |window_original_size| is the size of the item's window before it was scaled @@ -520,10 +528,12 @@ if (desks_bar_data.shrink_bounds.Contains(location_in_screen)) { // Update the mini views borders by checking if |location_in_screen| - // intersects. + // intersects. Only update the borders if the dragged item is not visible + // on all desks. overview_grid->IntersectsWithDesksBar( gfx::ToRoundedPoint(location_in_screen), - /*update_desks_bar_drag_details=*/true, /*for_drop=*/false); + /*update_desks_bar_drag_details=*/ + !DraggedItemIsVisibleOnAllDesks(item_), /*for_drop=*/false); float value = 0.f; if (centerpoint.y() < desks_bar_data.desks_bar_bounds.y() ||
diff --git a/ash/wm/workspace/workspace_layout_manager.cc b/ash/wm/workspace/workspace_layout_manager.cc index a9725b6..3d1b6041 100644 --- a/ash/wm/workspace/workspace_layout_manager.cc +++ b/ash/wm/workspace/workspace_layout_manager.cc
@@ -329,7 +329,7 @@ if (window->GetProperty(aura::client::kVisibleOnAllWorkspacesKey)) desks_controller->AddVisibleOnAllDesksWindow(window); else - desks_controller->RemoveVisibleOnAllDesksWindow(window); + desks_controller->MaybeRemoveVisibleOnAllDesksWindow(window); } } @@ -348,6 +348,7 @@ settings_bubble_container_ = nullptr; if (accessibility_bubble_container_ == window) accessibility_bubble_container_ = nullptr; + Shell::Get()->desks_controller()->MaybeRemoveVisibleOnAllDesksWindow(window); } void WorkspaceLayoutManager::OnWindowBoundsChanged(
diff --git a/base/allocator/partition_allocator/partition_ref_count.h b/base/allocator/partition_allocator/partition_ref_count.h index 310a9d6..ef7ad7e 100644 --- a/base/allocator/partition_allocator/partition_ref_count.h +++ b/base/allocator/partition_allocator/partition_ref_count.h
@@ -85,6 +85,16 @@ } private: +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunused-private-field" +#endif + void* padding_; // TODO(crbug.com/1164636): This "workaround" is meant to + // reduce the number of freelist corruption crashes we see in + // experiments. Remove once root cause has been found. +#if defined(__clang__) +#pragma clang diagnostic pop +#endif std::atomic<int32_t> count_{1}; };
diff --git a/base/android/java/src/org/chromium/base/BundleUtils.java b/base/android/java/src/org/chromium/base/BundleUtils.java index 00fc6c5..c41b70b 100644 --- a/base/android/java/src/org/chromium/base/BundleUtils.java +++ b/base/android/java/src/org/chromium/base/BundleUtils.java
@@ -5,17 +5,22 @@ package org.chromium.base; import android.content.Context; +import android.content.ContextWrapper; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.os.Build; import androidx.annotation.Nullable; +import androidx.collection.SimpleArrayMap; import dalvik.system.BaseDexClassLoader; +import dalvik.system.PathClassLoader; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.compat.ApiHelperForO; +import org.chromium.base.metrics.RecordHistogram; +import java.lang.reflect.Field; import java.util.Arrays; /** @@ -38,6 +43,11 @@ public final class BundleUtils { private static Boolean sIsBundle; + // This cache is needed to support the workaround for b/172602571, see + // createIsolatedSplitContext() for more info. + private static final SimpleArrayMap<String, ClassLoader> sCachedClassLoaders = + new SimpleArrayMap<>(); + /** * {@link BundleUtils#isBundle()} is not called directly by native because * {@link CalledByNative} prevents inlining, causing the bundle support lib to not be @@ -98,12 +108,56 @@ } try { - return ApiHelperForO.createContextForSplit(base, splitName); + Context context = ApiHelperForO.createContextForSplit(base, splitName); + ClassLoader parent = context.getClassLoader().getParent(); + Context appContext = ContextUtils.getApplicationContext(); + // If the ClassLoader from the newly created context does not equal either the + // BundleUtils ClassLoader (the base module ClassLoader) or the app context ClassLoader + // (the chrome module ClassLoader) there must be something messed up in the ClassLoader + // cache, see b/172602571. This should be solved for the chrome ClassLoader by + // SplitCompatAppComponentFactory, but modules which depend on the chrome module need + // special handling here to make sure they have the correct parent. + boolean shouldReplaceClassLoader = isolatedSplitsEnabled() + && !parent.equals(BundleUtils.class.getClassLoader()) && appContext != null + && !parent.equals(appContext.getClassLoader()); + if (shouldReplaceClassLoader) { + if (!sCachedClassLoaders.containsKey(splitName)) { + String[] splitNames = ApiHelperForO.getSplitNames(context.getApplicationInfo()); + int idx = Arrays.binarySearch(splitNames, splitName); + assert idx >= 0; + // The librarySearchPath argument to PathClassLoader is not needed here because + // the framework doesn't pass it either, see b/171269960. + sCachedClassLoaders.put(splitName, + new PathClassLoader(context.getApplicationInfo().splitSourceDirs[idx], + appContext.getClassLoader())); + } + replaceClassLoader(context, sCachedClassLoaders.get(splitName)); + } + RecordHistogram.recordBooleanHistogram( + "Android.IsolatedSplits.ClassLoaderReplaced." + splitName, + shouldReplaceClassLoader); + return context; } catch (PackageManager.NameNotFoundException e) { throw new RuntimeException(e); } } + /** Replaces the ClassLoader of the passed in Context. */ + public static void replaceClassLoader(Context baseContext, ClassLoader classLoader) { + while (baseContext instanceof ContextWrapper) { + baseContext = ((ContextWrapper) baseContext).getBaseContext(); + } + + try { + // baseContext should now be an instance of ContextImpl. + Field classLoaderField = baseContext.getClass().getDeclaredField("mClassLoader"); + classLoaderField.setAccessible(true); + classLoaderField.set(baseContext, classLoader); + } catch (ReflectiveOperationException e) { + throw new RuntimeException("Error setting ClassLoader.", e); + } + } + /* Returns absolute path to a native library in a feature module. */ @CalledByNative @Nullable
diff --git a/base/metrics/field_trial_param_associator.cc b/base/metrics/field_trial_param_associator.cc index 3dbc5516..ab3bcf4 100644 --- a/base/metrics/field_trial_param_associator.cc +++ b/base/metrics/field_trial_param_associator.cc
@@ -60,10 +60,11 @@ AutoLock scoped_lock(lock_); const FieldTrialRefKey key(trial_name, group_name); - if (!Contains(field_trial_params_, key)) + auto it = field_trial_params_.find(key); + if (it == field_trial_params_.end()) return false; - *params = field_trial_params_[key]; + *params = it->second; return true; }
diff --git a/base/metrics/field_trial_params.cc b/base/metrics/field_trial_params.cc index 608d5d0..71b7248 100644 --- a/base/metrics/field_trial_params.cc +++ b/base/metrics/field_trial_params.cc
@@ -114,14 +114,13 @@ std::string GetFieldTrialParamValueByFeature(const Feature& feature, const std::string& param_name) { - if (!FeatureList::IsEnabled(feature)) - return std::string(); - - FieldTrial* trial = FeatureList::GetFieldTrial(feature); - if (!trial) - return std::string(); - - return GetFieldTrialParamValue(trial->trial_name(), param_name); + FieldTrialParams params; + if (GetFieldTrialParamsByFeature(feature, ¶ms)) { + auto it = params.find(param_name); + if (it != params.end()) + return it->second; + } + return std::string(); } int GetFieldTrialParamByFeatureAsInt(const Feature& feature,
diff --git a/base/process/process_metrics_linux.cc b/base/process/process_metrics_linux.cc index ff933a7..53a0cf3 100644 --- a/base/process/process_metrics_linux.cc +++ b/base/process/process_metrics_linux.cc
@@ -658,10 +658,9 @@ } bool GetSystemMemoryInfo(SystemMemoryInfoKB* meminfo) { - // Synchronously reading files in /proc is safe. - ThreadRestrictions::ScopedAllowIO allow_io; - // Used memory is: total - free - buffers - caches + // ReadFileToStringNonBlocking doesn't require ScopedAllowIO, and reading + // /proc/meminfo is fast. See crbug.com/1160988 for details. FilePath meminfo_file("/proc/meminfo"); std::string meminfo_data; if (!ReadFileToStringNonBlocking(meminfo_file, &meminfo_data)) {
diff --git a/base/profiler/module_cache.cc b/base/profiler/module_cache.cc index b36ba46..bfe878a 100644 --- a/base/profiler/module_cache.cc +++ b/base/profiler/module_cache.cc
@@ -31,15 +31,21 @@ } // namespace ModuleCache::ModuleCache() = default; -ModuleCache::~ModuleCache() = default; + +ModuleCache::~ModuleCache() { + DCHECK_EQ(auxiliary_module_provider_, nullptr); +} const ModuleCache::Module* ModuleCache::GetModuleForAddress(uintptr_t address) { if (const ModuleCache::Module* module = GetExistingModuleForAddress(address)) return module; std::unique_ptr<const Module> new_module = CreateModuleForAddress(address); + if (!new_module && auxiliary_module_provider_) + new_module = auxiliary_module_provider_->TryCreateModuleForAddress(address); if (!new_module) return nullptr; + const auto result = native_modules_.insert(std::move(new_module)); // TODO(https://crbug.com/1131769): Reintroduce DCHECK(result.second) after // fixing the issue that is causing it to fail. @@ -126,6 +132,18 @@ return nullptr; } +void ModuleCache::RegisterAuxiliaryModuleProvider( + AuxiliaryModuleProvider* auxiliary_module_provider) { + DCHECK(!auxiliary_module_provider_); + auxiliary_module_provider_ = auxiliary_module_provider; +} + +void ModuleCache::UnregisterAuxiliaryModuleProvider( + AuxiliaryModuleProvider* auxiliary_module_provider) { + DCHECK_EQ(auxiliary_module_provider_, auxiliary_module_provider); + auxiliary_module_provider_ = nullptr; +} + bool ModuleCache::ModuleAndAddressCompare::operator()( const std::unique_ptr<const Module>& m1, const std::unique_ptr<const Module>& m2) const {
diff --git a/base/profiler/module_cache.h b/base/profiler/module_cache.h index fde60e7f..71f7d78 100644 --- a/base/profiler/module_cache.h +++ b/base/profiler/module_cache.h
@@ -66,6 +66,21 @@ virtual bool IsNative() const = 0; }; + // Interface for lazily creating a native module for a given |address|. The + // provider is registered with RegisterAuxiliaryModuleProvider(). + class AuxiliaryModuleProvider { + public: + AuxiliaryModuleProvider() = default; + AuxiliaryModuleProvider(const AuxiliaryModuleProvider&) = delete; + AuxiliaryModuleProvider& operator=(const AuxiliaryModuleProvider&) = delete; + + virtual std::unique_ptr<const Module> TryCreateModuleForAddress( + uintptr_t address) = 0; + + protected: + ~AuxiliaryModuleProvider() = default; + }; + ModuleCache(); ~ModuleCache(); @@ -103,6 +118,19 @@ // ModuleCache. void AddCustomNativeModule(std::unique_ptr<const Module> module); + // Registers a custom module provider for lazily creating native modules. At + // most one provider can be registered at any time, and the provider must be + // unregistered before being destroyed. This is intended to support native + // modules that require custom handling. In general, native modules will be + // found and added automatically when invoking GetModuleForAddress(). If no + // module is found, this provider will be used as fallback. + void RegisterAuxiliaryModuleProvider( + AuxiliaryModuleProvider* auxiliary_module_provider); + + // Unregisters the custom module provider. + void UnregisterAuxiliaryModuleProvider( + AuxiliaryModuleProvider* auxiliary_module_provider); + // Gets the module containing |address| if one already exists, or nullptr // otherwise. The returned module remains owned by and has the same lifetime // as the ModuleCache object. @@ -156,6 +184,9 @@ // because it can contain multiple modules that were loaded (then subsequently // unloaded) at the same base address. std::vector<std::unique_ptr<const Module>> inactive_non_native_modules_; + + // Auxiliary module provider, for lazily creating native modules. + AuxiliaryModuleProvider* auxiliary_module_provider_ = nullptr; }; } // namespace base
diff --git a/base/profiler/module_cache_unittest.cc b/base/profiler/module_cache_unittest.cc index 57986440..cefae68c 100644 --- a/base/profiler/module_cache_unittest.cc +++ b/base/profiler/module_cache_unittest.cc
@@ -411,5 +411,68 @@ } #endif +// Module provider that always return a fake module of size 1 for a given +// |address|. +class MockModuleProvider : public ModuleCache::AuxiliaryModuleProvider { + public: + explicit MockModuleProvider(size_t module_size = 1) + : module_size_(module_size) {} + + std::unique_ptr<const ModuleCache::Module> TryCreateModuleForAddress( + uintptr_t address) override { + return std::make_unique<FakeModule>(address, module_size_); + } + + private: + size_t module_size_; +}; + +// Check that auxiliary provider can inject new modules when registered. +TEST(ModuleCacheTest, RegisterAuxiliaryModuleProvider) { + ModuleCache cache; + EXPECT_EQ(nullptr, cache.GetModuleForAddress(1)); + + MockModuleProvider auxiliary_provider; + cache.RegisterAuxiliaryModuleProvider(&auxiliary_provider); + auto* module = cache.GetModuleForAddress(1); + EXPECT_NE(nullptr, module); + EXPECT_EQ(1U, module->GetBaseAddress()); + cache.UnregisterAuxiliaryModuleProvider(&auxiliary_provider); + + // Even when unregistered, the module remains in the cache. + EXPECT_EQ(module, cache.GetModuleForAddress(1)); +} + +// Check that ModuleCache's own module creator is used preferentially over +// auxiliary provider if possible. +MAYBE_TEST(ModuleCacheTest, NativeModuleOverAuxiliaryModuleProvider) { + ModuleCache cache; + + MockModuleProvider auxiliary_provider(/*module_size=*/100); + cache.RegisterAuxiliaryModuleProvider(&auxiliary_provider); + + const ModuleCache::Module* module = + cache.GetModuleForAddress(reinterpret_cast<uintptr_t>(&AFunctionForTest)); + ASSERT_NE(nullptr, module); + + // The module should be a native module, which will have size greater than 100 + // bytes. + EXPECT_NE(100u, module->GetSize()); + cache.UnregisterAuxiliaryModuleProvider(&auxiliary_provider); +} + +// Check that auxiliary provider is no longer used after being unregistered. +TEST(ModuleCacheTest, UnregisterAuxiliaryModuleProvider) { + ModuleCache cache; + + EXPECT_EQ(nullptr, cache.GetModuleForAddress(1)); + + MockModuleProvider auxiliary_provider; + cache.RegisterAuxiliaryModuleProvider(&auxiliary_provider); + cache.UnregisterAuxiliaryModuleProvider(&auxiliary_provider); + + EXPECT_EQ(nullptr, cache.GetModuleForAddress(1)); +} + } // namespace } // namespace base
diff --git a/base/profiler/native_unwinder_android.cc b/base/profiler/native_unwinder_android.cc index efba835..c5f12af 100644 --- a/base/profiler/native_unwinder_android.cc +++ b/base/profiler/native_unwinder_android.cc
@@ -127,10 +127,14 @@ process_memory_(process_memory), exclude_module_with_base_address_(exclude_module_with_base_address) {} -NativeUnwinderAndroid::~NativeUnwinderAndroid() = default; +NativeUnwinderAndroid::~NativeUnwinderAndroid() { + if (module_cache_) + module_cache_->UnregisterAuxiliaryModuleProvider(this); +} -void NativeUnwinderAndroid::AddInitialModules(ModuleCache* module_cache) { - AddInitialModulesFromMaps(*memory_regions_map_, module_cache); +void NativeUnwinderAndroid::InitializeModules(ModuleCache* module_cache) { + module_cache_ = module_cache; + module_cache_->RegisterAuxiliaryModuleProvider(this); } bool NativeUnwinderAndroid::CanUnwindFrom(const Frame& current_frame) const { @@ -215,34 +219,14 @@ return UnwindResult::UNRECOGNIZED_FRAME; } -// static -void NativeUnwinderAndroid::AddInitialModulesFromMaps( - const unwindstack::Maps& memory_regions_map, - ModuleCache* module_cache) { - // The effect of this loop is to create modules for the executable regions in - // the memory map. Regions composing a mapped ELF file are handled specially - // however: for just one module extending from the ELF base address to the - // *last* executable region backed by the file is implicitly created by - // ModuleCache. This avoids duplicate module instances covering the same - // in-memory module in the case that a module has multiple mmapped executable - // regions. - for (const std::unique_ptr<unwindstack::MapInfo>& region : - memory_regions_map) { - if (!(region->flags & PROT_EXEC)) - continue; - - // Use the standard ModuleCache POSIX module representation for ELF files. - // This call returns the containing ELF module for the region, creating it - // if it doesn't exist. - if (module_cache->GetModuleForAddress( - static_cast<uintptr_t>(region->start))) { - continue; - } - - // Non-ELF modules are represented with NonElfModule. - module_cache->AddCustomNativeModule( - std::make_unique<NonElfModule>(region.get())); +std::unique_ptr<const ModuleCache::Module> +NativeUnwinderAndroid::TryCreateModuleForAddress(uintptr_t address) { + unwindstack::MapInfo* map_info = memory_regions_map_->Find(address); + if (map_info == nullptr || !(map_info->flags & PROT_EXEC) || + map_info->flags & unwindstack::MAPS_FLAGS_DEVICE_MAP) { + return nullptr; } + return std::make_unique<NonElfModule>(map_info); } void NativeUnwinderAndroid::EmitDexFrame(uintptr_t dex_pc,
diff --git a/base/profiler/native_unwinder_android.h b/base/profiler/native_unwinder_android.h index 62774e6..30aa101 100644 --- a/base/profiler/native_unwinder_android.h +++ b/base/profiler/native_unwinder_android.h
@@ -27,7 +27,8 @@ }; // Native unwinder implementation for Android, using libunwindstack. -class NativeUnwinderAndroid : public Unwinder { +class NativeUnwinderAndroid : public Unwinder, + public ModuleCache::AuxiliaryModuleProvider { public: // Creates maps object from /proc/self/maps for use by NativeUnwinderAndroid. // Since this is an expensive call, the maps object should be re-used across @@ -35,8 +36,9 @@ static std::unique_ptr<unwindstack::Maps> CreateMaps(); static std::unique_ptr<unwindstack::Memory> CreateProcessMemory(); - // |exclude_module_with_base_address| is used to exclude a specific module - // and let another unwinder take control. TryUnwind() will exit with + // |memory_regions_map| and |process_memory| must outlive this unwinder. + // |exclude_module_with_base_address| is used to exclude a specific module and + // let another unwinder take control. TryUnwind() will exit with // UNRECOGNIZED_FRAME and CanUnwindFrom() will return false when a frame is // encountered in that module. NativeUnwinderAndroid(unwindstack::Maps* memory_regions_map, @@ -48,24 +50,25 @@ NativeUnwinderAndroid& operator=(const NativeUnwinderAndroid&) = delete; // Unwinder - void AddInitialModules(ModuleCache* module_cache) override; + void InitializeModules(ModuleCache* module_cache) override; bool CanUnwindFrom(const Frame& current_frame) const override; UnwindResult TryUnwind(RegisterContext* thread_context, uintptr_t stack_top, ModuleCache* module_cache, std::vector<Frame>* stack) const override; - // Adds modules found from executable loaded memory regions to |module_cache|. - // Public for test access. - static void AddInitialModulesFromMaps( - const unwindstack::Maps& memory_regions_map, - ModuleCache* module_cache); + // ModuleCache::AuxiliaryModuleProvider + std::unique_ptr<const ModuleCache::Module> TryCreateModuleForAddress( + uintptr_t address) override; private: void EmitDexFrame(uintptr_t dex_pc, ModuleCache* module_cache, std::vector<Frame>* stack) const; + // InitializeModules() registers self as an AuxiliaryModuleProvider. A pointer + // to the ModuleCache is saved to unregister self in destructor. + ModuleCache* module_cache_ = nullptr; unwindstack::Maps* const memory_regions_map_; unwindstack::Memory* const process_memory_; const uintptr_t exclude_module_with_base_address_;
diff --git a/base/profiler/native_unwinder_android_unittest.cc b/base/profiler/native_unwinder_android_unittest.cc index 5972c77..b3e6db23 100644 --- a/base/profiler/native_unwinder_android_unittest.cc +++ b/base/profiler/native_unwinder_android_unittest.cc
@@ -34,11 +34,6 @@ namespace { -bool CompareModulesByBaseAddress(const ModuleCache::Module* a, - const ModuleCache::Module* b) { - return a->GetBaseAddress() < b->GetBaseAddress(); -} - // Add a MapInfo with the provided values to |maps|. void AddMapInfo(uint64_t start, uint64_t end, @@ -114,11 +109,12 @@ std::unique_ptr<unwindstack::Maps> maps = NativeUnwinderAndroid::CreateMaps(); std::unique_ptr<unwindstack::Memory> memory = NativeUnwinderAndroid::CreateProcessMemory(); + + ModuleCache module_cache; auto unwinder = std::make_unique<NativeUnwinderAndroid>(maps.get(), memory.get(), 0); - ModuleCache module_cache; - unwinder->AddInitialModules(&module_cache); + unwinder->InitializeModules(&module_cache); std::vector<Frame> sample = CaptureScenario(&scenario, &module_cache, BindLambdaForTesting([&](RegisterContext* thread_context, @@ -154,11 +150,12 @@ std::unique_ptr<unwindstack::Maps> maps = NativeUnwinderAndroid::CreateMaps(); std::unique_ptr<unwindstack::Memory> memory = NativeUnwinderAndroid::CreateProcessMemory(); + + ModuleCache module_cache; auto unwinder = std::make_unique<NativeUnwinderAndroid>(maps.get(), memory.get(), 0); - ModuleCache module_cache; - unwinder->AddInitialModules(&module_cache); + unwinder->InitializeModules(&module_cache); std::vector<Frame> sample = CaptureScenario(&scenario, &module_cache, BindLambdaForTesting([&](RegisterContext* thread_context, @@ -196,11 +193,12 @@ std::unique_ptr<unwindstack::Maps> maps = NativeUnwinderAndroid::CreateMaps(); std::unique_ptr<unwindstack::Memory> memory = NativeUnwinderAndroid::CreateProcessMemory(); + + ModuleCache module_cache; auto unwinder = std::make_unique<NativeUnwinderAndroid>(maps.get(), memory.get(), 0); - ModuleCache module_cache; - unwinder->AddInitialModules(&module_cache); + unwinder->InitializeModules(&module_cache); std::vector<Frame> sample = CaptureScenario(&scenario, &module_cache, BindLambdaForTesting([&](RegisterContext* thread_context, @@ -228,12 +226,13 @@ std::unique_ptr<unwindstack::Memory> memory = NativeUnwinderAndroid::CreateProcessMemory(); ModuleCache module_cache; - NativeUnwinderAndroid::AddInitialModulesFromMaps(*maps, &module_cache); - + unwindstack::MapInfo* other_library_map = + maps->Find(GetAddressInOtherLibrary(other_library)); + ASSERT_NE(nullptr, other_library_map); auto unwinder = std::make_unique<NativeUnwinderAndroid>( - maps.get(), memory.get(), - module_cache.GetModuleForAddress(GetAddressInOtherLibrary(other_library)) - ->GetBaseAddress()); + maps.get(), memory.get(), other_library_map->start); + unwinder->InitializeModules(&module_cache); + std::vector<Frame> sample = CaptureScenario(&scenario, &module_cache, BindLambdaForTesting([&](RegisterContext* thread_context, @@ -266,34 +265,44 @@ std::unique_ptr<unwindstack::Maps> maps = NativeUnwinderAndroid::CreateMaps(); std::unique_ptr<unwindstack::Memory> memory = NativeUnwinderAndroid::CreateProcessMemory(); - ModuleCache module_cache; - NativeUnwinderAndroid::AddInitialModulesFromMaps(*maps, &module_cache); - // Several unwinders are used to unwind different portion of the stack. This - // tests that NativeUnwinderAndroid can pick up from a state in the middle of - // the stack. This emulates having NativeUnwinderAndroid work with other - // unwinders, but doesn't reproduce what happens in production. + // Several unwinders are used to unwind different portion of the stack. Since + // only 1 unwinder can be registered as a module provider, each unwinder uses + // a distinct ModuleCache. This tests that NativeUnwinderAndroid can pick up + // from a state in the middle of the stack. This emulates having + // NativeUnwinderAndroid work with other unwinders, but doesn't reproduce what + // happens in production. + ModuleCache module_cache_for_all; auto unwinder_for_all = std::make_unique<NativeUnwinderAndroid>(maps.get(), memory.get(), 0); + unwinder_for_all->InitializeModules(&module_cache_for_all); + + ModuleCache module_cache_for_native; auto unwinder_for_native = std::make_unique<NativeUnwinderAndroid>( maps.get(), memory.get(), reinterpret_cast<uintptr_t>(&__executable_start)); + unwinder_for_native->InitializeModules(&module_cache_for_native); + + ModuleCache module_cache_for_chrome; + unwindstack::MapInfo* other_library_map = + maps->Find(GetAddressInOtherLibrary(other_library)); + ASSERT_NE(nullptr, other_library_map); auto unwinder_for_chrome = std::make_unique<NativeUnwinderAndroid>( - maps.get(), memory.get(), - module_cache.GetModuleForAddress(GetAddressInOtherLibrary(other_library)) - ->GetBaseAddress()); + maps.get(), memory.get(), other_library_map->start); + unwinder_for_chrome->InitializeModules(&module_cache_for_chrome); std::vector<Frame> sample = CaptureScenario( - &scenario, &module_cache, + &scenario, &module_cache_for_native, BindLambdaForTesting([&](RegisterContext* thread_context, uintptr_t stack_top, std::vector<Frame>* sample) { // |unwinder_for_native| unwinds through native frames, but stops at // chrome frames. It might not contain SampleAddressRange. ASSERT_TRUE(unwinder_for_native->CanUnwindFrom(sample->back())); - EXPECT_EQ(UnwindResult::UNRECOGNIZED_FRAME, - unwinder_for_native->TryUnwind(thread_context, stack_top, - &module_cache, sample)); + EXPECT_EQ( + UnwindResult::UNRECOGNIZED_FRAME, + unwinder_for_native->TryUnwind(thread_context, stack_top, + &module_cache_for_native, sample)); EXPECT_FALSE(unwinder_for_native->CanUnwindFrom(sample->back())); ExpectStackDoesNotContain(*sample, @@ -304,9 +313,10 @@ // |unwinder_for_chrome| unwinds through Chrome frames, but stops at // |other_library|. It won't contain SetupFunctionAddressRange. ASSERT_TRUE(unwinder_for_chrome->CanUnwindFrom(sample->back())); - EXPECT_EQ(UnwindResult::UNRECOGNIZED_FRAME, - unwinder_for_chrome->TryUnwind(thread_context, stack_top, - &module_cache, sample)); + EXPECT_EQ( + UnwindResult::UNRECOGNIZED_FRAME, + unwinder_for_chrome->TryUnwind(thread_context, stack_top, + &module_cache_for_chrome, sample)); EXPECT_FALSE(unwinder_for_chrome->CanUnwindFrom(sample->back())); EXPECT_LT(prior_stack_size, sample->size()); ExpectStackContains(*sample, {scenario.GetWaitForSampleAddressRange()}); @@ -318,7 +328,7 @@ ASSERT_TRUE(unwinder_for_all->CanUnwindFrom(sample->back())); EXPECT_EQ(UnwindResult::COMPLETED, unwinder_for_all->TryUnwind(thread_context, stack_top, - &module_cache, sample)); + &module_cache_for_all, sample)); })); // The stack should contain a full unwind. @@ -370,7 +380,7 @@ std::make_unique<NativeUnwinderAndroid>(maps.get(), memory.get(), 0); ModuleCache module_cache; - unwinder->AddInitialModules(&module_cache); + unwinder->InitializeModules(&module_cache); std::vector<Frame> sample = CaptureScenario(&scenario, &module_cache, BindLambdaForTesting([&](RegisterContext* thread_context, @@ -431,12 +441,17 @@ maps); ModuleCache module_cache; - NativeUnwinderAndroid::AddInitialModulesFromMaps(maps, &module_cache); - std::vector<const ModuleCache::Module*> modules = module_cache.GetModules(); + std::unique_ptr<unwindstack::Memory> memory = + NativeUnwinderAndroid::CreateProcessMemory(); + auto unwinder = + std::make_unique<NativeUnwinderAndroid>(&maps, memory.get(), 0); + unwinder->InitializeModules(&module_cache); - ASSERT_EQ(1u, modules.size()); - EXPECT_EQ("[foo / bar]", modules[0]->GetDebugBasename().value()); + const ModuleCache::Module* module = module_cache.GetModuleForAddress(0x1000u); + + ASSERT_TRUE(module); + EXPECT_EQ("[foo / bar]", module->GetDebugBasename().value()); } // Checks that modules are only created for executable memory regions. @@ -446,113 +461,26 @@ AddMapInfo(0x2000u, 0x3000u, 0u, PROT_READ, "[b]", {0xAB}, maps); AddMapInfo(0x3000u, 0x4000u, 0u, PROT_READ | PROT_EXEC, "[c]", {0xAC}, maps); + std::unique_ptr<unwindstack::Memory> memory = + NativeUnwinderAndroid::CreateProcessMemory(); + ModuleCache module_cache; - NativeUnwinderAndroid::AddInitialModulesFromMaps(maps, &module_cache); + auto unwinder = + std::make_unique<NativeUnwinderAndroid>(&maps, memory.get(), 0); + unwinder->InitializeModules(&module_cache); - std::vector<const ModuleCache::Module*> modules = module_cache.GetModules(); - std::sort(modules.begin(), modules.end(), CompareModulesByBaseAddress); + const ModuleCache::Module* module1 = + module_cache.GetModuleForAddress(0x1000u); + const ModuleCache::Module* module2 = + module_cache.GetModuleForAddress(0x2000u); + const ModuleCache::Module* module3 = + module_cache.GetModuleForAddress(0x3000u); - ASSERT_EQ(2u, modules.size()); - EXPECT_EQ(0x1000u, modules[0]->GetBaseAddress()); - EXPECT_EQ(0x3000u, modules[1]->GetBaseAddress()); -} - -// Checks that module address ranges don't overlap. -TEST(NativeUnwinderAndroidTest, NonOverlappingModules) { - ModuleCache module_cache; - std::unique_ptr<unwindstack::Maps> maps = NativeUnwinderAndroid::CreateMaps(); - NativeUnwinderAndroid::AddInitialModulesFromMaps(*maps, &module_cache); - - std::vector<const ModuleCache::Module*> modules = module_cache.GetModules(); - std::sort(modules.begin(), modules.end(), CompareModulesByBaseAddress); - auto loc = std::adjacent_find( - modules.begin(), modules.end(), - [](const ModuleCache::Module* m1, const ModuleCache::Module* m2) { - return m2->GetBaseAddress() < m1->GetBaseAddress() + m1->GetSize(); - }); - - const auto describe_module = [](const ModuleCache::Module* module) { - return StringPrintf( - "id \"%s\", debug basename \"%s\" at [0x%" PRIxPTR ", 0x%" PRIxPTR ")", - module->GetId().c_str(), module->GetDebugBasename().value().c_str(), - module->GetBaseAddress(), module->GetBaseAddress() + module->GetSize()); - }; - - EXPECT_EQ(modules.end(), loc) << "module overlap found between\n" - << " " << describe_module(*loc) << " and \n" - << " " << describe_module(*std::next(loc)); -} - -// ModuleCache::GetModuleForAddress() is not implemented for 64-bit arm. -#if defined(ARCH_CPU_ARM64) -#define MAYBE_ModuleState_SystemLibrary DISABLED_ModuleState_SystemLibrary -#else -#define MAYBE_ModuleState_SystemLibrary ModuleState_SystemLibrary -#endif -// Checks that the module state created by the unwinder is consistent with the -// state created by the ModuleCache. Checks the module for a system library. -TEST(NativeUnwinderAndroidTest, MAYBE_ModuleState_SystemLibrary) { - ModuleCache unwinder_module_cache; - std::unique_ptr<unwindstack::Maps> maps = NativeUnwinderAndroid::CreateMaps(); - NativeUnwinderAndroid::AddInitialModulesFromMaps(*maps, - &unwinder_module_cache); - - const uintptr_t c_library_function_address = - reinterpret_cast<uintptr_t>(&printf); - - const ModuleCache::Module* unwinder_module = - unwinder_module_cache.GetExistingModuleForAddress( - c_library_function_address); - ASSERT_NE(nullptr, unwinder_module); - - ModuleCache reference_module_cache; - const ModuleCache::Module* reference_module = - reference_module_cache.GetModuleForAddress(c_library_function_address); - ASSERT_NE(nullptr, reference_module); - - EXPECT_EQ(reference_module->GetBaseAddress(), - unwinder_module->GetBaseAddress()); - EXPECT_EQ(reference_module->GetId(), unwinder_module->GetId()); - EXPECT_EQ(reference_module->GetDebugBasename(), - unwinder_module->GetDebugBasename()); - EXPECT_EQ(unwinder_module->GetSize(), reference_module->GetSize()); -} - -// ModuleCache::GetModuleForAddress() is not implemented for 64-bit arm. -#if defined(ARCH_CPU_ARM64) -#define MAYBE_ModuleState_ChromeLibrary DISABLED_ModuleState_ChromeLibrary -#else -#define MAYBE_ModuleState_ChromeLibrary ModuleState_ChromeLibrary -#endif -// Checks that the module state created by the unwinder is consistent with the -// state created by the ModuleCache. Checks the module for a Chrome-compiled -// library. -TEST(NativeUnwinderAndroidTest, MAYBE_ModuleState_ChromeLibrary) { - ModuleCache unwinder_module_cache; - std::unique_ptr<unwindstack::Maps> maps = NativeUnwinderAndroid::CreateMaps(); - NativeUnwinderAndroid::AddInitialModulesFromMaps(*maps, - &unwinder_module_cache); - - const uintptr_t chrome_function_address = - reinterpret_cast<uintptr_t>(&CaptureScenario); - - const ModuleCache::Module* unwinder_module = - unwinder_module_cache.GetExistingModuleForAddress( - chrome_function_address); - ASSERT_NE(nullptr, unwinder_module); - - ModuleCache reference_module_cache; - const ModuleCache::Module* reference_module = - reference_module_cache.GetModuleForAddress(chrome_function_address); - ASSERT_NE(nullptr, reference_module); - - EXPECT_EQ(reference_module->GetBaseAddress(), - unwinder_module->GetBaseAddress()); - EXPECT_NE("", unwinder_module->GetId()); - EXPECT_EQ(reference_module->GetId(), unwinder_module->GetId()); - EXPECT_EQ(reference_module->GetDebugBasename(), - unwinder_module->GetDebugBasename()); - EXPECT_EQ(unwinder_module->GetSize(), reference_module->GetSize()); + ASSERT_TRUE(module1); + EXPECT_EQ(0x1000u, module1->GetBaseAddress()); + EXPECT_EQ(nullptr, module2); + ASSERT_TRUE(module3); + EXPECT_EQ(0x3000u, module3->GetBaseAddress()); } } // namespace base
diff --git a/base/profiler/stack_sampler_impl.cc b/base/profiler/stack_sampler_impl.cc index bbe91e4..6a214d6 100644 --- a/base/profiler/stack_sampler_impl.cc +++ b/base/profiler/stack_sampler_impl.cc
@@ -92,17 +92,17 @@ std::make_move_iterator(unwinders.rend())); for (const auto& unwinder : unwinders_) - unwinder->AddInitialModules(module_cache_); + unwinder->InitializeModules(module_cache_); was_initialized_ = true; } void StackSamplerImpl::AddAuxUnwinder(std::unique_ptr<Unwinder> unwinder) { - // Initialize() invokes AddInitialModules() on the unwinders that are present + // Initialize() invokes InitializeModules() on the unwinders that are present // at the time. If it hasn't occurred yet, we allow it to add the initial // modules, otherwise we do it here. if (was_initialized_) - unwinder->AddInitialModules(module_cache_); + unwinder->InitializeModules(module_cache_); unwinders_.push_front(std::move(unwinder)); }
diff --git a/base/profiler/stack_sampling_profiler.cc b/base/profiler/stack_sampling_profiler.cc index 2bd80be9f..0c443e2 100644 --- a/base/profiler/stack_sampling_profiler.cc +++ b/base/profiler/stack_sampling_profiler.cc
@@ -126,8 +126,8 @@ : collection_id(next_collection_id.GetNext()), params(params), finished(finished), - sampler(std::move(sampler)), - profile_builder(std::move(profile_builder)) {} + profile_builder(std::move(profile_builder)), + sampler(std::move(sampler)) {} ~CollectionContext() = default; // An identifier for this collection, used to uniquely identify the @@ -137,12 +137,12 @@ const SamplingParams params; // Information about how to sample. WaitableEvent* const finished; // Signaled when all sampling complete. - // Platform-specific module that does the actual sampling. - std::unique_ptr<StackSampler> sampler; - // Receives the sampling data and builds a CallStackProfile. std::unique_ptr<ProfileBuilder> profile_builder; + // Platform-specific module that does the actual sampling. + std::unique_ptr<StackSampler> sampler; + // The absolute time for the next sample. TimeTicks next_sample_time; @@ -217,7 +217,7 @@ // signalled. The |collection| should already have been removed from // |active_collections_| by the caller, as this is needed to avoid flakiness // in unit tests. - void FinishCollection(CollectionContext* collection); + void FinishCollection(std::unique_ptr<CollectionContext> collection); // Check if the sampling thread is idle and begin a shutdown if it is. void ScheduleShutdownIfIdle(); @@ -506,7 +506,7 @@ } void StackSamplingProfiler::SamplingThread::FinishCollection( - CollectionContext* collection) { + std::unique_ptr<CollectionContext> collection) { DCHECK_EQ(GetThreadId(), PlatformThread::CurrentId()); DCHECK_EQ(0u, active_collections_.count(collection->collection_id)); @@ -518,7 +518,11 @@ profile_duration, collection->params.sampling_interval); // Signal that this collection is finished. - collection->finished->Signal(); + WaitableEvent* collection_finished = collection->finished; + // Ensure the collection is destroyed before signaling, so that it may + // not outlive StackSamplingProfiler. + collection.reset(); + collection_finished->Signal(); ScheduleShutdownIfIdle(); } @@ -612,7 +616,7 @@ size_t count = active_collections_.erase(collection_id); DCHECK_EQ(1U, count); - FinishCollection(collection.get()); + FinishCollection(std::move(collection)); } void StackSamplingProfiler::SamplingThread::RecordSampleTask( @@ -658,7 +662,7 @@ DCHECK_EQ(1U, count); // All capturing has completed so finish the collection. - FinishCollection(collection); + FinishCollection(std::move(owned_collection)); } void StackSamplingProfiler::SamplingThread::ShutdownTask(int add_events) {
diff --git a/base/profiler/stack_sampling_profiler_unittest.cc b/base/profiler/stack_sampling_profiler_unittest.cc index 6c8c3a32..e686fd20 100644 --- a/base/profiler/stack_sampling_profiler_unittest.cc +++ b/base/profiler/stack_sampling_profiler_unittest.cc
@@ -230,22 +230,6 @@ DISALLOW_COPY_AND_ASSIGN(TestProfilerInfo); }; -// Creates multiple profilers based on a vector of parameters. -std::vector<std::unique_ptr<TestProfilerInfo>> CreateProfilers( - SamplingProfilerThreadToken target_thread_token, - const std::vector<SamplingParams>& params, - ModuleCache* module_cache) { - DCHECK(!params.empty()); - - std::vector<std::unique_ptr<TestProfilerInfo>> profilers; - for (const auto& i : params) { - profilers.push_back(std::make_unique<TestProfilerInfo>(target_thread_token, - i, module_cache)); - } - - return profilers; -} - // Captures samples as specified by |params| on the TargetThread, and returns // them. Waits up to |profiler_wait_time| for the profiler to complete. std::vector<std::vector<Frame>> CaptureSamples(const SamplingParams& params, @@ -483,7 +467,7 @@ TestAuxUnwinder(const TestAuxUnwinder&) = delete; TestAuxUnwinder& operator=(const TestAuxUnwinder&) = delete; - void AddInitialModules(ModuleCache* module_cache) override { + void InitializeModules(ModuleCache* module_cache) override { if (add_initial_modules_callback_) add_initial_modules_callback_.Run(); } @@ -631,8 +615,8 @@ size_t count_ = 0; }; - WithTargetThread(BindLambdaForTesting( - [this](SamplingProfilerThreadToken target_thread_token) { + WithTargetThread( + BindLambdaForTesting([](SamplingProfilerThreadToken target_thread_token) { SamplingParams params[2]; // Providing an initial delay makes it more likely that both will be @@ -648,11 +632,11 @@ params[1].samples_per_profile = 100000; SampleRecordedCounter samples_recorded[size(params)]; - + ModuleCache module_cache1, module_cache2; TestProfilerInfo profiler_info0(target_thread_token, params[0], - module_cache(), &samples_recorded[0]); + &module_cache1, &samples_recorded[0]); TestProfilerInfo profiler_info1(target_thread_token, params[1], - module_cache(), &samples_recorded[1]); + &module_cache2, &samples_recorded[1]); profiler_info0.profiler.Start(); profiler_info1.profiler.Start(); @@ -848,23 +832,26 @@ // Checks that a sampler can be started while another is running. PROFILER_TEST_F(StackSamplingProfilerTest, MultipleStart) { - WithTargetThread(BindLambdaForTesting( - [this](SamplingProfilerThreadToken target_thread_token) { - std::vector<SamplingParams> params(2); + WithTargetThread( + BindLambdaForTesting([](SamplingProfilerThreadToken target_thread_token) { + SamplingParams params1; + params1.initial_delay = AVeryLongTimeDelta(); + params1.samples_per_profile = 1; + ModuleCache module_cache1; + TestProfilerInfo profiler_info1(target_thread_token, params1, + &module_cache1); - params[0].initial_delay = AVeryLongTimeDelta(); - params[0].samples_per_profile = 1; + SamplingParams params2; + params2.sampling_interval = TimeDelta::FromMilliseconds(1); + params2.samples_per_profile = 1; + ModuleCache module_cache2; + TestProfilerInfo profiler_info2(target_thread_token, params2, + &module_cache2); - params[1].sampling_interval = TimeDelta::FromMilliseconds(1); - params[1].samples_per_profile = 1; - - std::vector<std::unique_ptr<TestProfilerInfo>> profiler_infos = - CreateProfilers(target_thread_token, params, module_cache()); - - profiler_infos[0]->profiler.Start(); - profiler_infos[1]->profiler.Start(); - profiler_infos[1]->completed.Wait(); - EXPECT_EQ(1u, profiler_infos[1]->profile.samples.size()); + profiler_info1.profiler.Start(); + profiler_info2.profiler.Start(); + profiler_info2.completed.Wait(); + EXPECT_EQ(1u, profiler_info2.profile.samples.size()); })); } @@ -981,20 +968,26 @@ // started. PROFILER_TEST_F(StackSamplingProfilerTest, ProfileBeforeAndAfterSamplingThreadRunning) { - WithTargetThread(BindLambdaForTesting( - [this](SamplingProfilerThreadToken target_thread_token) { - std::vector<SamplingParams> params(2); + WithTargetThread( + BindLambdaForTesting([](SamplingProfilerThreadToken target_thread_token) { + ModuleCache module_cache1; + ModuleCache module_cache2; - params[0].initial_delay = AVeryLongTimeDelta(); - params[0].sampling_interval = TimeDelta::FromMilliseconds(1); - params[0].samples_per_profile = 1; - - params[1].initial_delay = TimeDelta::FromMilliseconds(0); - params[1].sampling_interval = TimeDelta::FromMilliseconds(1); - params[1].samples_per_profile = 1; - - std::vector<std::unique_ptr<TestProfilerInfo>> profiler_infos = - CreateProfilers(target_thread_token, params, module_cache()); + std::vector<std::unique_ptr<TestProfilerInfo>> profiler_infos; + profiler_infos.push_back(std::make_unique<TestProfilerInfo>( + target_thread_token, + SamplingParams{ + /*initial_delay=*/AVeryLongTimeDelta(), + /*samples_per_profile=*/1, + /*sampling_interval=*/TimeDelta::FromMilliseconds(1)}, + &module_cache1)); + profiler_infos.push_back(std::make_unique<TestProfilerInfo>( + target_thread_token, + SamplingParams{ + /*initial_delay=*/TimeDelta::FromMilliseconds(0), + /*samples_per_profile=*/1, + /*sampling_interval=*/TimeDelta::FromMilliseconds(1)}, + &module_cache2)); // First profiler is started when there has never been a sampling // thread. @@ -1053,9 +1046,9 @@ // Checks that synchronized multiple sampling requests execute in parallel. PROFILER_TEST_F(StackSamplingProfilerTest, ConcurrentProfiling_InSync) { - WithTargetThread(BindLambdaForTesting( - [this](SamplingProfilerThreadToken target_thread_token) { - std::vector<SamplingParams> params(2); + WithTargetThread( + BindLambdaForTesting([](SamplingProfilerThreadToken target_thread_token) { + std::vector<ModuleCache> module_caches(2); // Providing an initial delay makes it more likely that both will be // scheduled before either starts to run. Once started, samples will @@ -1063,16 +1056,21 @@ // whatever interval the thread wakes up. Thus, total execution time // will be 10ms (delay) + 10x1ms (sampling) + 1/2 timer minimum // interval. - params[0].initial_delay = TimeDelta::FromMilliseconds(10); - params[0].sampling_interval = TimeDelta::FromMilliseconds(1); - params[0].samples_per_profile = 9; - - params[1].initial_delay = TimeDelta::FromMilliseconds(11); - params[1].sampling_interval = TimeDelta::FromMilliseconds(1); - params[1].samples_per_profile = 8; - - std::vector<std::unique_ptr<TestProfilerInfo>> profiler_infos = - CreateProfilers(target_thread_token, params, module_cache()); + std::vector<std::unique_ptr<TestProfilerInfo>> profiler_infos; + profiler_infos.push_back(std::make_unique<TestProfilerInfo>( + target_thread_token, + SamplingParams{ + /*initial_delay=*/TimeDelta::FromMilliseconds(10), + /*samples_per_profile=*/9, + /*sampling_interval=*/TimeDelta::FromMilliseconds(1)}, + &module_caches[0])); + profiler_infos.push_back(std::make_unique<TestProfilerInfo>( + target_thread_token, + SamplingParams{ + /*initial_delay=*/TimeDelta::FromMilliseconds(11), + /*samples_per_profile=*/8, + /*sampling_interval=*/TimeDelta::FromMilliseconds(1)}, + &module_caches[1])); profiler_infos[0]->profiler.Start(); profiler_infos[1]->profiler.Start(); @@ -1092,39 +1090,43 @@ // Checks that several mixed sampling requests execute in parallel. PROFILER_TEST_F(StackSamplingProfilerTest, ConcurrentProfiling_Mixed) { - WithTargetThread(BindLambdaForTesting( - [this](SamplingProfilerThreadToken target_thread_token) { - std::vector<SamplingParams> params(3); + WithTargetThread(BindLambdaForTesting([](SamplingProfilerThreadToken + target_thread_token) { + std::vector<ModuleCache> module_caches(3); - params[0].initial_delay = TimeDelta::FromMilliseconds(8); - params[0].sampling_interval = TimeDelta::FromMilliseconds(4); - params[0].samples_per_profile = 10; + std::vector<std::unique_ptr<TestProfilerInfo>> profiler_infos; + profiler_infos.push_back(std::make_unique<TestProfilerInfo>( + target_thread_token, + SamplingParams{/*initial_delay=*/TimeDelta::FromMilliseconds(8), + /*samples_per_profile=*/10, + /*sampling_interval=*/TimeDelta::FromMilliseconds(4)}, + &module_caches[0])); + profiler_infos.push_back(std::make_unique<TestProfilerInfo>( + target_thread_token, + SamplingParams{/*initial_delay=*/TimeDelta::FromMilliseconds(9), + /*samples_per_profile=*/10, + /*sampling_interval=*/TimeDelta::FromMilliseconds(3)}, + &module_caches[1])); + profiler_infos.push_back(std::make_unique<TestProfilerInfo>( + target_thread_token, + SamplingParams{/*initial_delay=*/TimeDelta::FromMilliseconds(10), + /*samples_per_profile=*/10, + /*sampling_interval=*/TimeDelta::FromMilliseconds(2)}, + &module_caches[2])); - params[1].initial_delay = TimeDelta::FromMilliseconds(9); - params[1].sampling_interval = TimeDelta::FromMilliseconds(3); - params[1].samples_per_profile = 10; + for (auto& i : profiler_infos) + i->profiler.Start(); - params[2].initial_delay = TimeDelta::FromMilliseconds(10); - params[2].sampling_interval = TimeDelta::FromMilliseconds(2); - params[2].samples_per_profile = 10; - - std::vector<std::unique_ptr<TestProfilerInfo>> profiler_infos = - CreateProfilers(target_thread_token, params, module_cache()); - - for (auto& i : profiler_infos) - i->profiler.Start(); - - // Wait for one profiler to finish. - size_t completed_profiler = WaitForSamplingComplete(profiler_infos); - EXPECT_EQ(10u, - profiler_infos[completed_profiler]->profile.samples.size()); - // Stop and destroy all profilers, always in the same order. Don't - // crash. - for (auto& i : profiler_infos) - i->profiler.Stop(); - for (auto& i : profiler_infos) - i.reset(); - })); + // Wait for one profiler to finish. + size_t completed_profiler = WaitForSamplingComplete(profiler_infos); + EXPECT_EQ(10u, profiler_infos[completed_profiler]->profile.samples.size()); + // Stop and destroy all profilers, always in the same order. Don't + // crash. + for (auto& i : profiler_infos) + i->profiler.Stop(); + for (auto& i : profiler_infos) + i.reset(); + })); } // Checks that different threads can be sampled in parallel. @@ -1161,6 +1163,7 @@ params2.samples_per_profile = 8; Profile profile1, profile2; + ModuleCache module_cache1, module_cache2; WaitableEvent sampling_thread_completed1( WaitableEvent::ResetPolicy::MANUAL, @@ -1168,13 +1171,13 @@ StackSamplingProfiler profiler1( target_thread1.thread_token(), params1, std::make_unique<TestProfileBuilder>( - module_cache(), + &module_cache1, BindLambdaForTesting( [&profile1, &sampling_thread_completed1](Profile result_profile) { profile1 = std::move(result_profile); sampling_thread_completed1.Signal(); })), - CreateCoreUnwindersFactoryForTesting(module_cache())); + CreateCoreUnwindersFactoryForTesting(&module_cache1)); WaitableEvent sampling_thread_completed2( WaitableEvent::ResetPolicy::MANUAL, @@ -1182,13 +1185,13 @@ StackSamplingProfiler profiler2( target_thread2.thread_token(), params2, std::make_unique<TestProfileBuilder>( - module_cache(), + &module_cache2, BindLambdaForTesting( [&profile2, &sampling_thread_completed2](Profile result_profile) { profile2 = std::move(result_profile); sampling_thread_completed2.Signal(); })), - CreateCoreUnwindersFactoryForTesting(module_cache())); + CreateCoreUnwindersFactoryForTesting(&module_cache2)); // Finally the real work. profiler1.Start();
diff --git a/base/profiler/unwinder.h b/base/profiler/unwinder.h index 06f70021..864f29ff 100644 --- a/base/profiler/unwinder.h +++ b/base/profiler/unwinder.h
@@ -36,9 +36,12 @@ public: virtual ~Unwinder() = default; - // Invoked to allow the unwinder to add any modules it recognizes to the - // ModuleCache. - virtual void AddInitialModules(ModuleCache* module_cache) {} + // Invoked to allow the unwinder to add any modules it recognizes or register + // a module factory to the ModuleCache. This associates this Unwinder with + // |module_cache| for the remaining of its lifetime, which is reused in + // subsequent methods UpdateModules() and TryUnwinder(). Thus, |module_cache| + // must outlive this Unwinder. + virtual void InitializeModules(ModuleCache* module_cache) {} // Invoked at the time the stack is captured. IMPORTANT NOTE: this function is // invoked while the target thread is suspended. To avoid deadlock it must not
diff --git a/base/trace_event/common/trace_event_common.h b/base/trace_event/common/trace_event_common.h index 120481f3..684c8a6 100644 --- a/base/trace_event/common/trace_event_common.h +++ b/base/trace_event/common/trace_event_common.h
@@ -861,109 +861,6 @@ category_group, name, id, \ TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val) -// Records a single FLOW_BEGIN event called "name" immediately, with 0, 1 or 2 -// associated arguments. If the category is not enabled, then this -// does nothing. -// - category and name strings must have application lifetime (statics or -// literals). They may not include " chars. -// - |id| is used to match the FLOW_BEGIN event with the FLOW_END event. FLOW -// events are considered to match if their category_group, name and id values -// all match. |id| must either be a pointer or an integer value up to 64 bits. -// If it's a pointer, the bits will be xored with a hash of the process ID so -// that the same pointer on two different processes will not collide. -// FLOW events are different from ASYNC events in how they are drawn by the -// tracing UI. A FLOW defines asynchronous data flow, such as posting a task -// (FLOW_BEGIN) and later executing that task (FLOW_END). Expect FLOWs to be -// drawn as lines or arrows from FLOW_BEGIN scopes to FLOW_END scopes. Similar -// to ASYNC, a FLOW can consist of multiple phases. The first phase is defined -// by the FLOW_BEGIN calls. Additional phases can be defined using the FLOW_STEP -// macros. When the operation completes, call FLOW_END. An async operation can -// span threads and processes, but all events in that operation must use the -// same |name| and |id|. Each event can have its own args. -#define TRACE_EVENT_FLOW_BEGIN0(category_group, name, id) \ - INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, \ - category_group, name, id, \ - TRACE_EVENT_FLAG_NONE) -#define TRACE_EVENT_FLOW_BEGIN1(category_group, name, id, arg1_name, arg1_val) \ - INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, \ - category_group, name, id, \ - TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val) -#define TRACE_EVENT_FLOW_BEGIN2(category_group, name, id, arg1_name, arg1_val, \ - arg2_name, arg2_val) \ - INTERNAL_TRACE_EVENT_ADD_WITH_ID( \ - TRACE_EVENT_PHASE_FLOW_BEGIN, category_group, name, id, \ - TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, arg2_name, arg2_val) -#define TRACE_EVENT_COPY_FLOW_BEGIN0(category_group, name, id) \ - INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, \ - category_group, name, id, \ - TRACE_EVENT_FLAG_COPY) -#define TRACE_EVENT_COPY_FLOW_BEGIN1(category_group, name, id, arg1_name, \ - arg1_val) \ - INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, \ - category_group, name, id, \ - TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val) -#define TRACE_EVENT_COPY_FLOW_BEGIN2(category_group, name, id, arg1_name, \ - arg1_val, arg2_name, arg2_val) \ - INTERNAL_TRACE_EVENT_ADD_WITH_ID( \ - TRACE_EVENT_PHASE_FLOW_BEGIN, category_group, name, id, \ - TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, arg2_name, arg2_val) - -// Records a single FLOW_STEP event for |step| immediately. If the category -// is not enabled, then this does nothing. The |name| and |id| must match the -// FLOW_BEGIN event above. The |step| param identifies this step within the -// async event. This should be called at the beginning of the next phase of an -// asynchronous operation. -#define TRACE_EVENT_FLOW_STEP0(category_group, name, id, step) \ - INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_STEP, \ - category_group, name, id, \ - TRACE_EVENT_FLAG_NONE, "step", step) -#define TRACE_EVENT_FLOW_STEP1(category_group, name, id, step, arg1_name, \ - arg1_val) \ - INTERNAL_TRACE_EVENT_ADD_WITH_ID( \ - TRACE_EVENT_PHASE_FLOW_STEP, category_group, name, id, \ - TRACE_EVENT_FLAG_NONE, "step", step, arg1_name, arg1_val) -#define TRACE_EVENT_COPY_FLOW_STEP0(category_group, name, id, step) \ - INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_STEP, \ - category_group, name, id, \ - TRACE_EVENT_FLAG_COPY, "step", step) -#define TRACE_EVENT_COPY_FLOW_STEP1(category_group, name, id, step, arg1_name, \ - arg1_val) \ - INTERNAL_TRACE_EVENT_ADD_WITH_ID( \ - TRACE_EVENT_PHASE_FLOW_STEP, category_group, name, id, \ - TRACE_EVENT_FLAG_COPY, "step", step, arg1_name, arg1_val) - -// Records a single FLOW_END event for "name" immediately. If the category -// is not enabled, then this does nothing. -#define TRACE_EVENT_FLOW_END0(category_group, name, id) \ - INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, category_group, \ - name, id, TRACE_EVENT_FLAG_NONE) -#define TRACE_EVENT_FLOW_END_BIND_TO_ENCLOSING0(category_group, name, id) \ - INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, category_group, \ - name, id, \ - TRACE_EVENT_FLAG_BIND_TO_ENCLOSING) -#define TRACE_EVENT_FLOW_END1(category_group, name, id, arg1_name, arg1_val) \ - INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, category_group, \ - name, id, TRACE_EVENT_FLAG_NONE, arg1_name, \ - arg1_val) -#define TRACE_EVENT_FLOW_END2(category_group, name, id, arg1_name, arg1_val, \ - arg2_name, arg2_val) \ - INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, category_group, \ - name, id, TRACE_EVENT_FLAG_NONE, arg1_name, \ - arg1_val, arg2_name, arg2_val) -#define TRACE_EVENT_COPY_FLOW_END0(category_group, name, id) \ - INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, category_group, \ - name, id, TRACE_EVENT_FLAG_COPY) -#define TRACE_EVENT_COPY_FLOW_END1(category_group, name, id, arg1_name, \ - arg1_val) \ - INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, category_group, \ - name, id, TRACE_EVENT_FLAG_COPY, arg1_name, \ - arg1_val) -#define TRACE_EVENT_COPY_FLOW_END2(category_group, name, id, arg1_name, \ - arg1_val, arg2_name, arg2_val) \ - INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, category_group, \ - name, id, TRACE_EVENT_FLAG_COPY, arg1_name, \ - arg1_val, arg2_name, arg2_val) - // Special trace event macro to trace task execution with the location where it // was posted from. #define TRACE_TASK_EXECUTION(run_function, task) \
diff --git a/base/trace_event/trace_event_unittest.cc b/base/trace_event/trace_event_unittest.cc index 657c53f..457bcdf 100644 --- a/base/trace_event/trace_event_unittest.cc +++ b/base/trace_event/trace_event_unittest.cc
@@ -64,8 +64,6 @@ const char kAsyncIdStr[] = "0x5"; const int kAsyncId2 = 6; const char kAsyncId2Str[] = "0x6"; -const int kFlowId = 7; -const char kFlowIdStr[] = "0x7"; constexpr const char kRecordAllCategoryFilter[] = "*"; constexpr const char kAllCategory[] = "all"; @@ -445,12 +443,6 @@ "name1", "value1", "name2", "value2"); - TRACE_EVENT_FLOW_BEGIN0("all", "TRACE_EVENT_FLOW_BEGIN0 call", kFlowId); - TRACE_EVENT_FLOW_STEP0("all", "TRACE_EVENT_FLOW_STEP0 call", - kFlowId, "step1"); - TRACE_EVENT_FLOW_END_BIND_TO_ENCLOSING0("all", - "TRACE_EVENT_FLOW_END_BIND_TO_ENCLOSING0 call", kFlowId); - TRACE_COUNTER1("all", "TRACE_COUNTER1 call", 31415); TRACE_COUNTER2("all", "TRACE_COUNTER2 call", "a", 30000, @@ -643,17 +635,6 @@ EXPECT_SUB_FIND_("name2"); EXPECT_SUB_FIND_("value2"); - EXPECT_FIND_("TRACE_EVENT_FLOW_BEGIN0 call"); - EXPECT_SUB_FIND_("id"); - EXPECT_SUB_FIND_(kFlowIdStr); - EXPECT_FIND_("TRACE_EVENT_FLOW_STEP0 call"); - EXPECT_SUB_FIND_("id"); - EXPECT_SUB_FIND_(kFlowIdStr); - EXPECT_SUB_FIND_("step1"); - EXPECT_FIND_("TRACE_EVENT_FLOW_END_BIND_TO_ENCLOSING0 call"); - EXPECT_SUB_FIND_("id"); - EXPECT_SUB_FIND_(kFlowIdStr); - EXPECT_FIND_("TRACE_COUNTER1 call"); { std::string ph;
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index a0f2152..622c2f0 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -0.20210111.1.1 +0.20210111.3.1
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index a0f2152..622c2f0 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -0.20210111.1.1 +0.20210111.3.1
diff --git a/buildtools/DEPS b/buildtools/DEPS index 56de1b6..2dd38b6 100644 --- a/buildtools/DEPS +++ b/buildtools/DEPS
@@ -14,7 +14,7 @@ # # GN CIPD package version. - 'gn_version': 'git_revision:0d67e272bdb8145f87d238bc0b2cb8bf80ccec90', + 'gn_version': 'git_revision:595e3be7c8381d4eeefce62a63ec12bae9ce5140', # By default, do not checkout the re-client binaries. 'checkout_reclient': False,
diff --git a/cc/animation/scroll_offset_animation_curve.cc b/cc/animation/scroll_offset_animation_curve.cc index bc1a33e..52bb2a8 100644 --- a/cc/animation/scroll_offset_animation_curve.cc +++ b/cc/animation/scroll_offset_animation_curve.cc
@@ -361,6 +361,11 @@ DCHECK_NE(animation_type_, AnimationType::kLinear) << "UpdateTarget is not supported on linear scroll animations."; + // UpdateTarget is still called for linear animations occasionally. This is + // tracked via crbug.com/1164008. + if (animation_type_ == AnimationType::kLinear) + return; + // If the new UpdateTarget actually happened before the previous one, keep // |t| as the most recent, but reduce the duration of any generated // animation.
diff --git a/cc/animation/scroll_timeline.h b/cc/animation/scroll_timeline.h index c79001f..fbdbc46783 100644 --- a/cc/animation/scroll_timeline.h +++ b/cc/animation/scroll_timeline.h
@@ -5,6 +5,7 @@ #ifndef CC_ANIMATION_SCROLL_TIMELINE_H_ #define CC_ANIMATION_SCROLL_TIMELINE_H_ +#include <vector> #include "base/optional.h" #include "base/time/time.h" #include "cc/animation/animation_export.h" @@ -124,14 +125,22 @@ template <typename T> double ComputeProgress(double current_offset, const T& resolved_offsets) { DCHECK_GE(resolved_offsets.size(), 2u); + // When start offset is greater than end offset, current time is calculated + // outside of this method. + DCHECK(resolved_offsets[0] < resolved_offsets[resolved_offsets.size() - 1]); DCHECK(current_offset < resolved_offsets[resolved_offsets.size() - 1]); - // Look for scroll offset that contains the current offset. + // Traverse scroll offsets from the back to find first interval that + // contains the current offset. In case of overlapping offsets, last matching + // interval in the list is used to calculate the current time. The rational + // for choosing last matching offset is to be consistent with CSS property + // overrides. unsigned int offset_id; - for (offset_id = 1; offset_id < resolved_offsets.size() && - resolved_offsets[offset_id] <= current_offset; - offset_id++) { + for (offset_id = resolved_offsets.size() - 1; + offset_id > 0 && !(resolved_offsets[offset_id - 1] <= current_offset && + current_offset < resolved_offsets[offset_id]); + offset_id--) { } - DCHECK(offset_id < resolved_offsets.size()); + DCHECK_GE(offset_id, 1u); // Weight of each offset within time range is distributed equally. double offset_distance = 1.0 / (resolved_offsets.size() - 1); // Progress of the current offset within its offset range.
diff --git a/cc/animation/scroll_timeline_unittest.cc b/cc/animation/scroll_timeline_unittest.cc index 15589ae..4ee60fc 100644 --- a/cc/animation/scroll_timeline_unittest.cc +++ b/cc/animation/scroll_timeline_unittest.cc
@@ -205,6 +205,51 @@ time_range, vertical_timeline->CurrentTime(scroll_tree(), false)); } +TEST_F(ScrollTimelineTest, OverlappingScrollOffsets) { + double time_range = 100.0; + + // Start offset is greater than end offset ==> animation progress is + // either 0% or 100%. + std::vector<double> scroll_offsets = {350.0, 200.0, 50.0}; + + scoped_refptr<ScrollTimeline> vertical_timeline = ScrollTimeline::Create( + scroller_id(), ScrollTimeline::ScrollDown, scroll_offsets, time_range); + + // Offset is less than start offset ==> current time is 0. + SetScrollOffset(&property_trees(), scroller_id(), gfx::ScrollOffset(0, 300)); + EXPECT_SCROLL_TIMELINE_TIME_NEAR( + 0, vertical_timeline->CurrentTime(scroll_tree(), false)); + + // Offset is greater than end offset ==> current time is time_range. + SetScrollOffset(&property_trees(), scroller_id(), gfx::ScrollOffset(0, 360)); + EXPECT_SCROLL_TIMELINE_TIME_NEAR( + time_range, vertical_timeline->CurrentTime(scroll_tree(), false)); + + scroll_offsets = {0.0, 400.0, 200.0}; + + vertical_timeline = ScrollTimeline::Create( + scroller_id(), ScrollTimeline::ScrollDown, scroll_offsets, time_range); + + SetScrollOffset(&property_trees(), scroller_id(), gfx::ScrollOffset(0, 100)); + // Scroll offset is 25% of [0, 400) range, which maps to [0% 50%) of the + // entire scroll range. + EXPECT_SCROLL_TIMELINE_TIME_NEAR( + time_range * 0.5 * 0.25, + vertical_timeline->CurrentTime(scroll_tree(), false)); + + scroll_offsets = {200.0, 0.0, 400.0}; + + vertical_timeline = ScrollTimeline::Create( + scroller_id(), ScrollTimeline::ScrollDown, scroll_offsets, time_range); + + SetScrollOffset(&property_trees(), scroller_id(), gfx::ScrollOffset(0, 300)); + // Scroll offset is 75% of [0, 400) range, which maps to [50% 100%) of the + // entire scroll range. + EXPECT_SCROLL_TIMELINE_TIME_NEAR( + time_range * (0.5 + 0.5 * 0.75), + vertical_timeline->CurrentTime(scroll_tree(), false)); +} + TEST_F(ScrollTimelineTest, CurrentTimeIsAdjustedForTimeRange) { double time_range = content_size().height() - container_size().height();
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc index dd50507..29bcf4e5 100644 --- a/cc/layers/picture_layer_impl.cc +++ b/cc/layers/picture_layer_impl.cc
@@ -17,6 +17,7 @@ #include "base/metrics/histogram_macros.h" #include "base/no_destructor.h" #include "base/numerics/ranges.h" +#include "base/system/sys_info.h" #include "base/time/time.h" #include "base/trace_event/traced_value.h" #include "build/build_config.h" @@ -1112,6 +1113,15 @@ if (raster_scale < 0.1f) return true; +#if defined(OS_FUCHSIA) + // Always downscale images on low-end devices to save memory. This is a + // temporary fix to work around crbug.com/1161327 . + // TODO(crbug.com/1161327): Implement proper solution that works on all + // devices. + if (base::SysInfo::IsLowEndDevice() && raster_scale > 1.0) + return false; +#endif // defined(OS_FUCHSIA) + // If the results of scaling the bounds by the expected raster scale // would end up with a content rect whose width/height are more than one // pixel different from the layer bounds, don't directly composite the image
diff --git a/cc/paint/paint_image.cc b/cc/paint/paint_image.cc index f57728dd..70853e09 100644 --- a/cc/paint/paint_image.cc +++ b/cc/paint/paint_image.cc
@@ -298,6 +298,11 @@ texture_backing_->FlushPendingSkiaOps(); } +bool PaintImage::HasExclusiveTextureAccess() const { + DCHECK(IsTextureBacked()); + return texture_backing_->unique(); +} + int PaintImage::width() const { return paint_worklet_input_ ? static_cast<int>(paint_worklet_input_->GetSize().width())
diff --git a/cc/paint/paint_image.h b/cc/paint/paint_image.h index ab1a18c..30b369b 100644 --- a/cc/paint/paint_image.h +++ b/cc/paint/paint_image.h
@@ -239,11 +239,10 @@ int src_x, int src_y) const; - // Returned mailbox must not outlive this PaintImage. - gpu::Mailbox GetMailbox() const; + SkImageInfo GetSkImageInfo() const; Id stable_id() const { return id_; } - SkImageInfo GetSkImageInfo() const; + gpu::Mailbox GetMailbox() const; AnimationType animation_type() const { return animation_type_; } CompletionState completion_state() const { return completion_state_; } bool is_multipart() const { return is_multipart_; } @@ -266,6 +265,7 @@ // Skia internally buffers commands and flushes them as necessary but there // are some cases where we need to force a flush. void FlushPendingSkiaOps(); + bool HasExclusiveTextureAccess() const; int width() const; int height() const; SkColorSpace* color_space() const {
diff --git a/cc/paint/paint_op_buffer.cc b/cc/paint/paint_op_buffer.cc index d312f21e4..e01779d 100644 --- a/cc/paint/paint_op_buffer.cc +++ b/cc/paint/paint_op_buffer.cc
@@ -1515,14 +1515,9 @@ canvas->scale(1.f / op->scale_adjustment.width(), 1.f / op->scale_adjustment.height()); } - sk_sp<SkImage> sk_image; - if (op->image.IsTextureBacked()) { - sk_image = op->image.GetAcceleratedSkImage(); - DCHECK(sk_image || !canvas->recordingContext()); - } - if (!sk_image) - sk_image = op->image.GetSwSkImage(); - + auto sk_image = op->image.IsTextureBacked() + ? op->image.GetAcceleratedSkImage() + : op->image.GetSwSkImage(); canvas->drawImage(sk_image.get(), op->left, op->top, &paint); return; } @@ -1594,13 +1589,9 @@ if (!params.image_provider) { SkRect adjusted_src = AdjustSrcRectForScale(op->src, op->scale_adjustment); flags->DrawToSk(canvas, [op, adjusted_src](SkCanvas* c, const SkPaint& p) { - sk_sp<SkImage> sk_image; - if (op->image.IsTextureBacked()) { - sk_image = op->image.GetAcceleratedSkImage(); - DCHECK(sk_image || !c->recordingContext()); - } - if (!sk_image) - sk_image = op->image.GetSwSkImage(); + auto sk_image = op->image.IsTextureBacked() + ? op->image.GetAcceleratedSkImage() + : op->image.GetSwSkImage(); c->drawImageRect(sk_image.get(), adjusted_src, op->dst, &p, op->constraint); });
diff --git a/cc/scheduler/begin_frame_tracker.cc b/cc/scheduler/begin_frame_tracker.cc index 0480a2c..2b8b164 100644 --- a/cc/scheduler/begin_frame_tracker.cc +++ b/cc/scheduler/begin_frame_tracker.cc
@@ -18,9 +18,11 @@ void BeginFrameTracker::Start(const viz::BeginFrameArgs& new_args) { // Trace the frame time being passed between BeginFrameTrackers. - TRACE_EVENT_FLOW_STEP0( - TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"), "BeginFrameArgs", - new_args.frame_time.since_origin().InMicroseconds(), location_string_); + TRACE_EVENT_WITH_FLOW1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"), + "BeginFrameArgs", + TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, + new_args.frame_time.since_origin().InMicroseconds(), + "location", location_string_); // Trace this specific begin frame tracker Start/Finish times. TRACE_EVENT_COPY_ASYNC_BEGIN2(
diff --git a/cc/scheduler/scheduler.cc b/cc/scheduler/scheduler.cc index 8f51ef9..7a73f48e 100644 --- a/cc/scheduler/scheduler.cc +++ b/cc/scheduler/scheduler.cc
@@ -356,9 +356,9 @@ } // Trace this begin frame time through the Chrome stack - TRACE_EVENT_FLOW_BEGIN0( - TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"), - "viz::BeginFrameArgs", args.frame_time.since_origin().InMicroseconds()); + TRACE_EVENT_WITH_FLOW0(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"), + "viz::BeginFrameArgs", TRACE_EVENT_FLAG_FLOW_OUT, + args.frame_time.since_origin().InMicroseconds()); if (settings_.using_synchronous_renderer_compositor) { BeginImplFrameSynchronous(args);
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 8621f41..abd434e 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -311,7 +311,6 @@ "//chrome/browser/download/android:file_provider_java", "//chrome/browser/download/android:java", "//chrome/browser/download/android:java_resources", - "//chrome/browser/engagement/android:java", "//chrome/browser/enterprise/util:java", "//chrome/browser/feedback/android:java", "//chrome/browser/flags:java", @@ -455,6 +454,7 @@ "//components/signin/core/browser:signin_enums_java", "//components/signin/core/browser/android:java", "//components/signin/public/android:java", + "//components/site_engagement/content/android:java", "//components/spellcheck/browser/android:java", "//components/strictmode/android:java", "//components/subresource_filter/android:java", @@ -1066,7 +1066,6 @@ "//chrome/browser/download/android:java", "//chrome/browser/download/internal/android:javatests", "//chrome/browser/endpoint_fetcher:java", - "//chrome/browser/engagement/android:java", "//chrome/browser/enterprise/util:java", "//chrome/browser/feedback/android:java", "//chrome/browser/flags:java", @@ -1218,6 +1217,7 @@ "//components/signin/core/browser/android:signin_java_test_support", "//components/signin/core/browser/android:signin_javatests", "//components/signin/public/android:java", + "//components/site_engagement/content/android:java", "//components/strictmode/android:javatests", "//components/sync/android:sync_java", "//components/sync/protocol:protocol_java", @@ -3223,6 +3223,7 @@ # Files under a feature's public/ dir are included in chrome_java's source # files, so include these files in chrome_jni_headers. "feed/core/java/src/org/chromium/chrome/browser/feed/v2/FeedImageFetchClient.java", + "feed/core/java/src/org/chromium/chrome/browser/feed/v2/FeedPersistentKeyValueCache.java", "feed/core/java/src/org/chromium/chrome/browser/feed/v2/FeedServiceBridge.java", "feed/core/java/src/org/chromium/chrome/browser/feed/v2/FeedStreamSurface.java", "java/src/org/chromium/chrome/browser/AfterStartupTaskUtils.java",
diff --git a/chrome/android/DEPS b/chrome/android/DEPS index ace4f6d..086730b 100644 --- a/chrome/android/DEPS +++ b/chrome/android/DEPS
@@ -66,6 +66,7 @@ "+components/security_interstitials/content/android", "+components/signin/core/browser/android", "+components/signin/public/android", + "+components/site_engagement/content/android", "+components/spellcheck/browser", "+components/strictmode/android", "+components/subresource_filter/android",
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni index 8265217..b910bb3 100644 --- a/chrome/android/chrome_java_sources.gni +++ b/chrome/android/chrome_java_sources.gni
@@ -785,6 +785,7 @@ "java/src/org/chromium/chrome/browser/messages/MessageContainerCoordinator.java", "java/src/org/chromium/chrome/browser/metrics/ActivityTabStartupMetricsTracker.java", "java/src/org/chromium/chrome/browser/metrics/BackgroundTaskMemoryMetricsEmitter.java", + "java/src/org/chromium/chrome/browser/metrics/LaunchCauseMetrics.java", "java/src/org/chromium/chrome/browser/metrics/LaunchMetrics.java", "java/src/org/chromium/chrome/browser/metrics/MainIntentBehaviorMetrics.java", "java/src/org/chromium/chrome/browser/metrics/PackageMetrics.java",
diff --git a/chrome/android/chrome_test_java_sources.gni b/chrome/android/chrome_test_java_sources.gni index 6d313d23..42a97e3 100644 --- a/chrome/android/chrome_test_java_sources.gni +++ b/chrome/android/chrome_test_java_sources.gni
@@ -269,6 +269,7 @@ "javatests/src/org/chromium/chrome/browser/media/ui/MediaSessionTest.java", "javatests/src/org/chromium/chrome/browser/media/ui/PictureInPictureControllerTest.java", "javatests/src/org/chromium/chrome/browser/metrics/BackgroundMetricsTest.java", + "javatests/src/org/chromium/chrome/browser/metrics/LaunchCauseMetricsTest.java", "javatests/src/org/chromium/chrome/browser/metrics/MainIntentBehaviorMetricsIntegrationTest.java", "javatests/src/org/chromium/chrome/browser/metrics/PageLoadMetricsTest.java", "javatests/src/org/chromium/chrome/browser/metrics/StartupLoadingMetricsTest.java",
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryIPHUtils.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryIPHUtils.java index 60348b9..3c00cf44 100644 --- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryIPHUtils.java +++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryIPHUtils.java
@@ -6,6 +6,7 @@ import android.view.View; +import androidx.annotation.Nullable; import androidx.annotation.StringRes; import org.chromium.chrome.browser.feature_engagement.TrackerFactory; @@ -41,6 +42,7 @@ tracker.notifyEvent(EventConstants.KEYBOARD_ACCESSORY_PASSWORD_AUTOFILLED); return; case FeatureConstants.KEYBOARD_ACCESSORY_PAYMENT_FILLING_FEATURE: + case FeatureConstants.KEYBOARD_ACCESSORY_PAYMENT_OFFER_FEATURE: tracker.notifyEvent(EventConstants.KEYBOARD_ACCESSORY_PAYMENT_AUTOFILLED); return; } @@ -74,25 +76,6 @@ } /** - * Shows a help bubble pointing to the given view. It contains an appropriate text for the given - * feature. The help bubble will not be shown if the {@link Tracker} doesn't allow it anymore. - * This may happen for example: if it was shown too often, too many IPH were triggered this - * session or other config restrictions apply. - * @param feature A String identifying the IPH feature and its appropriate help text. - * @param view The {@link View} providing context and the Rect to which the bubble will point. - * @param rootView The {@link View} used to determine the maximal dimensions for the bubble. - */ - static void showHelpBubble(String feature, View view, View rootView) { - TextBubble helpBubble = createBubble(feature, new ViewRectProvider(view), rootView); - if (helpBubble == null) return; - // To emphasize which chip is pointed to, set selected to true for the built-in highlight. - // Prefer ViewHighlighter for views without a LayerDrawable background. - view.setSelected(true); - helpBubble.addOnDismissListener(() -> { view.setSelected(false); }); - helpBubble.show(); - } - - /** * Shows a help bubble pointing to the given rect. It contains an appropriate text for the given * feature. The help bubble will not be shown if the {@link Tracker} doesn't allow it anymore. * This may happen for example: if it was shown too often, too many IPH were triggered this @@ -102,19 +85,66 @@ * @param rootView The {@link View} used to determine the maximal dimensions for the bubble. */ static void showHelpBubble(String feature, RectProvider rectProvider, View rootView) { - TextBubble helpBubble = createBubble(feature, rectProvider, rootView); + TextBubble helpBubble = createBubble(feature, rectProvider, rootView, null); if (helpBubble != null) helpBubble.show(); } + /** + * Shows a help bubble pointing to the given view. It contains an appropriate text for the given + * feature. The help bubble will not be shown if the {@link Tracker} doesn't allow it anymore. + * This may happen for example: if it was shown too often, too many IPH were triggered this + * session or other config restrictions apply. + * @param feature A String identifying the IPH feature and its appropriate help text. + * @param helpText String that should be displayed within the IPH bubble. + * @param rectProvider The {@link RectProvider} providing bounds to which the bubble will point. + * @param rootView The {@link View} used to determine the maximal dimensions for the bubble. + */ + static void showHelpBubble( + String feature, RectProvider rectProvider, View rootView, @Nullable String helpText) { + TextBubble helpBubble = createBubble(feature, rectProvider, rootView, helpText); + if (helpBubble != null) helpBubble.show(); + } + + /** + * Shows a help bubble pointing to the given view. It contains an appropriate text for the given + * feature. The help bubble will not be shown if the {@link Tracker} doesn't allow it anymore. + * This may happen for example: if it was shown too often, too many IPH were triggered this + * session or other config restrictions apply. + * @param feature A String identifying the IPH feature and its appropriate help text. + * @param helpText String that should be displayed within the IPH bubble. + * @param view The {@link View} providing context and the Rect to which the bubble will point. + * @param rootView The {@link View} used to determine the maximal dimensions for the bubble. + */ + static void showHelpBubble( + String feature, View view, View rootView, @Nullable String helpText) { + TextBubble helpBubble = + createBubble(feature, new ViewRectProvider(view), rootView, helpText); + if (helpBubble == null) return; + // To emphasize which chip is pointed to, set selected to true for the built-in highlight. + // Prefer ViewHighlighter for views without a LayerDrawable background. + view.setSelected(true); + helpBubble.addOnDismissListener(() -> { view.setSelected(false); }); + helpBubble.show(); + } + private static TextBubble createBubble( - String feature, RectProvider rectProvider, View rootView) { + String feature, RectProvider rectProvider, View rootView, @Nullable String helpText) { final Tracker tracker = getTrackerFromProfile(); if (tracker == null) return null; if (!tracker.shouldTriggerHelpUI(feature)) return null; // This call records the IPH intent. - @StringRes - int helpText = getHelpTextForFeature(feature); - TextBubble helpBubble = new TextBubble(rootView.getContext(), rootView, helpText, helpText, - rectProvider, ChromeAccessibilityUtil.get().isAccessibilityEnabled()); + TextBubble helpBubble; + // If the help text is provided, then use it directly to generate the text bubble. + if (helpText != null && !helpText.isEmpty()) { + helpBubble = new TextBubble(rootView.getContext(), rootView, helpText, helpText, + /* showArrow= */ true, rectProvider, + ChromeAccessibilityUtil.get().isAccessibilityEnabled()); + } else { + @StringRes + int helpTextResourceId = getHelpTextForFeature(feature); + helpBubble = new TextBubble(rootView.getContext(), rootView, helpTextResourceId, + helpTextResourceId, rectProvider, + ChromeAccessibilityUtil.get().isAccessibilityEnabled()); + } helpBubble.setDismissOnTouchInteraction(true); helpBubble.addOnDismissListener(() -> { tracker.dismissed(feature); }); return helpBubble;
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryMediator.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryMediator.java index 027021c2..87fa588 100644 --- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryMediator.java +++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryMediator.java
@@ -329,6 +329,10 @@ return FeatureConstants.KEYBOARD_ACCESSORY_PASSWORD_FILLING_FEATURE; } if (containsCreditCardInfo(suggestion)) { + if (!suggestion.getItemTag().isEmpty()) { + // Prefer showing a linked cashback over the general IPH. + return FeatureConstants.KEYBOARD_ACCESSORY_PAYMENT_OFFER_FEATURE; + } return FeatureConstants.KEYBOARD_ACCESSORY_PAYMENT_FILLING_FEATURE; } if (containsAddressInfo(suggestion)) {
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryModernViewBinder.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryModernViewBinder.java index 40fd157..62f9c5b 100644 --- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryModernViewBinder.java +++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryModernViewBinder.java
@@ -57,14 +57,26 @@ @Override protected void bind(AutofillBarItem item, ChipView chipView) { + int iconId = item.getSuggestion().getIconId(); if (item.getFeatureForIPH() != null) { - showHelpBubble(item.getFeatureForIPH(), chipView, mRootViewForIPH); + if (item.getFeatureForIPH().equals( + FeatureConstants.KEYBOARD_ACCESSORY_PAYMENT_OFFER_FEATURE) + && iconId != 0) { + if (iconId != 0) { + showHelpBubble(item.getFeatureForIPH(), chipView.getStartIconViewRect(), + mRootViewForIPH, item.getSuggestion().getItemTag()); + } else { + showHelpBubble(item.getFeatureForIPH(), chipView, mRootViewForIPH, + item.getSuggestion().getItemTag()); + } + } else { + showHelpBubble(item.getFeatureForIPH(), chipView, mRootViewForIPH, null); + } } chipView.getPrimaryTextView().setText(item.getSuggestion().getLabel()); chipView.getSecondaryTextView().setText(item.getSuggestion().getSublabel()); chipView.getSecondaryTextView().setVisibility( item.getSuggestion().getSublabel().isEmpty() ? View.GONE : View.VISIBLE); - int iconId = item.getSuggestion().getIconId(); chipView.setIcon(iconId != 0 ? iconId : ChipView.INVALID_ICON_ID, false); KeyboardAccessoryData.Action action = item.getAction(); assert action != null : "Tried to bind item without action. Chose a wrong ViewHolder?";
diff --git a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryModernViewTest.java b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryModernViewTest.java index db5cfe1..d1328ea7 100644 --- a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryModernViewTest.java +++ b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryModernViewTest.java
@@ -362,6 +362,33 @@ @Test @MediumTest + public void testDismissesPaymentOfferEducationBubbleOnFilling() { + String itemTag = "Cashback linked"; + AutofillBarItem itemWithIPH = new AutofillBarItem( + new AutofillSuggestion("Johnathan", "Smith", itemTag, R.drawable.ic_offer_tag_green, + false, 70000, false, false, false), + new KeyboardAccessoryData.Action("", AUTOFILL_SUGGESTION, unused -> {})); + itemWithIPH.setFeatureForIPH(FeatureConstants.KEYBOARD_ACCESSORY_PAYMENT_OFFER_FEATURE); + + TestTracker tracker = new TestTracker(); + TrackerFactory.setTrackerForTests(tracker); + + TestThreadUtils.runOnUiThreadBlocking(() -> { + mModel.set(VISIBLE, true); + mModel.get(BAR_ITEMS).set(new BarItem[] {itemWithIPH, createTabs()}); + }); + + onViewWaiting(withText("Johnathan")); + waitForHelpBubble(withText(itemTag)); + onView(withText("Johnathan")).perform(click()); + + assertThat(tracker.wasDismissed(), is(true)); + assertThat(tracker.getLastEmittedEvent(), + is(EventConstants.KEYBOARD_ACCESSORY_PAYMENT_AUTOFILLED)); + } + + @Test + @MediumTest public void testNotifiesAboutPartiallyVisibleSuggestions() throws InterruptedException { // Ensure that the callback isn't triggered while all items are visible: AtomicInteger obfuscatedChildAt = new AtomicInteger(-1);
diff --git a/chrome/android/features/tab_ui/BUILD.gn b/chrome/android/features/tab_ui/BUILD.gn index c282fa9..afb8a6e 100644 --- a/chrome/android/features/tab_ui/BUILD.gn +++ b/chrome/android/features/tab_ui/BUILD.gn
@@ -221,6 +221,7 @@ "//components/policy/android:policy_java", "//components/search_engines/android:java", "//components/signin/public/android:java", + "//components/site_engagement/content/android:java", "//content/public/android:content_java", "//content/public/android:content_java_resources", "//third_party/android_deps:android_support_v7_appcompat_java",
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/TabContext.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/TabContext.java index e376e2d..18dbfb2 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/TabContext.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/TabContext.java
@@ -10,12 +10,12 @@ import org.json.JSONException; import org.json.JSONObject; -import org.chromium.chrome.browser.engagement.SiteEngagementService; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.state.CriticalPersistedTabData; import org.chromium.chrome.browser.tabmodel.TabModelFilter; import org.chromium.chrome.browser.tabmodel.TabModelSelector; +import org.chromium.components.site_engagement.SiteEngagementService; import org.chromium.content_public.browser.NavigationEntry; import java.util.ArrayList;
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v2/FeedPersistentKeyValueCache.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v2/FeedPersistentKeyValueCache.java new file mode 100644 index 0000000..c93ba50 --- /dev/null +++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v2/FeedPersistentKeyValueCache.java
@@ -0,0 +1,49 @@ +// Copyright 2020 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. + +package org.chromium.chrome.browser.feed.v2; + +import androidx.annotation.Nullable; + +import org.chromium.base.Callback; +import org.chromium.base.ThreadUtils; +import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.annotations.NativeMethods; +import org.chromium.chrome.browser.xsurface.PersistentKeyValueCache; + +/** + * Implementation of xsurface's PersistentKeyValueCache. + */ +@JNINamespace("feed") +public class FeedPersistentKeyValueCache implements PersistentKeyValueCache { + @Override + public void lookup(byte[] key, ValueConsumer consumer) { + assert ThreadUtils.runningOnUiThread(); + FeedPersistentKeyValueCacheJni.get().lookup(key, new Callback<byte[]>() { + @Override + public void onResult(byte[] result) { + consumer.run(result); + } + }); + } + + @Override + public void put(byte[] key, byte[] value, @Nullable Runnable onComplete) { + assert ThreadUtils.runningOnUiThread(); + FeedPersistentKeyValueCacheJni.get().put(key, value, onComplete); + } + + @Override + public void evict(byte[] key, @Nullable Runnable onComplete) { + assert ThreadUtils.runningOnUiThread(); + FeedPersistentKeyValueCacheJni.get().evict(key, onComplete); + } + + @NativeMethods + interface Natives { + void lookup(byte[] key, Object consumer); + void put(byte[] key, byte[] value, Runnable onComplete); + void evict(byte[] key, Runnable onComplete); + } +}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v2/FeedProcessScopeDependencyProvider.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v2/FeedProcessScopeDependencyProvider.java index c767a3c2..8def531 100644 --- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v2/FeedProcessScopeDependencyProvider.java +++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v2/FeedProcessScopeDependencyProvider.java
@@ -21,6 +21,7 @@ import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.signin.services.IdentityServicesProvider; import org.chromium.chrome.browser.xsurface.ImageFetchClient; +import org.chromium.chrome.browser.xsurface.PersistentKeyValueCache; import org.chromium.chrome.browser.xsurface.ProcessScopeDependencyProvider; import org.chromium.components.signin.base.CoreAccountInfo; import org.chromium.components.signin.identitymanager.ConsentLevel; @@ -34,6 +35,7 @@ private Context mContext; private ImageFetchClient mImageFetchClient; + private FeedPersistentKeyValueCache mPersistentKeyValueCache; private LibraryResolver mLibraryResolver; @VisibleForTesting @@ -42,6 +44,7 @@ FeedProcessScopeDependencyProvider() { mContext = createFeedContext(ContextUtils.getApplicationContext()); mImageFetchClient = new FeedImageFetchClient(); + mPersistentKeyValueCache = new FeedPersistentKeyValueCache(); if (BundleUtils.isIsolatedSplitInstalled(mContext, FEED_SPLIT_NAME)) { mLibraryResolver = (libName) -> { return BundleUtils.getNativeLibraryPath(libName, FEED_SPLIT_NAME); @@ -85,6 +88,11 @@ } @Override + public PersistentKeyValueCache getPersistentKeyValueCache() { + return mPersistentKeyValueCache; + } + + @Override public void logError(String tag, String format, Object... args) { Log.e(tag, format, args); }
diff --git a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v2/FeedProcessScopeDependencyProviderNativeTest.java b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v2/FeedProcessScopeDependencyProviderNativeTest.java new file mode 100644 index 0000000..d06e80d --- /dev/null +++ b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v2/FeedProcessScopeDependencyProviderNativeTest.java
@@ -0,0 +1,115 @@ +// Copyright 2020 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. + +package org.chromium.chrome.browser.feed.v2; + +import androidx.test.filters.MediumTest; + +import org.hamcrest.Matchers; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.Criteria; +import org.chromium.base.test.util.CriteriaHelper; +import org.chromium.base.test.util.Feature; +import org.chromium.chrome.browser.flags.ChromeFeatureList; +import org.chromium.chrome.browser.flags.ChromeSwitches; +import org.chromium.chrome.browser.xsurface.PersistentKeyValueCache; +import org.chromium.chrome.test.ChromeJUnit4ClassRunner; +import org.chromium.chrome.test.ChromeTabbedActivityTestRule; +import org.chromium.chrome.test.util.browser.Features; +import org.chromium.content_public.browser.test.util.TestThreadUtils; + +import java.util.ArrayList; + +/** + * Tests for FeedProcessScopeDependencyProvider. Uses ChromeTabbedActivityTestRule to test native + * code. Note, this class has a 'NativeTest' suffix to avoid collision with + * a junit test with the name 'FeedProcessScopeDependencyProviderTest'. + */ +@RunWith(ChromeJUnit4ClassRunner.class) +@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) +@Features.EnableFeatures(ChromeFeatureList.INTEREST_FEED_V2) +public class FeedProcessScopeDependencyProviderNativeTest { + static final byte[] VALUE_1 = "one".getBytes(); + static final byte[] VALUE_2 = "two".getBytes(); + + String toString(byte[] array) { + if (array == null) return "null"; + return new String(array); + } + + @Rule + public final ChromeTabbedActivityTestRule mActivityTestRule = + new ChromeTabbedActivityTestRule(); + + @Before + public void setUp() throws Exception { + mActivityTestRule.startMainActivityWithURL("about:blank"); + } + + @Test + @MediumTest + @Feature({"Feed"}) + public void testPersistentKeyValueCachePutAndLookup() { + FeedProcessScopeDependencyProvider dependencyProvider = + new FeedProcessScopeDependencyProvider(); + ArrayList<String> calls = new ArrayList<String>(); + + TestThreadUtils.runOnUiThreadBlocking(() -> { + PersistentKeyValueCache cache = dependencyProvider.getPersistentKeyValueCache(); + cache.put(VALUE_1, VALUE_2, () -> calls.add("put")); + cache.lookup(VALUE_1, (byte[] v) -> calls.add("lookup1 " + toString(v))); + cache.lookup(VALUE_2, (byte[] v) -> calls.add("lookup2 " + toString(v))); + }); + CriteriaHelper.pollUiThread(() -> { + Criteria.checkThat( + "Calls match", calls, Matchers.contains("put", "lookup1 two", "lookup2 null")); + }); + } + + @Test + @MediumTest + @Feature({"Feed"}) + public void testPersistentKeyValueCacheEvict() { + FeedProcessScopeDependencyProvider dependencyProvider = + new FeedProcessScopeDependencyProvider(); + ArrayList<String> calls = new ArrayList<String>(); + + TestThreadUtils.runOnUiThreadBlocking(() -> { + PersistentKeyValueCache cache = dependencyProvider.getPersistentKeyValueCache(); + cache.put(VALUE_1, VALUE_2, () -> calls.add("put")); + cache.evict(VALUE_1, () -> calls.add("evict")); + cache.lookup(VALUE_1, (byte[] v) -> calls.add("lookup " + toString(v))); + }); + + CriteriaHelper.pollUiThread(() -> { + Criteria.checkThat( + "Calls match", calls, Matchers.contains("put", "evict", "lookup null")); + }); + } + + @Test + @MediumTest + @Feature({"Feed"}) + public void testPersistentKeyValueCacheNullRunnables() { + // Verify put() and evict() accept null runnables. + FeedProcessScopeDependencyProvider dependencyProvider = + new FeedProcessScopeDependencyProvider(); + ArrayList<String> calls = new ArrayList<String>(); + + TestThreadUtils.runOnUiThreadBlocking(() -> { + PersistentKeyValueCache cache = dependencyProvider.getPersistentKeyValueCache(); + cache.put(VALUE_1, VALUE_2, null); + cache.evict(VALUE_1, null); + cache.put(VALUE_1, VALUE_2, () -> calls.add("put")); + }); + + CriteriaHelper.pollUiThread( + () -> { Criteria.checkThat("Calls match", calls, Matchers.contains("put")); }); + } +}
diff --git a/chrome/android/feed/feed_java_sources.gni b/chrome/android/feed/feed_java_sources.gni index fd330a0..3a9248e 100644 --- a/chrome/android/feed/feed_java_sources.gni +++ b/chrome/android/feed/feed_java_sources.gni
@@ -47,6 +47,7 @@ "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v2/CardMenuBottomSheetContent.java", "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v2/FeedImageFetchClient.java", "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v2/FeedListContentManager.java", + "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v2/FeedPersistentKeyValueCache.java", "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v2/FeedProcessScopeDependencyProvider.java", "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v2/FeedServiceBridge.java", "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v2/FeedSliceViewTracker.java", @@ -734,6 +735,7 @@ if (enable_feed_v2) { feed_test_java_sources += [ + "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v2/FeedProcessScopeDependencyProviderNativeTest.java", "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v2/FeedV2NewTabPageTest.java", "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v2/FeedV2TestHelper.java", "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v2/TestFeedServer.java", @@ -743,9 +745,10 @@ feed_test_deps = [] if (enable_feed_v1 || enable_feed_v2) { feed_test_deps += feed_deps + [ - "//chrome/browser/user_education:java", - "//third_party/google-truth:google_truth_java", - "//third_party/android_deps:guava_android_java", "//chrome/browser/privacy:java", + "//chrome/browser/user_education:java", + "//chrome/browser/xsurface:java", + "//third_party/android_deps:guava_android_java", + "//third_party/google-truth:google_truth_java", ] }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java index 9ccdb8e7..0b14a0c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
@@ -114,6 +114,7 @@ import org.chromium.chrome.browser.locale.LocaleManager; import org.chromium.chrome.browser.media.PictureInPictureController; import org.chromium.chrome.browser.metrics.ActivityTabStartupMetricsTracker; +import org.chromium.chrome.browser.metrics.LaunchCauseMetrics; import org.chromium.chrome.browser.metrics.LaunchMetrics; import org.chromium.chrome.browser.metrics.UmaSessionStats; import org.chromium.chrome.browser.multiwindow.MultiWindowUtils; @@ -330,6 +331,8 @@ @Nullable private StartupTabPreloader mStartupTabPreloader; + private LaunchCauseMetrics mLaunchCauseMetrics; + // TODO(972867): Pull MenuOrKeyboardActionController out of ChromeActivity. private List<MenuOrKeyboardActionController.MenuOrKeyboardActionHandler> mMenuActionHandlers = new ArrayList<>(); @@ -727,6 +730,22 @@ return mManualFillingComponent; } + /** + * TODO(mthiesse, https://crbug.com/1163961): Make this function abstract and have derived + * classes make their own. + * @return The {@link LaunchCauseMetrics} owned by this {@link ChromeActivity}. + */ + protected LaunchCauseMetrics createLaunchCauseMetrics() { + return new LaunchCauseMetrics(); + } + + private LaunchCauseMetrics getLaunchCauseMetrics() { + if (mLaunchCauseMetrics == null) { + mLaunchCauseMetrics = createLaunchCauseMetrics(); + } + return mLaunchCauseMetrics; + } + @Override public AppMenuPropertiesDelegate createAppMenuPropertiesDelegate() { return new AppMenuPropertiesDelegateImpl(this, getActivityTabProvider(), @@ -922,6 +941,7 @@ super.onResumeWithNative(); markSessionResume(); RecordUserAction.record("MobileComeToForeground"); + getLaunchCauseMetrics().recordLaunchCause(); Tab tab = getActivityTab(); if (tab != null) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillPopupBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillPopupBridge.java index 7910154..645c5b4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillPopupBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillPopupBridge.java
@@ -160,6 +160,7 @@ * @param index Index in the array where to place a new suggestion. * @param label First line of the suggestion. * @param sublabel Second line of the suggestion. + * @param itemTag The offer label of the suggestion. * @param iconId The resource ID for the icon associated with the suggestion, or 0 for no icon. * @param isIconAtStart {@code true} if {@param iconId} is displayed before {@param label}. * @param suggestionId Identifier for the suggestion type.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/base/SplitChromeApplication.java b/chrome/android/java/src/org/chromium/chrome/browser/base/SplitChromeApplication.java index 20f7360..02c41c9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/base/SplitChromeApplication.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/base/SplitChromeApplication.java
@@ -9,19 +9,17 @@ import android.annotation.SuppressLint; import android.app.Activity; import android.content.Context; -import android.content.ContextWrapper; import android.content.pm.PackageManager; import android.os.Build; import android.os.SystemClock; import org.chromium.base.ActivityState; import org.chromium.base.ApplicationStatus; +import org.chromium.base.BundleUtils; import org.chromium.base.JNIUtils; import org.chromium.base.TraceEvent; import org.chromium.base.metrics.RecordHistogram; -import java.lang.reflect.Field; - /** * Application class to use for Chrome when //chrome code is in an isolated split. This class will * perform any necessary initialization for non-browser processes without loading code from the @@ -101,7 +99,10 @@ // chromeContext will have the same ClassLoader as the base context, so no need to // replace the ClassLoaders here. if (!context.getClassLoader().equals(chromeContext.getClassLoader())) { - replaceClassLoader(this, chromeContext.getClassLoader()); + // Replace the application Context's ClassLoader with the chrome ClassLoader, + // because the application ClassLoader is expected to be able to access all chrome + // classes. + BundleUtils.replaceClassLoader(this, chromeContext.getClassLoader()); JNIUtils.setClassLoader(chromeContext.getClassLoader()); } }); @@ -143,24 +144,9 @@ return; } - replaceClassLoader( + BundleUtils.replaceClassLoader( activity.getBaseContext(), activity.getClass().getClassLoader()); } }); } - - private static void replaceClassLoader(Context baseContext, ClassLoader classLoader) { - while (baseContext instanceof ContextWrapper) { - baseContext = ((ContextWrapper) baseContext).getBaseContext(); - } - - try { - // baseContext should now be an instance of ContextImpl. - Field classLoaderField = baseContext.getClass().getDeclaredField("mClassLoader"); - classLoaderField.setAccessible(true); - classLoaderField.set(baseContext, classLoader); - } catch (ReflectiveOperationException e) { - throw new RuntimeException("Error setting ClassLoader.", e); - } - } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkBridge.java index c1fd6ad..04c22be 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkBridge.java
@@ -840,9 +840,10 @@ * bookmark ID will be returned. * @param title The title to be used for the reading list item. * @param url The URL of the reading list item. - * @return The bookmark ID created after saving the article to the reading list. + * @return The bookmark ID created after saving the article to the reading list, or null on + * error. */ - public BookmarkId addToReadingList(String title, String url) { + public @Nullable BookmarkId addToReadingList(String title, String url) { ThreadUtils.assertOnUiThread(); assert title != null; assert url != null;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java index f3ecd364..996db5c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java
@@ -9,16 +9,12 @@ import androidx.annotation.VisibleForTesting; -import org.chromium.base.ApplicationStatus; import org.chromium.base.Callback; -import org.chromium.base.Log; import org.chromium.base.TimeUtilsJni; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.NativeMethods; import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.task.PostTask; -import org.chromium.base.task.TaskTraits; -import org.chromium.chrome.browser.crash.PureJavaExceptionReporter; import org.chromium.chrome.browser.performance_hints.PerformanceHintsObserver; import org.chromium.chrome.browser.share.LensUtils; import org.chromium.components.embedder_support.contextmenu.ContextMenuParams; @@ -37,10 +33,6 @@ public class ContextMenuHelper { private static Callback<RevampedContextMenuCoordinator> sMenuShownCallbackForTests; - private static final String TAG = "ContextMenuHelper"; - - private boolean mDismissedFromHere; - private final WebContents mWebContents; private long mNativeContextMenuHelper; @@ -72,8 +64,6 @@ @CalledByNative private void destroy() { if (mCurrentContextMenu != null) { - Log.i(TAG, "Dismissing context menu " + mCurrentContextMenu); - mDismissedFromHere = true; mCurrentContextMenu.dismiss(); mCurrentContextMenu = null; } @@ -85,11 +75,6 @@ @CalledByNative private void setPopulatorFactory(ContextMenuPopulatorFactory populatorFactory) { if (mCurrentContextMenu != null) { - // TODO(crbug.com/1154731): Clean the debugging statements once we figure out the cause - // of the crash. - Log.i(TAG, "Dismissing context menu " + mCurrentContextMenu); - mDismissedFromHere = true; - mCurrentContextMenu.dismiss(); mCurrentContextMenu = null; } @@ -127,41 +112,7 @@ mCurrentContextMenuParams = params; mWindow = windowAndroid; mCallback = (result) -> { - if (mCurrentPopulator == null) { - Log.i(TAG, "mCurrentPopulator was null when mCallback was called."); - Log.i(TAG, "mCurrentContextMenu is " + mCurrentContextMenu); - Log.i(TAG, - "ContextMenuHelper is " + (mNativeContextMenuHelper == 0 ? "" : "NOT") - + " destroyed."); - Log.i(TAG, - "Context menu was " - + (mCurrentContextMenu != null && mCurrentContextMenu.isDismissed() - ? "" - : "NOT") - + " dismissed."); - Log.i(TAG, "Activity: " + mWindow.getActivity().get()); - Log.i(TAG, - "Activity state: " - + ApplicationStatus.getStateForActivity( - mWindow.getActivity().get())); - - Throwable throwable = new Throwable( - "This is not a crash. See https://crbug.com/1153706 for details." - + "\nmCurrentContextMenu is " + mCurrentContextMenu - + "\nmCurrentPopulator was null when mCallback was called." - + "\nContextMenuHelper is " + (mNativeContextMenuHelper == 0 ? "" : "NOT") - + " destroyed." - + "\nContext menu was " - + (mCurrentContextMenu != null && mCurrentContextMenu.isDismissed() ? "" - : "NOT") - + " dismissed." - + "\nContext menu was " + (mDismissedFromHere ? "" : "NOT") - + " dismissed by ContextMenuHelper."); - PostTask.postTask(TaskTraits.BEST_EFFORT_MAY_BLOCK, - () -> PureJavaExceptionReporter.reportJavaException(throwable)); - - return; - } + if (mCurrentPopulator == null) return; mSelectedItemBeforeDismiss = true; mCurrentPopulator.onItemSelected(result); @@ -177,12 +128,6 @@ } }; mOnMenuClosed = () -> { - Log.i(TAG, "mCurrentPopulator was " + mCurrentPopulator + " when the menu closed."); - Log.i(TAG, "mCurrentContextMenu was " + mCurrentContextMenu + " when the menu closed."); - Log.i(TAG, - "Activity: " + mWindow.getActivity().get() + ", activity state: " - + ApplicationStatus.getStateForActivity(mWindow.getActivity().get())); - recordTimeToTakeActionHistogram(mSelectedItemBeforeDismiss); mCurrentContextMenu = null; if (mCurrentNativeDelegate != null) { @@ -221,9 +166,6 @@ mCurrentContextMenu = menuCoordinator; mChipDelegate = mCurrentPopulator.getChipDelegate(); - Log.i(TAG, "Created mCurrentContextMenu: " + mCurrentContextMenu); - Log.i(TAG, "Activity was " + mWindow.getActivity().get() + " when the menu was created."); - // TODO(crbug/1158604): Remove leftover Lens dependencies. LensUtils.startLensConnectionIfNecessary(mIsIncognito); if (mChipDelegate != null) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuUi.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuUi.java index 70b5d72..7a896481 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuUi.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuUi.java
@@ -43,10 +43,4 @@ * Dismiss the context menu. */ void dismiss(); - - /** - * @return Whether the menu is dismissed. It may be dismissed but still be visible, e.g. hiding - * with an animation. - */ - boolean isDismissed(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuCoordinator.java index 2e2d706..970b922d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuCoordinator.java
@@ -19,9 +19,7 @@ import androidx.annotation.VisibleForTesting; import androidx.appcompat.app.AlertDialog; -import org.chromium.base.ApplicationStatus; import org.chromium.base.Callback; -import org.chromium.base.Log; import org.chromium.chrome.R; import org.chromium.chrome.browser.performance_hints.PerformanceHintsObserver; import org.chromium.chrome.browser.performance_hints.PerformanceHintsObserver.PerformanceClass; @@ -58,7 +56,6 @@ int CONTEXT_MENU_ITEM_WITH_ICON_BUTTON = 3; } - private static final String TAG = "CMenuCoordinator"; private static final int INVALID_ITEM_ID = -1; private WebContents mWebContents; @@ -71,7 +68,6 @@ private ContextMenuDialog mDialog; private Runnable mOnMenuClosed; private ContextMenuNativeDelegate mNativeDelegate; - private boolean mIsDismissed; /** * Constructor that also sets the content offset. @@ -100,11 +96,6 @@ dismissDialog(); } - @Override - public boolean isDismissed() { - return mIsDismissed; - } - // Shows the menu with chip. void displayMenuWithChip(final WindowAndroid window, WebContents webContents, ContextMenuParams params, List<Pair<Integer, ModelList>> items, @@ -229,10 +220,6 @@ // See https://crbug.com/990987 if (activity.isFinishing() || activity.isDestroyed()) return; - Log.i(TAG, - "#clickItem called for menu " + this + ", activity: " + activity - + ", activity state: " + ApplicationStatus.getStateForActivity(activity)); - onItemClicked.onResult((int) id); dismissDialog(); } @@ -291,7 +278,6 @@ } private void dismissDialog() { - mIsDismissed = true; if (mWebContentsObserver != null) { mWebContentsObserver.destroy(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/metrics/LaunchCauseMetrics.java b/chrome/android/java/src/org/chromium/chrome/browser/metrics/LaunchCauseMetrics.java new file mode 100644 index 0000000..219be093 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/metrics/LaunchCauseMetrics.java
@@ -0,0 +1,84 @@ +// Copyright 2020 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. + +package org.chromium.chrome.browser.metrics; + +import androidx.annotation.CallSuper; +import androidx.annotation.IntDef; + +import org.chromium.base.ApplicationState; +import org.chromium.base.ApplicationStatus; +import org.chromium.base.annotations.RemovableInRelease; +import org.chromium.base.metrics.RecordHistogram; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Computes and records metrics for what caused Chrome to be launched. + */ +public class LaunchCauseMetrics { + // Static to avoid recording launch metrics when transitioning between Activities without + // Chrome leaving the foreground. + private static boolean sRecordedLaunchCause; + + /* package */ static final String LAUNCH_CAUSE_HISTOGRAM = + "MobileStartup.Experimental.LaunchCause"; + + // These values are persisted in histograms. Please do not renumber. Append only. + @IntDef({LaunchCause.OTHER}) + @Retention(RetentionPolicy.SOURCE) + /* package */ @interface LaunchCause { + int OTHER = 0; + + // A histogram enum cannot have only 1 entry, so while developing this we need to lie. + int NUM_ENTRIES = 2; + } + + public LaunchCauseMetrics() { + ApplicationStatus.registerApplicationStateListener(newState -> { + if (newState == ApplicationState.HAS_STOPPED_ACTIVITIES) { + reset(); + } + }); + } + + /** + * Resets state used to compute launch cause when Chrome is backgrounded. + */ + @CallSuper + protected void reset() { + sRecordedLaunchCause = false; + } + + /** + * TODO(mthiesse, https://crbug.com/1163961): Make this function abstract. + * + * Computes and returns what the cause of the Chrome launch was. + */ + protected @LaunchCause int computeLaunchCause() { + return LaunchCause.OTHER; + } + + /** + * Called after Chrome has launched and all information necessary to compute why Chrome was + * launched is available. + * + * Records UMA metrics for what caused Chrome to launch. + */ + public void recordLaunchCause() { + if (sRecordedLaunchCause) return; + sRecordedLaunchCause = true; + + @LaunchCause + int cause = computeLaunchCause(); + RecordHistogram.recordEnumeratedHistogram( + LAUNCH_CAUSE_HISTOGRAM, cause, LaunchCause.NUM_ENTRIES); + } + + @RemovableInRelease + /* package */ static void resetForTests() { + sRecordedLaunchCause = false; + } +}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/background_sync/PeriodicBackgroundSyncTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/background_sync/PeriodicBackgroundSyncTest.java index a9347c6..34e29b1 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/background_sync/PeriodicBackgroundSyncTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/background_sync/PeriodicBackgroundSyncTest.java
@@ -20,7 +20,6 @@ import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.Feature; import org.chromium.chrome.browser.background_sync.BackgroundSyncBackgroundTaskScheduler.BackgroundSyncTask; -import org.chromium.chrome.browser.engagement.SiteEngagementService; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.tab.Tab; @@ -29,6 +28,7 @@ import org.chromium.chrome.test.util.browser.TabTitleObserver; import org.chromium.chrome.test.util.browser.signin.AccountManagerTestRule; import org.chromium.components.externalauth.ExternalAuthUtils; +import org.chromium.components.site_engagement.SiteEngagementService; import org.chromium.content_public.browser.test.NativeLibraryTestUtils; import org.chromium.content_public.browser.test.util.BackgroundSyncNetworkUtils; import org.chromium.content_public.browser.test.util.TestThreadUtils;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkBridgeTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkBridgeTest.java index 9442632..d39bd02 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkBridgeTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkBridgeTest.java
@@ -17,11 +17,15 @@ import org.chromium.base.test.UiThreadTest; import org.chromium.base.test.util.Batch; import org.chromium.base.test.util.Feature; +import org.chromium.base.test.util.RequiresRestart; import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem; +import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.test.ChromeBrowserTestRule; import org.chromium.chrome.test.util.BookmarkTestUtil; +import org.chromium.chrome.test.util.browser.Features; import org.chromium.components.bookmarks.BookmarkId; +import org.chromium.components.bookmarks.BookmarkType; import org.chromium.content_public.browser.test.util.TestThreadUtils; import java.util.ArrayList; @@ -314,4 +318,22 @@ + "over partner bookmarks", expectedSearchResults, searchResults); } + + @Test + @SmallTest + @UiThreadTest + @RequiresRestart("Reading list glue code uses the flag to load a keyed service.") + @Features.EnableFeatures({ChromeFeatureList.READ_LATER}) + public void testAddToReadingList() { + Assert.assertNull("Should return null for non http/https URLs.", + mBookmarkBridge.addToReadingList("a", "chrome://flags")); + BookmarkId readingListId = mBookmarkBridge.addToReadingList("a", "https://www.google.com/"); + Assert.assertNotNull(readingListId); + Assert.assertEquals(BookmarkType.READING_LIST, readingListId.getType()); + BookmarkItem readingListItem = + mBookmarkBridge.getReadingListItem("https://www.google.com/"); + Assert.assertNotNull(readingListItem); + Assert.assertEquals("https://www.google.com/", readingListItem.getUrl()); + Assert.assertEquals("a", readingListItem.getTitle()); + } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/LaunchCauseMetricsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/LaunchCauseMetricsTest.java new file mode 100644 index 0000000..5c45241 --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/LaunchCauseMetricsTest.java
@@ -0,0 +1,96 @@ +// Copyright 2020 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. + +package org.chromium.chrome.browser.metrics; + +import android.app.Activity; + +import androidx.test.filters.SmallTest; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; +import org.mockito.quality.Strictness; + +import org.chromium.base.ActivityState; +import org.chromium.base.ApplicationStatus; +import org.chromium.base.metrics.RecordHistogram; +import org.chromium.base.test.BaseJUnit4ClassRunner; +import org.chromium.base.test.UiThreadTest; +import org.chromium.base.test.util.Batch; +import org.chromium.content_public.browser.test.NativeLibraryTestUtils; + +/** + * Tests basic functionality of LaunchCauseMetrics. + */ +@RunWith(BaseJUnit4ClassRunner.class) +@Batch(Batch.UNIT_TESTS) +public final class LaunchCauseMetricsTest { + @Mock + private Activity mActivity; + + @Rule + public MockitoRule mMockitoRule = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS); + + @Before + public void setUp() { + NativeLibraryTestUtils.loadNativeLibraryNoBrowserProcess(); + } + + @After + public void tearDown() { + ApplicationStatus.destroyForJUnitTests(); + LaunchCauseMetrics.resetForTests(); + } + + private static int histogramCountForValue(int value) { + return RecordHistogram.getHistogramValueCountForTesting( + LaunchCauseMetrics.LAUNCH_CAUSE_HISTOGRAM, value); + } + + @Test + @SmallTest + @UiThreadTest + public void testRecordsOncePerLaunch() throws Throwable { + int count = histogramCountForValue(LaunchCauseMetrics.LaunchCause.OTHER); + LaunchCauseMetrics metrics = new LaunchCauseMetrics(); + metrics.recordLaunchCause(); + count++; + Assert.assertEquals(count, histogramCountForValue(LaunchCauseMetrics.LaunchCause.OTHER)); + + ApplicationStatus.onStateChangeForTesting(mActivity, ActivityState.CREATED); + ApplicationStatus.onStateChangeForTesting(mActivity, ActivityState.STARTED); + ApplicationStatus.onStateChangeForTesting(mActivity, ActivityState.RESUMED); + metrics.recordLaunchCause(); + Assert.assertEquals(count, histogramCountForValue(LaunchCauseMetrics.LaunchCause.OTHER)); + + ApplicationStatus.onStateChangeForTesting(mActivity, ActivityState.PAUSED); + metrics.recordLaunchCause(); + Assert.assertEquals(count, histogramCountForValue(LaunchCauseMetrics.LaunchCause.OTHER)); + + ApplicationStatus.onStateChangeForTesting(mActivity, ActivityState.STOPPED); + metrics.recordLaunchCause(); + count++; + Assert.assertEquals(count, histogramCountForValue(LaunchCauseMetrics.LaunchCause.OTHER)); + } + + @Test + @SmallTest + @UiThreadTest + public void testRecordsOnceWithMultipleInstances() throws Throwable { + int count = histogramCountForValue(LaunchCauseMetrics.LaunchCause.OTHER); + LaunchCauseMetrics metrics = new LaunchCauseMetrics(); + metrics.recordLaunchCause(); + count++; + Assert.assertEquals(count, histogramCountForValue(LaunchCauseMetrics.LaunchCause.OTHER)); + new LaunchCauseMetrics().recordLaunchCause(); + Assert.assertEquals(count, histogramCountForValue(LaunchCauseMetrics.LaunchCause.OTHER)); + } +}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridgeTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridgeTest.java index 11edd12..a3750552 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridgeTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridgeTest.java
@@ -37,7 +37,6 @@ import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.UserActionTester; import org.chromium.chrome.R; -import org.chromium.chrome.browser.engagement.SiteEngagementService; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.permissions.PermissionTestRule; import org.chromium.chrome.browser.profiles.Profile; @@ -49,6 +48,7 @@ import org.chromium.components.browser_ui.widget.RoundedIconGenerator; import org.chromium.components.content_settings.ContentSettingValues; import org.chromium.components.permissions.PermissionDialogController; +import org.chromium.components.site_engagement.SiteEngagementService; import org.chromium.components.url_formatter.SchemeDisplay; import org.chromium.components.url_formatter.UrlFormatter; import org.chromium.components.user_prefs.UserPrefs;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/portals/PortalsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/portals/PortalsTest.java index 39ae4ec2..6a1e6dfa 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/portals/PortalsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/portals/PortalsTest.java
@@ -40,7 +40,6 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.app.ChromeActivity; import org.chromium.chrome.browser.banners.AppBannerManager; -import org.chromium.chrome.browser.engagement.SiteEngagementService; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.history.BrowsingHistoryBridge; import org.chromium.chrome.browser.history.HistoryItem; @@ -54,6 +53,7 @@ import org.chromium.chrome.test.util.browser.webapps.WebappTestPage; import org.chromium.components.location.LocationUtils; import org.chromium.components.permissions.PermissionDialogController; +import org.chromium.components.site_engagement.SiteEngagementService; import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.browser.test.util.Coordinates; import org.chromium.content_public.browser.test.util.DOMUtils;
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt index 424233c1..5ea8be8 100644 --- a/chrome/android/profiles/newest.txt +++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-89.0.4384.0_rc-r1-merged.afdo.bz2 +chromeos-chrome-amd64-89.0.4385.0_rc-r1-merged.afdo.bz2
diff --git a/chrome/app/os_settings_search_tag_strings.grdp b/chrome/app/os_settings_search_tag_strings.grdp index 1e5511e..1c28610 100644 --- a/chrome/app/os_settings_search_tag_strings.grdp +++ b/chrome/app/os_settings_search_tag_strings.grdp
@@ -1174,6 +1174,12 @@ <message name="IDS_OS_SETTINGS_TAG_ABOUT_TERMS_OF_SERVICE" desc="Text for search result item which, when clicked, navigates the user to 'About Chrome OS' settings, with a link to the Terms of Service."> Terms of Service </message> + <message name="IDS_OS_SETTINGS_TAG_ABOUT_DIAGNOSTICS" 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 'Troubleshooting'"> + Diagnostics + </message> + <message name="IDS_OS_SETTINGS_TAG_ABOUT_DIAGNOSTICS_ALT1" 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 + </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_DIAGNOSTICS.png.sha1 b/chrome/app/os_settings_search_tag_strings_grdp/IDS_OS_SETTINGS_TAG_ABOUT_DIAGNOSTICS.png.sha1 new file mode 100644 index 0000000..4e27acd1 --- /dev/null +++ b/chrome/app/os_settings_search_tag_strings_grdp/IDS_OS_SETTINGS_TAG_ABOUT_DIAGNOSTICS.png.sha1
@@ -0,0 +1 @@ +03b9e41a8763c919cf065f6fcd5c2e19d8557712 \ No newline at end of file
diff --git a/chrome/app/os_settings_search_tag_strings_grdp/IDS_OS_SETTINGS_TAG_ABOUT_DIAGNOSTICS_ALT1.png.sha1 b/chrome/app/os_settings_search_tag_strings_grdp/IDS_OS_SETTINGS_TAG_ABOUT_DIAGNOSTICS_ALT1.png.sha1 new file mode 100644 index 0000000..1eed646 --- /dev/null +++ b/chrome/app/os_settings_search_tag_strings_grdp/IDS_OS_SETTINGS_TAG_ABOUT_DIAGNOSTICS_ALT1.png.sha1
@@ -0,0 +1 @@ +b2d89c3e093f3bf2538e9acba7463616a55ded65 \ No newline at end of file
diff --git a/chrome/app/os_settings_strings.grdp b/chrome/app/os_settings_strings.grdp index 06b76986..11b36fa 100644 --- a/chrome/app/os_settings_strings.grdp +++ b/chrome/app/os_settings_strings.grdp
@@ -180,6 +180,9 @@ <message name="IDS_SETTINGS_ABOUT_PAGE_LAST_UPDATE_MESSAGE" desc="Message shown on the top level about page to inform the user that this device will no longer receive latest software updates."> This is the last automatic software and security update for this <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph>. To get future updates, upgrade to a newer model. <ph name="LINK_BEGIN"><a target="_blank" href="$2<ex>https://google.com/</ex>"></ph>Learn more<ph name="LINK_END"></a></ph> </message> + <message name="IDS_SETTINGS_ABOUT_PAGE_DIAGNOSTICS" desc="Text of the button which allows the user to diagnose their device."> + Diagnostics + </message> <!-- People (OS settings) --> <message name="IDS_OS_SETTINGS_PEOPLE" desc="Name of a section in the OS settings page." meaning="People and their accounts.">
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ABOUT_PAGE_DIAGNOSTICS.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ABOUT_PAGE_DIAGNOSTICS.png.sha1 new file mode 100644 index 0000000..3d7337b7 --- /dev/null +++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ABOUT_PAGE_DIAGNOSTICS.png.sha1
@@ -0,0 +1 @@ +20e6ba8d611ab6b26e291ac9482522da01aa9f1f \ No newline at end of file
diff --git a/chrome/app/profiles_strings.grdp b/chrome/app/profiles_strings.grdp index cc6c4d7..c9e1d224 100644 --- a/chrome/app/profiles_strings.grdp +++ b/chrome/app/profiles_strings.grdp
@@ -716,6 +716,9 @@ <message name="IDS_PROFILE_PICKER_PROFILE_CARD_NEEDS_SIGNIN_PROMPT" desc="Text on the profile card signaling that the user must sign-in in order to open a profile"> Sign in </message> + <message name="IDS_PROFILE_PICKER_PROFILE_CARD_LABEL" desc="Label for a profile card button that opens a new profile"> + Open <ph name="PROFILE_NAME">$1<ex>User</ex></ph> profile + </message> <message name="IDS_PROFILE_PICKER_PROFILE_MENU_BUTTON_NAME" desc="Text to be spoken when the focus is set to the menu button of the profile card on the picker main screen or shown on hover."> Customize your profile, including its name </message>
diff --git a/chrome/app/profiles_strings_grdp/IDS_PROFILE_PICKER_PROFILE_CARD_LABEL.png.sha1 b/chrome/app/profiles_strings_grdp/IDS_PROFILE_PICKER_PROFILE_CARD_LABEL.png.sha1 new file mode 100644 index 0000000..d12fb547 --- /dev/null +++ b/chrome/app/profiles_strings_grdp/IDS_PROFILE_PICKER_PROFILE_CARD_LABEL.png.sha1
@@ -0,0 +1 @@ +eea50f2911664882a4492bf72f588a4821c18315 \ No newline at end of file
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index fa360b36..583b8b1 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -321,8 +321,6 @@ "component_updater/games_component_installer.h", "component_updater/mei_preload_component_installer.cc", "component_updater/mei_preload_component_installer.h", - "component_updater/optimization_hints_component_installer.cc", - "component_updater/optimization_hints_component_installer.h", "component_updater/origin_trials_component_installer.cc", "component_updater/origin_trials_component_installer.h", "component_updater/pepper_flash_component_installer.cc", @@ -479,10 +477,6 @@ "engagement/important_sites_util.h", "engagement/site_engagement_helper.cc", "engagement/site_engagement_helper.h", - "engagement/site_engagement_observer.cc", - "engagement/site_engagement_observer.h", - "engagement/site_engagement_service.cc", - "engagement/site_engagement_service.h", "engagement/site_engagement_service_factory.cc", "engagement/site_engagement_service_factory.h", "enterprise/browser_management/browser_management_service.cc", @@ -512,6 +506,8 @@ "favicon/large_icon_service_factory.h", "feature_engagement/tracker_factory.cc", "feature_engagement/tracker_factory.h", + "federated_learning/floc_eligibility_observer.cc", + "federated_learning/floc_eligibility_observer.h", "federated_learning/floc_event_logger.cc", "federated_learning/floc_event_logger.h", "federated_learning/floc_id_provider.h", @@ -997,6 +993,8 @@ "page_load_metrics/observers/aborts_page_load_metrics_observer.h", "page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.cc", "page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.h", + "page_load_metrics/observers/ad_metrics/floc_page_load_metrics_observer.cc", + "page_load_metrics/observers/ad_metrics/floc_page_load_metrics_observer.h", "page_load_metrics/observers/ad_metrics/frame_data.cc", "page_load_metrics/observers/ad_metrics/frame_data.h", "page_load_metrics/observers/ad_metrics/page_ad_density_tracker.cc", @@ -2717,6 +2715,7 @@ "android/feed/v2/background_refresh_task.cc", "android/feed/v2/background_refresh_task.h", "android/feed/v2/feed_image_fetch_client.cc", + "android/feed/v2/feed_persistent_key_value_cache.cc", "android/feed/v2/feed_service_bridge.cc", "android/feed/v2/feed_service_bridge.h", "android/feed/v2/feed_service_factory.cc", @@ -3028,8 +3027,6 @@ "download/android/service/download_task_scheduler.h", "download/android/string_utils.cc", "download/download_crx_util_android.cc", - "engagement/site_engagement_service_android.cc", - "engagement/site_engagement_service_android.h", "enterprise/util/android_enterprise_info.cc", "enterprise/util/android_enterprise_info.h", "file_select_helper_contacts_android.cc", @@ -3372,7 +3369,6 @@ "//chrome/browser/share", ] - deps += [ "//chrome/browser/engagement/android:jni_headers" ] deps -= [ "//components/storage_monitor" ] if (enable_supervised_users) { @@ -5985,9 +5981,7 @@ deps += [ "//chrome/common:offline_page_auto_fetcher_mojom", "//components/offline_pages/content/background_loader", - "//components/offline_pages/content/renovations", "//components/offline_pages/core/downloads:offline_pages_ui_adapter", - "//components/offline_pages/core/renovations", "//components/offline_pages/core/request_header", ]
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 6c0185c6..e2012e9 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -3488,12 +3488,6 @@ flag_descriptions::kSystemKeyboardLockDescription, kOsDesktop, FEATURE_VALUE_TYPE(features::kSystemKeyboardLock)}, #if defined(OS_ANDROID) - {"offline-pages-load-signal-collecting", - flag_descriptions::kOfflinePagesLoadSignalCollectingName, - flag_descriptions::kOfflinePagesLoadSignalCollectingDescription, - kOsAndroid, - FEATURE_VALUE_TYPE( - offline_pages::kOfflinePagesLoadSignalCollectingFeature)}, {"offline-pages-live-page-sharing", flag_descriptions::kOfflinePagesLivePageSharingName, flag_descriptions::kOfflinePagesLivePageSharingDescription, kOsAndroid, @@ -3514,16 +3508,6 @@ kOsAndroid, FEATURE_VALUE_TYPE( offline_pages::kOfflinePagesDescriptivePendingStatusFeature)}, - {"offline-pages-resource-based-snapshot", - flag_descriptions::kOfflinePagesResourceBasedSnapshotName, - flag_descriptions::kOfflinePagesResourceBasedSnapshotDescription, - kOsAndroid, - FEATURE_VALUE_TYPE( - offline_pages::kOfflinePagesResourceBasedSnapshotFeature)}, - {"offline-pages-renovations", - flag_descriptions::kOfflinePagesRenovationsName, - flag_descriptions::kOfflinePagesRenovationsDescription, kOsAndroid, - FEATURE_VALUE_TYPE(offline_pages::kOfflinePagesRenovationsFeature)}, {"offline-pages-in-downloads-home-open-in-cct", flag_descriptions::kOfflinePagesInDownloadHomeOpenInCctName, flag_descriptions::kOfflinePagesInDownloadHomeOpenInCctDescription,
diff --git a/chrome/browser/accessibility/accessibility_extension_api_browsertest.cc b/chrome/browser/accessibility/accessibility_extension_api_browsertest.cc index 34bdbc1c1..3e8e1f26 100644 --- a/chrome/browser/accessibility/accessibility_extension_api_browsertest.cc +++ b/chrome/browser/accessibility/accessibility_extension_api_browsertest.cc
@@ -17,7 +17,16 @@ namespace extensions { -using AccessibilityPrivateApiTest = ExtensionApiTest; +class AccessibilityPrivateApiTest : public ExtensionApiTest { + public: + void SetUp() override { + scoped_feature_list_.InitAndDisableFeature( + ::features::kSelectToSpeakNavigationControl); + ExtensionApiTest::SetUp(); + } + + base::test::ScopedFeatureList scoped_feature_list_; +}; IN_PROC_BROWSER_TEST_F(AccessibilityPrivateApiTest, SendSyntheticKeyEvent) { ASSERT_TRUE(RunExtensionSubtest("accessibility_private/",
diff --git a/chrome/browser/android/bookmarks/bookmark_bridge.cc b/chrome/browser/android/bookmarks/bookmark_bridge.cc index 52ef5096..048b4ce7 100644 --- a/chrome/browser/android/bookmarks/bookmark_bridge.cc +++ b/chrome/browser/android/bookmarks/bookmark_bridge.cc
@@ -828,8 +828,9 @@ const BookmarkNode* node = reading_list_manager_->Add( GURL(base::android::ConvertJavaStringToUTF16(env, j_url)), base::android::ConvertJavaStringToUTF8(env, j_title)); - DCHECK(node); - return JavaBookmarkIdCreateBookmarkId(env, node->id(), GetBookmarkType(node)); + return node ? JavaBookmarkIdCreateBookmarkId(env, node->id(), + GetBookmarkType(node)) + : ScopedJavaLocalRef<jobject>(); } ScopedJavaLocalRef<jobject> BookmarkBridge::GetReadingListItem(
diff --git a/chrome/browser/android/feed/v2/feed_persistent_key_value_cache.cc b/chrome/browser/android/feed/v2/feed_persistent_key_value_cache.cc new file mode 100644 index 0000000..ca8b363a9 --- /dev/null +++ b/chrome/browser/android/feed/v2/feed_persistent_key_value_cache.cc
@@ -0,0 +1,111 @@ +// Copyright 2020 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 <memory> + +#include "base/android/callback_android.h" +#include "base/android/jni_android.h" +#include "base/android/jni_array.h" +#include "chrome/android/chrome_jni_headers/FeedPersistentKeyValueCache_jni.h" +#include "chrome/browser/android/feed/v2/feed_service_factory.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_manager.h" +#include "components/feed/core/v2/public/feed_service.h" +#include "components/feed/core/v2/public/feed_stream_api.h" +#include "components/feed/core/v2/public/persistent_key_value_store.h" + +namespace feed { +namespace { +using base::android::JavaParamRef; + +std::string JavaByteArrayToString( + JNIEnv* env, + const base::android::JavaRef<jbyteArray>& byte_array) { + std::string result; + base::android::JavaByteArrayToString(env, byte_array, &result); + return result; +} + +void OnLookupFinished(JNIEnv* env, + base::android::ScopedJavaGlobalRef<jobject> callback, + PersistentKeyValueStore::Result result) { + base::android::ScopedJavaLocalRef<jbyteArray> j_result; + if (result.get_result) { + j_result = base::android::ToJavaByteArray(env, *result.get_result); + } + base::android::RunObjectCallbackAndroid(callback, j_result); +} + +void CallRunnable(base::android::ScopedJavaGlobalRef<jobject> runnable, + PersistentKeyValueStore::Result result) { + if (runnable) + base::android::RunRunnableAndroid(runnable); +} + +PersistentKeyValueStore* GetStore() { + Profile* profile = ProfileManager::GetLastUsedProfile(); + if (!profile) + return nullptr; + + FeedService* feed_service = FeedServiceFactory::GetForBrowserContext(profile); + if (!feed_service) + return nullptr; + + return feed_service->GetStream()->GetPersistentKeyValueStore(); +} + +} // namespace + +void JNI_FeedPersistentKeyValueCache_Lookup( + JNIEnv* env, + const JavaParamRef<jbyteArray>& j_key, + const JavaParamRef<jobject>& j_response_callback) { + base::android::ScopedJavaGlobalRef<jobject> callback(j_response_callback); + + PersistentKeyValueStore* store = GetStore(); + if (!store) { + OnLookupFinished(env, std::move(callback), {}); + return; + } + return store->Get( + JavaByteArrayToString(env, j_key), + base::BindOnce(&OnLookupFinished, env, std::move(callback))); +} + +void JNI_FeedPersistentKeyValueCache_Put( + JNIEnv* env, + const JavaParamRef<jbyteArray>& j_key, + const JavaParamRef<jbyteArray>& j_value, + const JavaParamRef<jobject>& j_runnable) { + base::android::ScopedJavaGlobalRef<jobject> callback(j_runnable); + + PersistentKeyValueStore* store = GetStore(); + if (!store) { + base::android::RunRunnableAndroid(j_runnable); + return; + } + return store->Put( + JavaByteArrayToString(env, j_key), JavaByteArrayToString(env, j_value), + base::BindOnce(&CallRunnable, + base::android::ScopedJavaGlobalRef<jobject>(j_runnable))); +} + +void JNI_FeedPersistentKeyValueCache_Evict( + JNIEnv* env, + const JavaParamRef<jbyteArray>& j_key, + const JavaParamRef<jobject>& j_runnable) { + base::android::ScopedJavaGlobalRef<jobject> callback(j_runnable); + + PersistentKeyValueStore* store = GetStore(); + if (!store) { + base::android::RunRunnableAndroid(j_runnable); + return; + } + return store->Delete( + JavaByteArrayToString(env, j_key), + base::BindOnce(&CallRunnable, + base::android::ScopedJavaGlobalRef<jobject>(j_runnable))); +} + +} // namespace feed
diff --git a/chrome/browser/android/feed/v2/feed_service_factory.cc b/chrome/browser/android/feed/v2/feed_service_factory.cc index 472d37b..a19b022 100644 --- a/chrome/browser/android/feed/v2/feed_service_factory.cc +++ b/chrome/browser/android/feed/v2/feed_service_factory.cc
@@ -23,6 +23,7 @@ #include "chrome/common/chrome_version.h" #include "components/background_task_scheduler/background_task_scheduler_factory.h" #include "components/feed/buildflags.h" +#include "components/feed/core/proto/v2/keyvalue_store.pb.h" #include "components/feed/core/proto/v2/store.pb.h" #include "components/feed/core/v2/public/feed_service.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" @@ -129,6 +130,9 @@ storage_partition->GetProtoDatabaseProvider()->GetDB<feedstore::Record>( leveldb_proto::ProtoDbType::FEED_STREAM_DATABASE, feed_dir.AppendASCII("streamdb"), background_task_runner), + storage_partition->GetProtoDatabaseProvider()->GetDB<feedkvstore::Entry>( + leveldb_proto::ProtoDbType::FEED_KEY_VALUE_DATABASE, + feed_dir.AppendASCII("keyvaldb"), background_task_runner), identity_manager, HistoryServiceFactory::GetForProfile(profile, ServiceAccessType::IMPLICIT_ACCESS),
diff --git a/chrome/browser/android/metrics/launch_metrics.cc b/chrome/browser/android/metrics/launch_metrics.cc index c5f69b0..759b28843 100644 --- a/chrome/browser/android/metrics/launch_metrics.cc +++ b/chrome/browser/android/metrics/launch_metrics.cc
@@ -7,9 +7,9 @@ #include "base/time/time.h" #include "chrome/android/chrome_jni_headers/LaunchMetrics_jni.h" #include "chrome/browser/banners/app_banner_settings_helper.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/prefs/pref_metrics_service.h" #include "chrome/browser/profiles/profile.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "components/webapps/android/shortcut_info.h" #include "content/public/browser/web_contents.h" #include "third_party/blink/public/mojom/manifest/display_mode.mojom.h"
diff --git a/chrome/browser/android/usage_stats/usage_stats_database.cc b/chrome/browser/android/usage_stats/usage_stats_database.cc index bddd3e3..bb9bdb10 100644 --- a/chrome/browser/android/usage_stats/usage_stats_database.cc +++ b/chrome/browser/android/usage_stats/usage_stats_database.cc
@@ -219,9 +219,8 @@ return; } - // TODO(crbug/927655): If/when leveldb_proto adds an UpdateEntriesInRange - // function, we should consolidate these two proto_db_ calls into a single - // call. + // If leveldb_proto adds a DeleteEntriesInRange function, these two proto_db_ + // calls could be consolidated into a single call (crbug.com/939136). // Load all WebsiteEvents where the timestamp is in the specified range. // Function accepts a half-open range [startTime, endTime) as input, but the
diff --git a/chrome/browser/autofill/automated_tests/cache_replayer.cc b/chrome/browser/autofill/automated_tests/cache_replayer.cc index 6470a98..3b63617 100644 --- a/chrome/browser/autofill/automated_tests/cache_replayer.cc +++ b/chrome/browser/autofill/automated_tests/cache_replayer.cc
@@ -15,6 +15,7 @@ #include "base/command_line.h" #include "base/files/file_util.h" #include "base/json/json_reader.h" +#include "base/numerics/safe_conversions.h" #include "base/strings/strcat.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" @@ -215,17 +216,15 @@ // that all the response body data is utilized. std::string GetStringFromDataElements( const std::vector<network::DataElement>* data_elements) { - network::DataElement unified_data_element; - unified_data_element.SetToEmptyBytes(); - for (auto it = data_elements->begin(); it != data_elements->end(); ++it) { - unified_data_element.AppendBytes(it->bytes(), it->length()); + std::string result; + for (const network::DataElement& element : *data_elements) { + DCHECK_EQ(element.type(), network::mojom::DataElementType::kBytes); + // Provide the length of the bytes explicitly, not to rely on the null + // termination. + result.append(element.bytes(), + base::checked_cast<size_t>(element.length())); } - - // Using the std::string constructor with length ensures that we don't rely - // on having a termination character to delimit the string. This is the - // safest approach. - return std::string(unified_data_element.bytes(), - unified_data_element.length()); + return result; } // Gets Query request proto content from HTTP POST body.
diff --git a/chrome/browser/background_sync/background_sync_controller_impl_unittest.cc b/chrome/browser/background_sync/background_sync_controller_impl_unittest.cc index 2c3d2d19..8d2459a 100644 --- a/chrome/browser/background_sync/background_sync_controller_impl_unittest.cc +++ b/chrome/browser/background_sync/background_sync_controller_impl_unittest.cc
@@ -10,13 +10,13 @@ #include "base/files/scoped_temp_dir.h" #include "base/macros.h" #include "chrome/browser/background_sync/background_sync_delegate_impl.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/history/history_service_factory.h" #include "chrome/test/base/testing_profile.h" #include "components/history/core/browser/history_database_params.h" #include "components/history/core/browser/history_service.h" #include "components/history/core/test/test_history_database.h" #include "components/site_engagement/content/site_engagement_score.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "components/variations/variations_associated_data.h" #include "content/public/browser/background_sync_parameters.h" #include "content/public/browser/background_sync_registration.h"
diff --git a/chrome/browser/background_sync/background_sync_delegate_impl.cc b/chrome/browser/background_sync/background_sync_delegate_impl.cc index 7b16a18f..dc669f6d 100644 --- a/chrome/browser/background_sync/background_sync_delegate_impl.cc +++ b/chrome/browser/background_sync/background_sync_delegate_impl.cc
@@ -5,10 +5,10 @@ #include "chrome/browser/background_sync/background_sync_delegate_impl.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/metrics/ukm_background_recorder_service.h" #include "chrome/browser/profiles/profile.h" #include "components/content_settings/core/browser/host_content_settings_map.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "content/public/browser/background_sync_context.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/storage_partition.h"
diff --git a/chrome/browser/background_sync/background_sync_delegate_impl.h b/chrome/browser/background_sync/background_sync_delegate_impl.h index 50dc9e7..74b3c8ae 100644 --- a/chrome/browser/background_sync/background_sync_delegate_impl.h +++ b/chrome/browser/background_sync/background_sync_delegate_impl.h
@@ -8,8 +8,8 @@ #include <set> #include "build/build_config.h" -#include "chrome/browser/engagement/site_engagement_observer.h" #include "components/background_sync/background_sync_delegate.h" +#include "components/site_engagement/content/site_engagement_observer.h" #include "url/origin.h" class Profile;
diff --git a/chrome/browser/banners/android/BUILD.gn b/chrome/browser/banners/android/BUILD.gn index f2c8bfd..8fac3ef 100644 --- a/chrome/browser/banners/android/BUILD.gn +++ b/chrome/browser/banners/android/BUILD.gn
@@ -60,7 +60,6 @@ "//chrome/android:chrome_java", "//chrome/android:chrome_test_java", "//chrome/android:chrome_test_util_java", - "//chrome/browser/engagement/android:java", "//chrome/browser/flags:java", "//chrome/browser/profiles/android:java", "//chrome/browser/tab:java", @@ -72,6 +71,7 @@ "//components/infobars/android:java", "//components/signin/core/browser/android:java", "//components/signin/core/browser/android:signin_java_test_support", + "//components/site_engagement/content/android:java", "//components/webapps/android:java", "//content/public/android:content_java", "//content/public/test/android:content_java_test_support",
diff --git a/chrome/browser/banners/android/java/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java b/chrome/browser/banners/android/java/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java index 8deaf41..4c74c64 100644 --- a/chrome/browser/banners/android/java/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java +++ b/chrome/browser/banners/android/java/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java
@@ -64,7 +64,6 @@ import org.chromium.chrome.browser.app.ChromeActivity; import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule; import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils; -import org.chromium.chrome.browser.engagement.SiteEngagementService; import org.chromium.chrome.browser.feature_engagement.TrackerFactory; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeSwitches; @@ -92,6 +91,7 @@ import org.chromium.components.infobars.InfoBarUiItem; import org.chromium.components.signin.AccountManagerFacadeProvider; import org.chromium.components.signin.test.util.FakeAccountManagerFacade; +import org.chromium.components.site_engagement.SiteEngagementService; import org.chromium.components.webapps.installable.InstallableAmbientBadgeInfoBar; import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.content_public.browser.WebContents;
diff --git a/chrome/browser/banners/app_banner_manager.cc b/chrome/browser/banners/app_banner_manager.cc index dadee4d..4038272c 100644 --- a/chrome/browser/banners/app_banner_manager.cc +++ b/chrome/browser/banners/app_banner_manager.cc
@@ -18,9 +18,9 @@ #include "base/time/time.h" #include "chrome/browser/banners/app_banner_metrics.h" #include "chrome/browser/banners/app_banner_settings_helper.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/chrome_switches.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "components/webapps/installable/installable_data.h" #include "components/webapps/installable/installable_manager.h" #include "components/webapps/installable/installable_metrics.h"
diff --git a/chrome/browser/banners/app_banner_manager.h b/chrome/browser/banners/app_banner_manager.h index 0a4eb00..e00b47d 100644 --- a/chrome/browser/banners/app_banner_manager.h +++ b/chrome/browser/banners/app_banner_manager.h
@@ -13,7 +13,7 @@ #include "base/memory/weak_ptr.h" #include "base/observer_list.h" #include "base/strings/string16.h" -#include "chrome/browser/engagement/site_engagement_observer.h" +#include "components/site_engagement/content/site_engagement_observer.h" #include "components/webapps/installable/installable_logging.h" #include "components/webapps/installable/installable_params.h" #include "content/public/browser/media_player_id.h"
diff --git a/chrome/browser/banners/app_banner_manager_android.cc b/chrome/browser/banners/app_banner_manager_android.cc index 81fcab5c..e39498444 100644 --- a/chrome/browser/banners/app_banner_manager_android.cc +++ b/chrome/browser/banners/app_banner_manager_android.cc
@@ -20,7 +20,6 @@ #include "chrome/browser/banners/android/jni_headers/AppBannerManager_jni.h" #include "chrome/browser/banners/app_banner_metrics.h" #include "chrome/browser/banners/app_banner_settings_helper.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/flags/android/chrome_feature_list.h" #include "chrome/browser/infobars/infobar_service.h" #include "chrome/browser/webapps/android/features.h" @@ -31,6 +30,7 @@ #include "components/feature_engagement/public/tracker.h" #include "components/infobars/core/infobar.h" #include "components/infobars/core/infobar_delegate.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "components/version_info/channel.h" #include "components/webapps/android/add_to_homescreen_params.h" #include "components/webapps/android/shortcut_info.h"
diff --git a/chrome/browser/banners/app_banner_manager_browsertest.cc b/chrome/browser/banners/app_banner_manager_browsertest.cc index 2a90e31f..9c18678c 100644 --- a/chrome/browser/banners/app_banner_manager_browsertest.cc +++ b/chrome/browser/banners/app_banner_manager_browsertest.cc
@@ -19,12 +19,12 @@ #include "chrome/browser/banners/app_banner_manager_desktop.h" #include "chrome/browser/banners/app_banner_metrics.h" #include "chrome/browser/banners/app_banner_settings_helper.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/test/base/ui_test_utils.h" #include "components/site_engagement/content/site_engagement_score.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "components/webapps/installable/installable_logging.h" #include "components/webapps/installable/installable_manager.h" #include "components/webapps/installable/installable_metrics.h"
diff --git a/chrome/browser/banners/app_banner_settings_helper_unittest.cc b/chrome/browser/banners/app_banner_settings_helper_unittest.cc index fa274730..d0de883a 100644 --- a/chrome/browser/banners/app_banner_settings_helper_unittest.cc +++ b/chrome/browser/banners/app_banner_settings_helper_unittest.cc
@@ -4,9 +4,9 @@ #include "chrome/browser/banners/app_banner_settings_helper.h" #include "chrome/browser/banners/app_banner_metrics.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h" #include "chrome/test/base/testing_profile.h" +#include "components/site_engagement/content/site_engagement_service.h" namespace webapps {
diff --git a/chrome/browser/browser_process.h b/chrome/browser/browser_process.h index f04600e..1ea08a7a 100644 --- a/chrome/browser/browser_process.h +++ b/chrome/browser/browser_process.h
@@ -90,10 +90,6 @@ class NetworkTimeTracker; } -namespace optimization_guide { -class OptimizationGuideService; -} - namespace policy { class ChromeBrowserPolicyConnector; class PolicyService; @@ -229,11 +225,6 @@ virtual federated_learning::FlocSortingLshClustersService* floc_sorting_lsh_clusters_service() = 0; - // Returns the service used to provide hints for what optimizations can be - // performed on slow page loads. - virtual optimization_guide::OptimizationGuideService* - optimization_guide_service() = 0; - // Returns the StartupData which owns any pre-created objects in //chrome // before the full browser starts. virtual StartupData* startup_data() = 0;
diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc index 55619d2..35510d17 100644 --- a/chrome/browser/browser_process_impl.cc +++ b/chrome/browser/browser_process_impl.cc
@@ -100,8 +100,6 @@ #include "components/metrics_services_manager/metrics_services_manager.h" #include "components/metrics_services_manager/metrics_services_manager_client.h" #include "components/network_time/network_time_tracker.h" -#include "components/optimization_guide/core/optimization_guide_features.h" -#include "components/optimization_guide/core/optimization_guide_service.h" #include "components/permissions/permissions_client.h" #include "components/policy/core/common/policy_service.h" #include "components/prefs/json_pref_store.h" @@ -1009,14 +1007,6 @@ return floc_sorting_lsh_clusters_service_.get(); } -optimization_guide::OptimizationGuideService* -BrowserProcessImpl::optimization_guide_service() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!created_optimization_guide_service_) - CreateOptimizationGuideService(); - return optimization_guide_service_.get(); -} - StartupData* BrowserProcessImpl::startup_data() { return startup_data_; } @@ -1275,19 +1265,6 @@ std::make_unique<federated_learning::FlocSortingLshClustersService>(); } -void BrowserProcessImpl::CreateOptimizationGuideService() { - DCHECK(!created_optimization_guide_service_); - DCHECK(!optimization_guide_service_); - created_optimization_guide_service_ = true; - - if (!optimization_guide::features::IsOptimizationHintsEnabled()) - return; - - optimization_guide_service_ = - std::make_unique<optimization_guide::OptimizationGuideService>( - content::GetUIThreadTaskRunner({})); -} - #if !defined(OS_ANDROID) // Android's GCMDriver currently makes the assumption that it's a singleton. // Until this gets fixed, instantiating multiple Java GCMDrivers will throw an
diff --git a/chrome/browser/browser_process_impl.h b/chrome/browser/browser_process_impl.h index a967b1e..1d3c566 100644 --- a/chrome/browser/browser_process_impl.h +++ b/chrome/browser/browser_process_impl.h
@@ -175,8 +175,6 @@ override; federated_learning::FlocSortingLshClustersService* floc_sorting_lsh_clusters_service() override; - optimization_guide::OptimizationGuideService* optimization_guide_service() - override; StartupData* startup_data() override; @@ -330,10 +328,6 @@ std::unique_ptr<federated_learning::FlocSortingLshClustersService> floc_sorting_lsh_clusters_service_; - bool created_optimization_guide_service_ = false; - std::unique_ptr<optimization_guide::OptimizationGuideService> - optimization_guide_service_; - bool shutting_down_ = false; bool tearing_down_ = false;
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index c4647ab..117da8a 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -60,9 +60,9 @@ #include "chrome/browser/device_api/device_service_impl.h" #include "chrome/browser/download/chrome_download_manager_delegate.h" #include "chrome/browser/download/download_prefs.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/extensions/chrome_extension_cookies.h" #include "chrome/browser/external_protocol/external_protocol_handler.h" +#include "chrome/browser/federated_learning/floc_eligibility_observer.h" #include "chrome/browser/federated_learning/floc_id_provider.h" #include "chrome/browser/federated_learning/floc_id_provider_factory.h" #include "chrome/browser/font_access/chrome_font_access_delegate.h" @@ -89,6 +89,7 @@ #include "chrome/browser/notifications/platform_notification_service_impl.h" #include "chrome/browser/password_manager/chrome_password_manager_client.h" #include "chrome/browser/payments/payment_request_display_manager_factory.h" +#include "components/site_engagement/content/site_engagement_service.h" #if !defined(OS_ANDROID) #include "chrome/browser/payments/payment_handler_navigation_throttle.h" #endif @@ -5747,12 +5748,16 @@ } std::string ChromeContentBrowserClient::GetInterestCohortForJsApi( - content::BrowserContext* browser_context, + content::WebContents* web_contents, const GURL& url, const base::Optional<url::Origin>& top_frame_origin) { + federated_learning::FlocEligibilityObserver::GetOrCreateForCurrentDocument( + web_contents->GetMainFrame()) + ->OnInterestCohortApiUsed(); + federated_learning::FlocIdProvider* floc_id_provider = federated_learning::FlocIdProviderFactory::GetForProfile( - Profile::FromBrowserContext(browser_context)); + Profile::FromBrowserContext(web_contents->GetBrowserContext())); if (!floc_id_provider) return std::string();
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h index 0d7dc1a..8b59398 100644 --- a/chrome/browser/chrome_content_browser_client.h +++ b/chrome/browser/chrome_content_browser_client.h
@@ -639,7 +639,7 @@ content::NavigationDownloadPolicy* download_policy) override; std::string GetInterestCohortForJsApi( - content::BrowserContext* browser_context, + content::WebContents* web_contents, const GURL& url, const base::Optional<url::Origin>& top_frame_origin) override;
diff --git a/chrome/browser/chromeos/assistant/assistant_util.cc b/chrome/browser/chromeos/assistant/assistant_util.cc index 607cabe..2b9d8210 100644 --- a/chrome/browser/chromeos/assistant/assistant_util.cc +++ b/chrome/browser/chromeos/assistant/assistant_util.cc
@@ -72,7 +72,7 @@ NOTREACHED(); return AssistantAllowedState::DISALLOWED_BY_ACCOUNT_TYPE; - case user_manager::USER_TYPE_SUPERVISED: + case user_manager::USER_TYPE_SUPERVISED_DEPRECATED: case user_manager::NUM_USER_TYPES: NOTREACHED(); return AssistantAllowedState::DISALLOWED_BY_ACCOUNT_TYPE;
diff --git a/chrome/browser/chromeos/assistant/assistant_util_unittest.cc b/chrome/browser/chromeos/assistant/assistant_util_unittest.cc index 59bcc92..e5d9aa9 100644 --- a/chrome/browser/chromeos/assistant/assistant_util_unittest.cc +++ b/chrome/browser/chromeos/assistant/assistant_util_unittest.cc
@@ -130,7 +130,7 @@ EXPECT_EQ(account_id_, fake_user_manager_->GetGuestAccountId()); return; case user_manager::NUM_USER_TYPES: - case user_manager::USER_TYPE_SUPERVISED: + case user_manager::USER_TYPE_SUPERVISED_DEPRECATED: NOTREACHED(); } } @@ -161,7 +161,7 @@ case user_manager::USER_TYPE_GUEST: fake_user_manager_->AddGuestUser(); return; - case user_manager::USER_TYPE_SUPERVISED: + case user_manager::USER_TYPE_SUPERVISED_DEPRECATED: case user_manager::NUM_USER_TYPES: NOTREACHED(); }
diff --git a/chrome/browser/chromeos/crosapi/browser_util.cc b/chrome/browser/chromeos/crosapi/browser_util.cc index afaf136..f3c68b5a 100644 --- a/chrome/browser/chromeos/crosapi/browser_util.cc +++ b/chrome/browser/chromeos/crosapi/browser_util.cc
@@ -59,7 +59,7 @@ return true; case user_manager::USER_TYPE_GUEST: case user_manager::USER_TYPE_PUBLIC_ACCOUNT: - case user_manager::USER_TYPE_SUPERVISED: + case user_manager::USER_TYPE_SUPERVISED_DEPRECATED: case user_manager::USER_TYPE_KIOSK_APP: case user_manager::USER_TYPE_CHILD: case user_manager::USER_TYPE_ARC_KIOSK_APP:
diff --git a/chrome/browser/chromeos/drive/drivefs_native_message_host.cc b/chrome/browser/chromeos/drive/drivefs_native_message_host.cc index b617839..bb6d7e7 100644 --- a/chrome/browser/chromeos/drive/drivefs_native_message_host.cc +++ b/chrome/browser/chromeos/drive/drivefs_native_message_host.cc
@@ -64,7 +64,9 @@ DCHECK(client_); if (UseBidirectionalNativeMessaging()) { - drivefs_remote_->HandleMessageFromExtension(message); + if (drivefs_remote_) { + drivefs_remote_->HandleMessageFromExtension(message); + } } else { if (!drive_service_ || !drive_service_->GetDriveFsInterface()) { OnDriveFsResponse(FILE_ERROR_SERVICE_UNAVAILABLE, "");
diff --git a/chrome/browser/chromeos/drive/drivefs_native_message_host_unittest.cc b/chrome/browser/chromeos/drive/drivefs_native_message_host_unittest.cc index c06d9ab..3b45624 100644 --- a/chrome/browser/chromeos/drive/drivefs_native_message_host_unittest.cc +++ b/chrome/browser/chromeos/drive/drivefs_native_message_host_unittest.cc
@@ -150,6 +150,7 @@ extension_port_.BindNewPipeAndPassReceiver(), receiver_.BindNewPipeAndPassRemote()); MockClient client; + EXPECT_CALL(*this, HandleMessageFromExtension).Times(0); EXPECT_CALL(client, PostMessageFromNativeHost).Times(0); EXPECT_CALL(client, CloseChannel("FILE_ERROR_FAILED: foo")); receiver_.set_disconnect_handler(run_loop.QuitClosure()); @@ -158,6 +159,9 @@ extension_port_.ResetWithReason(1u, "foo"); run_loop.Run(); + + host->OnMessage("bar"); + base::RunLoop().RunUntilIdle(); } class DriveFsNativeMessageHostTestWithoutFlag
diff --git a/chrome/browser/chromeos/extensions/device_local_account_management_policy_provider.cc b/chrome/browser/chromeos/extensions/device_local_account_management_policy_provider.cc index e9ec6a9..3d5fe45 100644 --- a/chrome/browser/chromeos/extensions/device_local_account_management_policy_provider.cc +++ b/chrome/browser/chromeos/extensions/device_local_account_management_policy_provider.cc
@@ -223,8 +223,8 @@ // Network access. emk::kSockets, - // Just provides dictionaries, no access to content. - emk::kSpellcheck, + // Deprecated manifest key. + // "spellcheck", // (Note: Using string literal since extensions::manifest_keys only has // constants for sub-keys.)
diff --git a/chrome/browser/chromeos/extensions/users_private/users_private_api.cc b/chrome/browser/chromeos/extensions/users_private/users_private_api.cc index 6cfc71f..89bb922e 100644 --- a/chrome/browser/chromeos/extensions/users_private/users_private_api.cc +++ b/chrome/browser/chromeos/extensions/users_private/users_private_api.cc
@@ -75,7 +75,7 @@ api_user.name = base::UTF16ToUTF8(user.GetDisplayName()); api_user.is_owner = user.GetAccountId() == user_manager::UserManager::Get()->GetOwnerAccountId(); - api_user.is_supervised = user.IsSupervised(); + api_user.is_supervised = user.IsChildOrDeprecatedSupervised(); api_user.is_child = user.IsChild(); return api_user; } @@ -128,7 +128,8 @@ for (size_t i = 0; i < email_list->GetSize(); ++i) { std::string email; email_list->GetString(i, &email); - if (user_manager->IsSupervisedAccountId(AccountId::FromUserEmail(email))) { + if (user_manager->IsDeprecatedSupervisedAccountId( + AccountId::FromUserEmail(email))) { email_list->Remove(i, nullptr); --i; }
diff --git a/chrome/browser/chromeos/first_run/first_run.cc b/chrome/browser/chromeos/first_run/first_run.cc index 69d29d1e..a652d8e 100644 --- a/chrome/browser/chromeos/first_run/first_run.cc +++ b/chrome/browser/chromeos/first_run/first_run.cc
@@ -67,7 +67,7 @@ bool IsRegularUserOrSupervisedChild(user_manager::UserManager* user_manager) { switch (user_manager->GetActiveUser()->GetType()) { case user_manager::USER_TYPE_REGULAR: - case user_manager::USER_TYPE_SUPERVISED: + case user_manager::USER_TYPE_SUPERVISED_DEPRECATED: case user_manager::USER_TYPE_CHILD: return true; default: @@ -85,7 +85,7 @@ return true; switch (user_manager->GetActiveUser()->GetType()) { case user_manager::USER_TYPE_REGULAR: - case user_manager::USER_TYPE_SUPERVISED: + case user_manager::USER_TYPE_SUPERVISED_DEPRECATED: return !profile->GetProfilePolicyConnector()->IsManaged(); default: return false;
diff --git a/chrome/browser/chromeos/login/chrome_restart_request.cc b/chrome/browser/chromeos/login/chrome_restart_request.cc index 698d996..06cbc5f 100644 --- a/chrome/browser/chromeos/login/chrome_restart_request.cc +++ b/chrome/browser/chromeos/login/chrome_restart_request.cc
@@ -152,13 +152,14 @@ ::switches::kDisableWebRtcHWEncoding, ::switches::kOzonePlatform, ash::switches::kAshClearFastInkBuffer, + ash::switches::kAshEnablePaletteOnAllDisplays, ash::switches::kAshEnableTabletMode, ash::switches::kAshEnableWaylandServer, ash::switches::kAshForceEnableStylusTools, - ash::switches::kAshEnablePaletteOnAllDisplays, ash::switches::kAshTouchHud, ash::switches::kAuraLegacyPowerButton, ash::switches::kEnableDimShelf, + ash::switches::kForceInTabletPhysicalState, ash::switches::kShowTaps, blink::switches::kBlinkSettings, blink::switches::kDarkModeSettings,
diff --git a/chrome/browser/chromeos/login/existing_user_controller.cc b/chrome/browser/chromeos/login/existing_user_controller.cc index e197778..9d660792 100644 --- a/chrome/browser/chromeos/login/existing_user_controller.cc +++ b/chrome/browser/chromeos/login/existing_user_controller.cc
@@ -481,7 +481,7 @@ if (user->IsKioskType()) continue; // TODO(xiyuan): Clean user profile whose email is not in allowlist. - if (user->GetType() == user_manager::USER_TYPE_SUPERVISED) + if (user->GetType() == user_manager::USER_TYPE_SUPERVISED_DEPRECATED) continue; const bool meets_allowlist_requirements = !user->HasGaiaAccount() || user_manager->IsGaiaUserAllowed(*user);
diff --git a/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc b/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc index c90d503..24feb50 100644 --- a/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc +++ b/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc
@@ -122,9 +122,7 @@ const char kManagedDomain[] = "example.com"; const char kUserAllowlist[] = "*@ad-domain.com"; const char kUserNotMatchingAllowlist[] = "user@another_mail.com"; -const char kSupervisedUserID[] = "supervised_user@locally-managed.localhost"; const char kPassword[] = "test_password"; -const char kHash[] = "test_hash"; const char kPublicSessionUserEmail[] = "public_session_user@localhost"; const char kPublicSessionSecondUserEmail[] = @@ -347,15 +345,6 @@ SigninSpecifics()); } -IN_PROC_BROWSER_TEST_F(ExistingUserControllerUntrustedTest, - SupervisedUserLoginForbidden) { - UserContext user_context(user_manager::UserType::USER_TYPE_SUPERVISED, - AccountId::FromUserEmail(kSupervisedUserID)); - user_context.SetKey(Key(kPassword)); - user_context.SetUserIDHash(kHash); - existing_user_controller()->Login(user_context, SigninSpecifics()); -} - MATCHER_P(HasDetails, expected, "") { return expected == *content::Details<const std::string>(arg).ptr(); }
diff --git a/chrome/browser/chromeos/login/login_ui_hide_supervised_users_browsertest.cc b/chrome/browser/chromeos/login/login_ui_hide_supervised_users_browsertest.cc index 14b19bc..1075ab5 100644 --- a/chrome/browser/chromeos/login/login_ui_hide_supervised_users_browsertest.cc +++ b/chrome/browser/chromeos/login/login_ui_hide_supervised_users_browsertest.cc
@@ -19,10 +19,10 @@ constexpr char kHistogramName[] = "ChromeOS.LegacySupervisedUsers.HiddenFromLoginScreen"; -const LoginManagerMixin::TestUserInfo kLegacySupervisedUser{ +const LoginManagerMixin::TestUserInfo kDeprecatedSupervisedUser{ AccountId::FromUserEmailGaiaId("test@locally-managed.localhost", "123456780"), - user_manager::USER_TYPE_SUPERVISED}; + user_manager::USER_TYPE_SUPERVISED_DEPRECATED}; const LoginManagerMixin::TestUserInfo kFamilyLinkUser{ AccountId::FromUserEmailGaiaId(test::kTestEmail, test::kTestGaiaId), @@ -38,11 +38,11 @@ protected: LoginManagerMixin login_mixin_{&mixin_host_, - {kLegacySupervisedUser, kFamilyLinkUser}}; + {kDeprecatedSupervisedUser, kFamilyLinkUser}}; base::HistogramTester histogram_tester_; }; -// Verifies that the login screen hides legacy supervised users and records +// Verifies that the login screen hides deprecated supervised users and records // metrics. IN_PROC_BROWSER_TEST_F(LoginUIHideSupervisedUsersTest, SupervisedUserHidden) { // Only the Gaia users should be displayed on the login screen. @@ -50,10 +50,10 @@ EXPECT_EQ(3u, user_manager::UserManager::Get()->GetUsers().size()); for (user_manager::User* user : user_manager::UserManager::Get()->GetUsers()) { - EXPECT_TRUE(!user->IsSupervised() || user->IsChild()); + EXPECT_TRUE(!user->IsChildOrDeprecatedSupervised() || user->IsChild()); } - // The login screen hid one legacy supervised user. + // The login screen hid one deprecated supervised user. histogram_tester_.ExpectBucketCount(kHistogramName, /*sample=*/true, /*expected_count=*/1); // The login screen displayed two regular users and one Family Link user.
diff --git a/chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.cc b/chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.cc index 5688756..3a015d2 100644 --- a/chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.cc +++ b/chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.cc
@@ -110,10 +110,12 @@ if (enable_for_testing_) return true; - // PIN is disabled for legacy supervised user, but allowed to child user. + // PIN is disabled for deprecated supervised user, but allowed to child user. user_manager::User* user = user_manager::UserManager::Get()->GetActiveUser(); - if (user && user->GetType() == user_manager::UserType::USER_TYPE_SUPERVISED) + if (user && user->GetType() == + user_manager::UserType::USER_TYPE_SUPERVISED_DEPRECATED) { return false; + } return true; }
diff --git a/chrome/browser/chromeos/login/screens/user_selection_screen.cc b/chrome/browser/chromeos/login/screens/user_selection_screen.cc index 15017c8..c10730ec 100644 --- a/chrome/browser/chromeos/login/screens/user_selection_screen.cc +++ b/chrome/browser/chromeos/login/screens/user_selection_screen.cc
@@ -531,15 +531,16 @@ base::DictionaryValue* user_dict) { const bool is_public_session = user->GetType() == user_manager::USER_TYPE_PUBLIC_ACCOUNT; - const bool is_legacy_supervised_user = - user->GetType() == user_manager::USER_TYPE_SUPERVISED; + const bool is_deprecated_supervised_user = + user->GetType() == user_manager::USER_TYPE_SUPERVISED_DEPRECATED; const bool is_child_user = user->GetType() == user_manager::USER_TYPE_CHILD; user_dict->SetString(kKeyUsername, user->GetAccountId().Serialize()); user_dict->SetString(kKeyEmailAddress, user->display_email()); user_dict->SetString(kKeyDisplayName, user->GetDisplayName()); user_dict->SetBoolean(kKeyPublicAccount, is_public_session); - user_dict->SetBoolean(kKeyLegacySupervisedUser, is_legacy_supervised_user); + user_dict->SetBoolean(kKeyLegacySupervisedUser, + is_deprecated_supervised_user); user_dict->SetBoolean(kKeyChildUser, is_child_user); user_dict->SetBoolean(kKeyDesktopUser, false); user_dict->SetInteger(kKeyInitialAuthType, static_cast<int>(auth_type)); @@ -587,7 +588,7 @@ return false; // Public sessions are always allowed to log in offline. - // Supervised users are always allowed to log in offline. + // Deprecated supervised users are always allowed to log in offline. // For all other users, force online sign in if: // * The flag to force online sign-in is set for the user. // * The user's OAuth token is invalid or unknown. @@ -596,13 +597,14 @@ const user_manager::User::OAuthTokenStatus token_status = user->oauth_token_status(); - const bool is_supervised_user = - user->GetType() == user_manager::USER_TYPE_SUPERVISED; + // TODO(crbug/1155729): Check if this bool is ever true. If not, remove it. + const bool is_deprecated_supervised_user = + user->GetType() == user_manager::USER_TYPE_SUPERVISED_DEPRECATED; const bool is_public_session = user->GetType() == user_manager::USER_TYPE_PUBLIC_ACCOUNT; const bool has_gaia_account = user->HasGaiaAccount(); - if (is_supervised_user) + if (is_deprecated_supervised_user) return false; if (is_public_session)
diff --git a/chrome/browser/chromeos/login/session/user_session_manager.cc b/chrome/browser/chromeos/login/session/user_session_manager.cc index 83d711d1..b4f1bcc 100644 --- a/chrome/browser/chromeos/login/session/user_session_manager.cc +++ b/chrome/browser/chromeos/login/session/user_session_manager.cc
@@ -1025,7 +1025,7 @@ for (auto* user : logged_in_users) { if (user->GetType() != user_manager::USER_TYPE_REGULAR && user->GetType() != user_manager::USER_TYPE_GUEST && - user->GetType() != user_manager::USER_TYPE_SUPERVISED && + user->GetType() != user_manager::USER_TYPE_SUPERVISED_DEPRECATED && user->GetType() != user_manager::USER_TYPE_CHILD) { continue; }
diff --git a/chrome/browser/chromeos/login/signin/auth_error_observer.cc b/chrome/browser/chromeos/login/signin/auth_error_observer.cc index 03310ce..d6177c9 100644 --- a/chrome/browser/chromeos/login/signin/auth_error_observer.cc +++ b/chrome/browser/chromeos/login/signin/auth_error_observer.cc
@@ -25,8 +25,9 @@ bool AuthErrorObserver::ShouldObserve(Profile* profile) { const user_manager::User* const user = ProfileHelper::Get()->GetUserByProfile(profile); - return user && (user->HasGaiaAccount() || - user->GetType() == user_manager::USER_TYPE_SUPERVISED); + return user && + (user->HasGaiaAccount() || + user->GetType() == user_manager::USER_TYPE_SUPERVISED_DEPRECATED); } AuthErrorObserver::AuthErrorObserver(Profile* profile) : profile_(profile) { @@ -80,7 +81,7 @@ const user_manager::User* const user = ProfileHelper::Get()->GetUserByProfile(profile_); DCHECK(user->HasGaiaAccount() || - user->GetType() == user_manager::USER_TYPE_SUPERVISED); + user->GetType() == user_manager::USER_TYPE_SUPERVISED_DEPRECATED); if (auth_error.IsPersistentError()) { // Invalidate OAuth2 refresh token to force Gaia sign-in flow. This is @@ -100,10 +101,6 @@ "token status."; user_manager::UserManager::Get()->SaveUserOAuthStatus( user->GetAccountId(), user_manager::User::OAUTH2_TOKEN_STATUS_VALID); - if (user->GetType() == user_manager::USER_TYPE_SUPERVISED) { - base::RecordAction( - base::UserMetricsAction("ManagedUsers_Chromeos_Sync_Recovered")); - } } } }
diff --git a/chrome/browser/chromeos/login/users/chrome_user_manager.cc b/chrome/browser/chromeos/login/users/chrome_user_manager.cc index d144d2c..32ef3b6 100644 --- a/chrome/browser/chromeos/login/users/chrome_user_manager.cc +++ b/chrome/browser/chromeos/login/users/chrome_user_manager.cc
@@ -97,8 +97,8 @@ return IsManagedSessionEnabledForUser(active_user) ? LoginState::LOGGED_IN_USER_PUBLIC_ACCOUNT_MANAGED : LoginState::LOGGED_IN_USER_PUBLIC_ACCOUNT; - case user_manager::USER_TYPE_SUPERVISED: - return LoginState::LOGGED_IN_USER_SUPERVISED; + case user_manager::USER_TYPE_SUPERVISED_DEPRECATED: + return LoginState::LOGGED_IN_USER_SUPERVISED_DEPRECATED; case user_manager::USER_TYPE_KIOSK_APP: return LoginState::LOGGED_IN_USER_KIOSK_APP; case user_manager::USER_TYPE_CHILD:
diff --git a/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc b/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc index f3021ef3..6358671 100644 --- a/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc +++ b/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc
@@ -1184,7 +1184,7 @@ const user_manager::User& user) const { DCHECK(user.GetType() == user_manager::USER_TYPE_REGULAR || user.GetType() == user_manager::USER_TYPE_GUEST || - user.GetType() == user_manager::USER_TYPE_SUPERVISED || + user.GetType() == user_manager::USER_TYPE_SUPERVISED_DEPRECATED || user.GetType() == user_manager::USER_TYPE_CHILD); return chrome_user_manager_util::IsUserAllowed( @@ -1367,7 +1367,7 @@ account_id == user_manager::StubAdAccountId(); } -bool ChromeUserManagerImpl::IsSupervisedAccountId( +bool ChromeUserManagerImpl::IsDeprecatedSupervisedAccountId( const AccountId& account_id) const { const policy::BrowserPolicyConnectorChromeOS* connector = g_browser_process->platform_part()->browser_policy_connector_chromeos();
diff --git a/chrome/browser/chromeos/login/users/chrome_user_manager_impl.h b/chrome/browser/chromeos/login/users/chrome_user_manager_impl.h index aff78c79..e7a2bbe 100644 --- a/chrome/browser/chromeos/login/users/chrome_user_manager_impl.h +++ b/chrome/browser/chromeos/login/users/chrome_user_manager_impl.h
@@ -104,7 +104,8 @@ void AsyncRemoveCryptohome(const AccountId& account_id) const override; bool IsGuestAccountId(const AccountId& account_id) const override; bool IsStubAccountId(const AccountId& account_id) const override; - bool IsSupervisedAccountId(const AccountId& account_id) const override; + bool IsDeprecatedSupervisedAccountId( + const AccountId& account_id) const override; bool HasBrowserRestarted() const override; const gfx::ImageSkia& GetResourceImagekiaNamed(int id) const override; base::string16 GetResourceStringUTF16(int string_id) const override;
diff --git a/chrome/browser/chromeos/login/users/chrome_user_manager_util.cc b/chrome/browser/chromeos/login/users/chrome_user_manager_util.cc index a36e055..87ca8aa7 100644 --- a/chrome/browser/chromeos/login/users/chrome_user_manager_util.cc +++ b/chrome/browser/chromeos/login/users/chrome_user_manager_util.cc
@@ -62,13 +62,13 @@ bool is_user_allowlisted) { DCHECK(user.GetType() == user_manager::USER_TYPE_REGULAR || user.GetType() == user_manager::USER_TYPE_GUEST || - user.GetType() == user_manager::USER_TYPE_SUPERVISED || + user.GetType() == user_manager::USER_TYPE_SUPERVISED_DEPRECATED || user.GetType() == user_manager::USER_TYPE_CHILD); if (user.GetType() == user_manager::USER_TYPE_GUEST && !is_guest_allowed) { return false; } - if (user.GetType() == user_manager::USER_TYPE_SUPERVISED) { + if (user.GetType() == user_manager::USER_TYPE_SUPERVISED_DEPRECATED) { return false; } if (user.HasGaiaAccount() && !is_user_allowlisted) {
diff --git a/chrome/browser/chromeos/login/users/chrome_user_manager_util.h b/chrome/browser/chromeos/login/users/chrome_user_manager_util.h index 6bd93b9..00ae5f5 100644 --- a/chrome/browser/chromeos/login/users/chrome_user_manager_util.h +++ b/chrome/browser/chromeos/login/users/chrome_user_manager_util.h
@@ -13,7 +13,7 @@ // Returns true if all `users` are allowed depending on the provided device // policies. Accepted user types: USER_TYPE_REGULAR, USER_TYPE_GUEST, -// USER_TYPE_SUPERVISED, USER_TYPE_CHILD. +// USER_TYPE_SUPERVISED_DEPRECATED, USER_TYPE_CHILD. // This function only checks against the device policies provided, so it does // not depend on CrosSettings or any other policy store. bool AreAllUsersAllowed(const user_manager::UserList& users, @@ -22,7 +22,7 @@ // Returns true if `user` is allowed, according to the given constraints. // Accepted user types: USER_TYPE_REGULAR, USER_TYPE_GUEST, -// USER_TYPE_SUPERVISED, USER_TYPE_CHILD. +// USER_TYPE_SUPERVISED_DEPRECATED, USER_TYPE_CHILD. bool IsUserAllowed(const user_manager::User& user, bool is_guest_allowed, bool is_user_allowlisted);
diff --git a/chrome/browser/chromeos/login/users/fake_chrome_user_manager.cc b/chrome/browser/chromeos/login/users/fake_chrome_user_manager.cc index a1e4f0c..f3c18cb6 100644 --- a/chrome/browser/chromeos/login/users/fake_chrome_user_manager.cc +++ b/chrome/browser/chromeos/login/users/fake_chrome_user_manager.cc
@@ -341,7 +341,7 @@ return account_id == user_manager::StubAccountId(); } -bool FakeChromeUserManager::IsSupervisedAccountId( +bool FakeChromeUserManager::IsDeprecatedSupervisedAccountId( const AccountId& account_id) const { const policy::BrowserPolicyConnectorChromeOS* connector = g_browser_process->platform_part()->browser_policy_connector_chromeos(); @@ -612,13 +612,13 @@ const user_manager::User& user) const { DCHECK(user.GetType() == user_manager::USER_TYPE_REGULAR || user.GetType() == user_manager::USER_TYPE_GUEST || - user.GetType() == user_manager::USER_TYPE_SUPERVISED || + user.GetType() == user_manager::USER_TYPE_SUPERVISED_DEPRECATED || user.GetType() == user_manager::USER_TYPE_CHILD); if (user.GetType() == user_manager::USER_TYPE_GUEST && !IsGuestSessionAllowed()) return false; - if (user.GetType() == user_manager::USER_TYPE_SUPERVISED) + if (user.GetType() == user_manager::USER_TYPE_SUPERVISED_DEPRECATED) return false; if (user.HasGaiaAccount() && !IsGaiaUserAllowed(user)) return false;
diff --git a/chrome/browser/chromeos/login/users/fake_chrome_user_manager.h b/chrome/browser/chromeos/login/users/fake_chrome_user_manager.h index cef8d2c..cccb79a1 100644 --- a/chrome/browser/chromeos/login/users/fake_chrome_user_manager.h +++ b/chrome/browser/chromeos/login/users/fake_chrome_user_manager.h
@@ -130,7 +130,8 @@ void AsyncRemoveCryptohome(const AccountId& account_id) const override; bool IsGuestAccountId(const AccountId& account_id) const override; bool IsStubAccountId(const AccountId& account_id) const override; - bool IsSupervisedAccountId(const AccountId& account_id) const override; + bool IsDeprecatedSupervisedAccountId( + const AccountId& account_id) const override; bool HasBrowserRestarted() const override; const gfx::ImageSkia& GetResourceImagekiaNamed(int id) const override; base::string16 GetResourceStringUTF16(int string_id) const override;
diff --git a/chrome/browser/chromeos/login/users/mock_user_manager.h b/chrome/browser/chromeos/login/users/mock_user_manager.h index 7e27199..7b61e99 100644 --- a/chrome/browser/chromeos/login/users/mock_user_manager.h +++ b/chrome/browser/chromeos/login/users/mock_user_manager.h
@@ -88,7 +88,7 @@ MOCK_CONST_METHOD0(IsFirstExecAfterBoot, bool(void)); MOCK_CONST_METHOD1(IsGuestAccountId, bool(const AccountId&)); MOCK_CONST_METHOD1(IsStubAccountId, bool(const AccountId&)); - MOCK_CONST_METHOD1(IsSupervisedAccountId, bool(const AccountId&)); + MOCK_CONST_METHOD1(IsDeprecatedSupervisedAccountId, bool(const AccountId&)); MOCK_CONST_METHOD0(HasBrowserRestarted, bool(void)); // UserManagerBase overrides:
diff --git a/chrome/browser/chromeos/policy/extension_install_event_log_collector.cc b/chrome/browser/chromeos/policy/extension_install_event_log_collector.cc index 1c137442..0aa6fe9 100644 --- a/chrome/browser/chromeos/policy/extension_install_event_log_collector.cc +++ b/chrome/browser/chromeos/policy/extension_install_event_log_collector.cc
@@ -149,8 +149,9 @@ return em::ExtensionInstallReportLogEvent::USER_TYPE_GUEST; case user_manager::USER_TYPE_PUBLIC_ACCOUNT: return em::ExtensionInstallReportLogEvent::USER_TYPE_PUBLIC_ACCOUNT; - case user_manager::USER_TYPE_SUPERVISED: - return em::ExtensionInstallReportLogEvent::USER_TYPE_SUPERVISED; + case user_manager::USER_TYPE_SUPERVISED_DEPRECATED: + return em::ExtensionInstallReportLogEvent:: + USER_TYPE_SUPERVISED_DEPRECATED; case user_manager::USER_TYPE_KIOSK_APP: return em::ExtensionInstallReportLogEvent::USER_TYPE_KIOSK_APP; case user_manager::USER_TYPE_CHILD:
diff --git a/chrome/browser/chromeos/policy/off_hours/device_off_hours_controller.cc b/chrome/browser/chromeos/policy/off_hours/device_off_hours_controller.cc index 05ee0a0b..7fd916e 100644 --- a/chrome/browser/chromeos/policy/off_hours/device_off_hours_controller.cc +++ b/chrome/browser/chromeos/policy/off_hours/device_off_hours_controller.cc
@@ -73,7 +73,7 @@ for (auto* user : logged_in_users) { if (user->GetType() == user_manager::USER_TYPE_REGULAR || user->GetType() == user_manager::USER_TYPE_GUEST || - user->GetType() == user_manager::USER_TYPE_SUPERVISED || + user->GetType() == user_manager::USER_TYPE_SUPERVISED_DEPRECATED || user->GetType() == user_manager::USER_TYPE_CHILD) { users_to_check.push_back(user); }
diff --git a/chrome/browser/chromeos/policy/user_policy_manager_builder_chromeos.cc b/chrome/browser/chromeos/policy/user_policy_manager_builder_chromeos.cc index c5815dd8..54c3464 100644 --- a/chrome/browser/chromeos/policy/user_policy_manager_builder_chromeos.cc +++ b/chrome/browser/chromeos/policy/user_policy_manager_builder_chromeos.cc
@@ -116,7 +116,7 @@ // |UserCloudPolicyManagerChromeOS| is created here. // All other user types do not have user policy. const AccountId& account_id = user->GetAccountId(); - if (user->GetType() == user_manager::USER_TYPE_SUPERVISED || + if (user->GetType() == user_manager::USER_TYPE_SUPERVISED_DEPRECATED || (user->GetType() != user_manager::USER_TYPE_CHILD && BrowserPolicyConnector::IsNonEnterpriseUser( account_id.GetUserEmail()))) {
diff --git a/chrome/browser/chromeos/power/ml/user_activity_manager_unittest.cc b/chrome/browser/chromeos/power/ml/user_activity_manager_unittest.cc index 0efcbd4..9cba5bc 100644 --- a/chrome/browser/chromeos/power/ml/user_activity_manager_unittest.cc +++ b/chrome/browser/chromeos/power/ml/user_activity_manager_unittest.cc
@@ -21,7 +21,6 @@ #include "chrome/browser/chromeos/power/ml/smart_dim/ml_agent.h" #include "chrome/browser/chromeos/power/ml/user_activity_event.pb.h" #include "chrome/browser/chromeos/power/ml/user_activity_ukm_logger.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/tabs/tab_activity_simulator.h" @@ -36,6 +35,7 @@ #include "chromeos/services/machine_learning/public/cpp/fake_service_connection.h" #include "chromeos/services/machine_learning/public/cpp/service_connection.h" #include "components/session_manager/session_manager_types.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "components/ukm/content/source_url_recorder.h" #include "components/ukm/test_ukm_recorder.h" #include "content/public/browser/web_contents.h"
diff --git a/chrome/browser/chromeos/system/timezone_util.cc b/chrome/browser/chromeos/system/timezone_util.cc index f29b0f41..18d804f1 100644 --- a/chrome/browser/chromeos/system/timezone_util.cc +++ b/chrome/browser/chromeos/system/timezone_util.cc
@@ -170,7 +170,7 @@ switch (user->GetType()) { case user_manager::USER_TYPE_REGULAR: - case user_manager::USER_TYPE_SUPERVISED: + case user_manager::USER_TYPE_SUPERVISED_DEPRECATED: case user_manager::USER_TYPE_KIOSK_APP: case user_manager::USER_TYPE_ARC_KIOSK_APP: case user_manager::USER_TYPE_ACTIVE_DIRECTORY:
diff --git a/chrome/browser/component_updater/registration.cc b/chrome/browser/component_updater/registration.cc index 4ef2087..2b17bd7 100644 --- a/chrome/browser/component_updater/registration.cc +++ b/chrome/browser/component_updater/registration.cc
@@ -21,7 +21,6 @@ #include "chrome/browser/component_updater/games_component_installer.h" #include "chrome/browser/component_updater/hyphenation_component_installer.h" #include "chrome/browser/component_updater/mei_preload_component_installer.h" -#include "chrome/browser/component_updater/optimization_hints_component_installer.h" #include "chrome/browser/component_updater/origin_trials_component_installer.h" #include "chrome/browser/component_updater/pepper_flash_component_installer.h" #include "chrome/browser/component_updater/ssl_error_assistant_component_installer.h" @@ -36,6 +35,7 @@ #include "components/component_updater/component_updater_service.h" #include "components/component_updater/crl_set_remover.h" #include "components/component_updater/installer_policies/on_device_head_suggest_component_installer.h" +#include "components/component_updater/installer_policies/optimization_hints_component_installer.h" #include "components/component_updater/installer_policies/safety_tips_component_installer.h" #include "components/nacl/common/buildflags.h" #include "device/vr/buildflags/buildflags.h" @@ -118,7 +118,7 @@ g_browser_process->floc_sorting_lsh_clusters_service()); RegisterOnDeviceHeadSuggestComponent( cus, g_browser_process->GetApplicationLocale()); - RegisterOptimizationHintsComponent(cus, is_off_the_record_profile); + RegisterOptimizationHintsComponent(cus); RegisterTrustTokenKeyCommitmentsComponentIfTrustTokensEnabled(cus); RegisterFirstPartySetsComponent(cus);
diff --git a/chrome/browser/content_index/content_index_provider_impl.cc b/chrome/browser/content_index/content_index_provider_impl.cc index 52014b7f..29ec5c9 100644 --- a/chrome/browser/content_index/content_index_provider_impl.cc +++ b/chrome/browser/content_index/content_index_provider_impl.cc
@@ -11,7 +11,6 @@ #include "base/strings/string_split.h" #include "base/task/post_task.h" #include "build/build_config.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/engagement/site_engagement_service_factory.h" #include "chrome/browser/metrics/ukm_background_recorder_service.h" #include "chrome/browser/offline_items_collection/offline_content_aggregator_factory.h" @@ -21,6 +20,7 @@ #include "components/offline_items_collection/core/offline_item.h" #include "components/offline_items_collection/core/update_delta.h" #include "components/site_engagement/content/site_engagement_score.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/content_index_context.h"
diff --git a/chrome/browser/content_index/content_index_provider_unittest.cc b/chrome/browser/content_index/content_index_provider_unittest.cc index 8208c26..36226811 100644 --- a/chrome/browser/content_index/content_index_provider_unittest.cc +++ b/chrome/browser/content_index/content_index_provider_unittest.cc
@@ -12,7 +12,6 @@ #include "base/run_loop.h" #include "base/test/bind.h" #include "base/time/time.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/engagement/site_engagement_service_factory.h" #include "chrome/browser/history/history_service_factory.h" #include "chrome/test/base/testing_profile.h" @@ -20,6 +19,7 @@ #include "components/history/core/browser/history_service.h" #include "components/history/core/test/test_history_database.h" #include "components/offline_items_collection/core/offline_content_provider.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/content_index_provider.h" #include "content/public/test/browser_task_environment.h"
diff --git a/chrome/browser/engagement/android/BUILD.gn b/chrome/browser/engagement/android/BUILD.gn index 719956e..ed6f5b6 100644 --- a/chrome/browser/engagement/android/BUILD.gn +++ b/chrome/browser/engagement/android/BUILD.gn
@@ -4,33 +4,18 @@ import("//build/config/android/rules.gni") -android_library("java") { - sources = [ "java/src/org/chromium/chrome/browser/engagement/SiteEngagementService.java" ] - deps = [ - ":jni_headers", - "//base:base_java", - "//base:jni_java", - "//chrome/browser/profiles/android:java", - ] - annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ] -} - android_library("javatests") { testonly = true sources = [ "java/src/org/chromium/chrome/browser/engagement/SiteEngagementServiceTest.java" ] deps = [ - ":java", "//base:base_java_test_support", "//chrome/android:chrome_java", "//chrome/browser/flags:java", "//chrome/browser/profiles/android:java", "//chrome/browser/tab:java", "//chrome/test/android:chrome_java_test_support", + "//components/site_engagement/content/android:java", "//third_party/android_deps:androidx_test_runner_java", "//third_party/junit:junit", ] } - -generate_jni("jni_headers") { - sources = [ "java/src/org/chromium/chrome/browser/engagement/SiteEngagementService.java" ] -}
diff --git a/chrome/browser/engagement/android/java/src/org/chromium/chrome/browser/engagement/SiteEngagementServiceTest.java b/chrome/browser/engagement/android/java/src/org/chromium/chrome/browser/engagement/SiteEngagementServiceTest.java index 229f89e7..a7cbfa0 100644 --- a/chrome/browser/engagement/android/java/src/org/chromium/chrome/browser/engagement/SiteEngagementServiceTest.java +++ b/chrome/browser/engagement/android/java/src/org/chromium/chrome/browser/engagement/SiteEngagementServiceTest.java
@@ -18,6 +18,7 @@ import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; +import org.chromium.components.site_engagement.SiteEngagementService; /** * Test for the Site Engagement Service Java binding.
diff --git a/chrome/browser/engagement/history_aware_site_engagement_service.h b/chrome/browser/engagement/history_aware_site_engagement_service.h index 28ef6f5..0f1b433 100644 --- a/chrome/browser/engagement/history_aware_site_engagement_service.h +++ b/chrome/browser/engagement/history_aware_site_engagement_service.h
@@ -8,9 +8,9 @@ #include <set> #include "base/scoped_observation.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "components/history/core/browser/history_service.h" #include "components/history/core/browser/history_service_observer.h" +#include "components/site_engagement/content/site_engagement_service.h" namespace content { class BrowserContext;
diff --git a/chrome/browser/engagement/important_sites_util.cc b/chrome/browser/engagement/important_sites_util.cc index d59b459f..ff8a55e 100644 --- a/chrome/browser/engagement/important_sites_util.cc +++ b/chrome/browser/engagement/important_sites_util.cc
@@ -18,7 +18,6 @@ #include "chrome/browser/banners/app_banner_settings_helper.h" #include "chrome/browser/bookmarks/bookmark_model_factory.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/installable/installable_utils.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/pref_names.h" @@ -30,6 +29,7 @@ #include "components/prefs/pref_service.h" #include "components/prefs/scoped_user_pref_update.h" #include "components/site_engagement/content/site_engagement_score.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "components/site_engagement/core/mojom/site_engagement_details.mojom.h" #include "net/base/registry_controlled_domains/registry_controlled_domain.h" #include "third_party/blink/public/mojom/site_engagement/site_engagement.mojom.h"
diff --git a/chrome/browser/engagement/important_sites_util_unittest.cc b/chrome/browser/engagement/important_sites_util_unittest.cc index 3490d94..0b1ef7d 100644 --- a/chrome/browser/engagement/important_sites_util_unittest.cc +++ b/chrome/browser/engagement/important_sites_util_unittest.cc
@@ -16,7 +16,6 @@ #include "build/build_config.h" #include "chrome/browser/bookmarks/bookmark_model_factory.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/history/history_service_factory.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h" #include "chrome/test/base/testing_profile.h" @@ -27,6 +26,7 @@ #include "components/content_settings/core/common/content_settings_pattern.h" #include "components/keyed_service/core/keyed_service.h" #include "components/site_engagement/content/site_engagement_score.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "content/public/browser/web_contents.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/engagement/site_engagement_helper.h b/chrome/browser/engagement/site_engagement_helper.h index 16f8d64..1bc870f 100644 --- a/chrome/browser/engagement/site_engagement_helper.h +++ b/chrome/browser/engagement/site_engagement_helper.h
@@ -9,7 +9,7 @@ #include "base/macros.h" #include "base/timer/timer.h" -#include "chrome/browser/engagement/site_engagement_service.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "content/public/browser/media_player_id.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_user_data.h"
diff --git a/chrome/browser/engagement/site_engagement_helper_unittest.cc b/chrome/browser/engagement/site_engagement_helper_unittest.cc index 8134641..56652e98 100644 --- a/chrome/browser/engagement/site_engagement_helper_unittest.cc +++ b/chrome/browser/engagement/site_engagement_helper_unittest.cc
@@ -8,13 +8,13 @@ #include "base/test/metrics/histogram_tester.h" #include "base/timer/mock_timer.h" #include "base/values.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/common/chrome_switches.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h" #include "chrome/test/base/testing_profile.h" #include "components/site_engagement/content/engagement_type.h" #include "components/site_engagement/content/site_engagement_metrics.h" #include "components/site_engagement/content/site_engagement_score.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/page_navigator.h" #include "content/public/browser/web_contents.h"
diff --git a/chrome/browser/engagement/site_engagement_service_factory.h b/chrome/browser/engagement/site_engagement_service_factory.h index 53d4177..a699263 100644 --- a/chrome/browser/engagement/site_engagement_service_factory.h +++ b/chrome/browser/engagement/site_engagement_service_factory.h
@@ -7,8 +7,8 @@ #include "base/macros.h" #include "base/memory/singleton.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "components/keyed_service/content/browser_context_keyed_service_factory.h" +#include "components/site_engagement/content/site_engagement_service.h" class Profile;
diff --git a/chrome/browser/engagement/site_engagement_service_unittest.cc b/chrome/browser/engagement/site_engagement_service_unittest.cc index 1775aae..d5970b96 100644 --- a/chrome/browser/engagement/site_engagement_service_unittest.cc +++ b/chrome/browser/engagement/site_engagement_service_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/engagement/site_engagement_service.h" +#include "components/site_engagement/content/site_engagement_service.h" #include <algorithm> #include <map> @@ -23,7 +23,6 @@ #include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/engagement/history_aware_site_engagement_service.h" #include "chrome/browser/engagement/site_engagement_helper.h" -#include "chrome/browser/engagement/site_engagement_observer.h" #include "chrome/browser/engagement/site_engagement_service_factory.h" #include "chrome/browser/history/history_service_factory.h" #include "chrome/common/chrome_switches.h" @@ -40,6 +39,7 @@ #include "components/prefs/pref_service.h" #include "components/site_engagement/content/engagement_type.h" #include "components/site_engagement/content/site_engagement_metrics.h" +#include "components/site_engagement/content/site_engagement_observer.h" #include "components/site_engagement/content/site_engagement_score.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h"
diff --git a/chrome/browser/extensions/BUILD.gn b/chrome/browser/extensions/BUILD.gn index 8c943ea..7ff55fa8 100644 --- a/chrome/browser/extensions/BUILD.gn +++ b/chrome/browser/extensions/BUILD.gn
@@ -342,8 +342,6 @@ "api/signed_in_devices/signed_in_devices_api.h", "api/signed_in_devices/signed_in_devices_manager.cc", "api/signed_in_devices/signed_in_devices_manager.h", - "api/spellcheck/spellcheck_api.cc", - "api/spellcheck/spellcheck_api.h", "api/storage/managed_value_store_cache.cc", "api/storage/managed_value_store_cache.h", "api/storage/policy_value_store.cc",
diff --git a/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.cc b/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.cc index 2be6cd6a..d844ae82 100644 --- a/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.cc +++ b/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.cc
@@ -1043,6 +1043,7 @@ auto* client = settings.per_profile ? profile_client_ : browser_client_; client->UploadSecurityEventReport( context_, + /* include_device_info */ !settings.per_profile, policy::RealtimeReportingJobConfiguration::BuildReport( std::move(event_list), reporting::GetContext(Profile::FromBrowserContext(context_))),
diff --git a/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router_unittest.cc b/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router_unittest.cc index c73893cd..55226593 100644 --- a/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router_unittest.cc +++ b/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router_unittest.cc
@@ -62,7 +62,7 @@ namespace { ACTION_P(CaptureArg, wrapper) { - *wrapper = arg1.Clone(); + *wrapper = arg2.Clone(); } constexpr char kConnectorsPrefValue[] = R"([ @@ -279,7 +279,7 @@ event_router_->AddEventObserver(&event_observer); base::Value report; - EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _)) + EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _, _)) .WillOnce(CaptureArg(&report)); TriggerOnPolicySpecifiedPasswordReuseDetectedEvent(); @@ -315,7 +315,7 @@ event_router_->AddEventObserver(&event_observer); base::Value report; - EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _)) + EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _, _)) .WillOnce(CaptureArg(&report)); TriggerOnPolicySpecifiedPasswordChangedEvent(); @@ -348,7 +348,7 @@ event_router_->AddEventObserver(&event_observer); base::Value report; - EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _)) + EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _, _)) .WillOnce(CaptureArg(&report)); TriggerOnDangerousDownloadOpenedEvent(); @@ -398,7 +398,7 @@ event_router_->AddEventObserver(&event_observer); base::Value report; - EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _)) + EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _, _)) .WillOnce(CaptureArg(&report)); TriggerOnSecurityInterstitialProceededEvent(); @@ -438,7 +438,7 @@ event_router_->AddEventObserver(&event_observer); base::Value report; - EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _)) + EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _, _)) .WillOnce(CaptureArg(&report)); TriggerOnSecurityInterstitialShownEvent(); @@ -478,7 +478,7 @@ event_router_->AddEventObserver(&event_observer); base::Value report; - EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _)) + EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _, _)) .WillOnce(CaptureArg(&report)); TriggerOnDangerousDownloadEvent(); @@ -520,7 +520,7 @@ event_router_->AddEventObserver(&event_observer); base::Value report; - EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _)) + EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _, _)) .WillOnce(CaptureArg(&report)); TriggerOnDangerousDownloadEventBypass(); @@ -560,7 +560,7 @@ api::safe_browsing_private::OnSecurityInterstitialShown::kEventName); event_router_->AddEventObserver(&event_observer); - EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _)).Times(1); + EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _, _)).Times(1); TriggerOnSecurityInterstitialShownEvent(); base::RunLoop().RunUntilIdle(); EXPECT_EQ(1u, event_observer.PassEventArgs().GetList().size()); @@ -568,7 +568,7 @@ // Now turn off policy. This time no report should be generated. SetReportingPolicy(false); - EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _)).Times(0); + EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _, _)).Times(0); TriggerOnSecurityInterstitialShownEvent(); base::RunLoop().RunUntilIdle(); EXPECT_EQ(1u, event_observer.PassEventArgs().GetList().size()); @@ -587,7 +587,7 @@ // Now turn on policy. SetReportingPolicy(true); - EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _)).Times(1); + EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _, _)).Times(1); TriggerOnSecurityInterstitialShownEvent(); base::RunLoop().RunUntilIdle(); EXPECT_EQ(1u, event_observer.PassEventArgs().GetList().size()); @@ -602,7 +602,7 @@ event_router_->AddEventObserver(&event_observer); base::Value report; - EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _)).Times(0); + EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _, _)).Times(0); TriggerOnPolicySpecifiedPasswordReuseDetectedEvent(); base::RunLoop().RunUntilIdle(); @@ -618,7 +618,7 @@ event_router_->AddEventObserver(&event_observer); base::Value report; - EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _)).Times(0); + EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _, _)).Times(0); TriggerOnPolicySpecifiedPasswordChangedEvent(); base::RunLoop().RunUntilIdle(); @@ -635,7 +635,7 @@ event_router_->AddEventObserver(&event_observer); base::Value report; - EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _)).Times(0); + EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _, _)).Times(0); TriggerOnDangerousDownloadOpenedEvent(); base::RunLoop().RunUntilIdle(); @@ -652,7 +652,7 @@ event_router_->AddEventObserver(&event_observer); base::Value report; - EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _)).Times(0); + EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _, _)).Times(0); TriggerOnSecurityInterstitialProceededEvent(); base::RunLoop().RunUntilIdle(); @@ -669,7 +669,7 @@ event_router_->AddEventObserver(&event_observer); base::Value report; - EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _)).Times(0); + EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _, _)).Times(0); TriggerOnSecurityInterstitialShownEvent(); base::RunLoop().RunUntilIdle(); @@ -686,7 +686,7 @@ event_router_->AddEventObserver(&event_observer); base::Value report; - EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _)).Times(0); + EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _, _)).Times(0); TriggerOnDangerousDownloadEvent(); base::RunLoop().RunUntilIdle(); @@ -703,7 +703,7 @@ event_router_->AddEventObserver(&event_observer); base::Value report; - EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _)).Times(0); + EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _, _)).Times(0); TriggerOnDangerousDownloadEventBypass(); base::RunLoop().RunUntilIdle(); @@ -716,7 +716,7 @@ SetUpRouters(/*realtime_reporting_enable=*/true, /*authorized=*/true); base::Value report; - EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _)) + EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _, _)) .WillOnce(CaptureArg(&report)); TriggerOnSensitiveDataEvent(safe_browsing::EventResult::ALLOWED); @@ -766,7 +766,7 @@ SetUpRouters(/*realtime_reporting_enable=*/true, /*authorized=*/true); base::Value report; - EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _)) + EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _, _)) .WillOnce(CaptureArg(&report)); TriggerOnSensitiveDataEvent(safe_browsing::EventResult::BLOCKED); @@ -816,7 +816,7 @@ SetUpRouters(/*realtime_reporting_enable=*/true, /*authorized=*/true); base::Value report; - EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _)) + EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _, _)) .WillOnce(CaptureArg(&report)); TriggerOnUnscannedFileEvent(safe_browsing::EventResult::ALLOWED); @@ -860,7 +860,7 @@ SetUpRouters(/*realtime_reporting_enable=*/true, /*authorized=*/true); base::Value report; - EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _)) + EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _, _)) .WillOnce(CaptureArg(&report)); TriggerOnUnscannedFileEvent(safe_browsing::EventResult::BLOCKED); @@ -911,7 +911,7 @@ ->SetIdentityManagerForTesting( identity_test_environment.identity_manager()); - EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _)) + EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _, _)) .WillRepeatedly(Return()); // With no primary account, we should not set the username. @@ -1043,13 +1043,13 @@ #endif if (should_report) { - EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _)).Times(1); + EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _, _)).Times(1); } else if (client_) { // Because the test will crate a |client_| object when the policy is // set, even if the feature flag or other conditions indicate that // reports should not be sent, it is possible that the pointer is not // null. In this case, make sure UploadSecurityEventReport() is not called. - EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _)).Times(0); + EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _, _)).Times(0); } TriggerOnPolicySpecifiedPasswordChangedEvent();
diff --git a/chrome/browser/extensions/api/spellcheck/spellcheck_api.cc b/chrome/browser/extensions/api/spellcheck/spellcheck_api.cc deleted file mode 100644 index 0ba0c2d..0000000 --- a/chrome/browser/extensions/api/spellcheck/spellcheck_api.cc +++ /dev/null
@@ -1,88 +0,0 @@ -// Copyright (c) 2012 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/extensions/api/spellcheck/spellcheck_api.h" - -#include "base/lazy_instance.h" -#include "chrome/browser/spellchecker/spellcheck_factory.h" -#include "chrome/browser/spellchecker/spellcheck_service.h" -#include "chrome/common/extensions/api/spellcheck/spellcheck_handler.h" -#include "extensions/common/manifest_constants.h" - -namespace extensions { - -namespace { - -SpellcheckDictionaryInfo* GetSpellcheckDictionaryInfo( - const Extension* extension) { - SpellcheckDictionaryInfo *spellcheck_info = - static_cast<SpellcheckDictionaryInfo*>( - extension->GetManifestData(manifest_keys::kSpellcheck)); - return spellcheck_info; -} - -SpellcheckService::DictionaryFormat GetDictionaryFormat( - const std::string& format) { - if (format == "hunspell") { - return SpellcheckService::DICT_HUNSPELL; - } else if (format == "text") { - return SpellcheckService::DICT_TEXT; - } else { - return SpellcheckService::DICT_UNKNOWN; - } -} - -} // namespace - -SpellcheckAPI::SpellcheckAPI(content::BrowserContext* context) { - extension_registry_observer_.Add(ExtensionRegistry::Get(context)); -} - -SpellcheckAPI::~SpellcheckAPI() = default; - -static base::LazyInstance<BrowserContextKeyedAPIFactory<SpellcheckAPI>>:: - DestructorAtExit g_spellcheck_api_factory = LAZY_INSTANCE_INITIALIZER; - -// static -BrowserContextKeyedAPIFactory<SpellcheckAPI>* -SpellcheckAPI::GetFactoryInstance() { - return g_spellcheck_api_factory.Pointer(); -} - -void SpellcheckAPI::OnExtensionLoaded(content::BrowserContext* browser_context, - const Extension* extension) { - SpellcheckDictionaryInfo* spellcheck_info = - GetSpellcheckDictionaryInfo(extension); - if (spellcheck_info) { - // TODO(rlp): Handle load failure. = - SpellcheckService* spellcheck = - SpellcheckServiceFactory::GetForContext(browser_context); - spellcheck->LoadExternalDictionary( - spellcheck_info->language, - spellcheck_info->locale, - spellcheck_info->path, - GetDictionaryFormat(spellcheck_info->format)); - } -} -void SpellcheckAPI::OnExtensionUnloaded( - content::BrowserContext* browser_context, - const Extension* extension, - UnloadedExtensionReason reason) { - SpellcheckDictionaryInfo* spellcheck_info = - GetSpellcheckDictionaryInfo(extension); - if (spellcheck_info) { - // TODO(rlp): Handle unload failure. - SpellcheckService* spellcheck = - SpellcheckServiceFactory::GetForContext(browser_context); - spellcheck->UnloadExternalDictionary(spellcheck_info->path); - } -} - -template <> -void -BrowserContextKeyedAPIFactory<SpellcheckAPI>::DeclareFactoryDependencies() { - DependsOn(SpellcheckServiceFactory::GetInstance()); -} - -} // namespace extensions
diff --git a/chrome/browser/extensions/api/spellcheck/spellcheck_api.h b/chrome/browser/extensions/api/spellcheck/spellcheck_api.h deleted file mode 100644 index b75884c6..0000000 --- a/chrome/browser/extensions/api/spellcheck/spellcheck_api.h +++ /dev/null
@@ -1,52 +0,0 @@ -// Copyright (c) 2013 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_EXTENSIONS_API_SPELLCHECK_SPELLCHECK_API_H_ -#define CHROME_BROWSER_EXTENSIONS_API_SPELLCHECK_SPELLCHECK_API_H_ - -#include "base/macros.h" -#include "base/scoped_observer.h" -#include "extensions/browser/browser_context_keyed_api_factory.h" -#include "extensions/browser/extension_registry.h" -#include "extensions/browser/extension_registry_observer.h" - -namespace extensions { - -class SpellcheckAPI : public BrowserContextKeyedAPI, - public ExtensionRegistryObserver { - public: - explicit SpellcheckAPI(content::BrowserContext* context); - ~SpellcheckAPI() override; - - // BrowserContextKeyedAPI implementation. - static BrowserContextKeyedAPIFactory<SpellcheckAPI>* GetFactoryInstance(); - - private: - friend class BrowserContextKeyedAPIFactory<SpellcheckAPI>; - - // ExtensionRegistryObserver implementation. - void OnExtensionLoaded(content::BrowserContext* browser_context, - const Extension* extension) override; - void OnExtensionUnloaded(content::BrowserContext* browser_context, - const Extension* extension, - UnloadedExtensionReason reason) override; - - // BrowserContextKeyedAPI implementation. - static const char* service_name() { - return "SpellcheckAPI"; - } - - // Listen to extension load, unloaded notifications. - ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver> - extension_registry_observer_{this}; - - DISALLOW_COPY_AND_ASSIGN(SpellcheckAPI); -}; - -template <> -void BrowserContextKeyedAPIFactory<SpellcheckAPI>::DeclareFactoryDependencies(); - -} // namespace extensions - -#endif // CHROME_BROWSER_EXTENSIONS_API_SPELLCHECK_SPELLCHECK_API_H_
diff --git a/chrome/browser/extensions/browser_context_keyed_service_factories.cc b/chrome/browser/extensions/browser_context_keyed_service_factories.cc index 7591f15..925218d 100644 --- a/chrome/browser/extensions/browser_context_keyed_service_factories.cc +++ b/chrome/browser/extensions/browser_context_keyed_service_factories.cc
@@ -49,7 +49,6 @@ #include "chrome/browser/extensions/warning_badge_service_factory.h" #include "chrome/browser/speech/extension_api/tts_extension_api.h" #include "chrome/common/buildflags.h" -#include "components/spellcheck/spellcheck_buildflags.h" #include "extensions/browser/api/bluetooth_low_energy/bluetooth_low_energy_api.h" #include "extensions/browser/api/networking_private/networking_private_delegate_factory.h" #include "ppapi/buildflags/buildflags.h" @@ -67,10 +66,6 @@ #include "chrome/browser/extensions/api/mdns/mdns_api.h" #endif -#if BUILDFLAG(ENABLE_SPELLCHECK) -#include "chrome/browser/extensions/api/spellcheck/spellcheck_api.h" -#endif - #if BUILDFLAG(ENABLE_AUTOFILL_ASSISTANT_API) #include "chrome/browser/extensions/api/autofill_assistant_private/autofill_assistant_private_api.h" #endif @@ -130,9 +125,6 @@ extensions::SettingsPrivateEventRouterFactory::GetInstance(); extensions::SettingsOverridesAPI::GetFactoryInstance(); extensions::SignedInDevicesManager::GetFactoryInstance(); -#if BUILDFLAG(ENABLE_SPELLCHECK) - extensions::SpellcheckAPI::GetFactoryInstance(); -#endif extensions::SystemIndicatorManagerFactory::GetInstance(); extensions::TabCaptureRegistry::GetFactoryInstance(); extensions::TabsWindowsAPI::GetFactoryInstance();
diff --git a/chrome/browser/extensions/forced_extensions/force_installed_metrics.cc b/chrome/browser/extensions/forced_extensions/force_installed_metrics.cc index ec61213..415f06b1 100644 --- a/chrome/browser/extensions/forced_extensions/force_installed_metrics.cc +++ b/chrome/browser/extensions/forced_extensions/force_installed_metrics.cc
@@ -61,8 +61,8 @@ return ForceInstalledMetrics::UserType::USER_TYPE_GUEST; case user_manager::USER_TYPE_PUBLIC_ACCOUNT: return ForceInstalledMetrics::UserType::USER_TYPE_PUBLIC_ACCOUNT; - case user_manager::USER_TYPE_SUPERVISED: - return ForceInstalledMetrics::UserType::USER_TYPE_SUPERVISED; + case user_manager::USER_TYPE_SUPERVISED_DEPRECATED: + return ForceInstalledMetrics::UserType::USER_TYPE_SUPERVISED_DEPRECATED; case user_manager::USER_TYPE_KIOSK_APP: return ForceInstalledMetrics::UserType::USER_TYPE_KIOSK_APP; case user_manager::USER_TYPE_CHILD:
diff --git a/chrome/browser/extensions/forced_extensions/force_installed_metrics.h b/chrome/browser/extensions/forced_extensions/force_installed_metrics.h index 06fe74f..10d46ea 100644 --- a/chrome/browser/extensions/forced_extensions/force_installed_metrics.h +++ b/chrome/browser/extensions/forced_extensions/force_installed_metrics.h
@@ -46,7 +46,9 @@ // Session with Regular new user, which has a user name and password. USER_TYPE_REGULAR_NEW = 2, USER_TYPE_PUBLIC_ACCOUNT = 3, - USER_TYPE_SUPERVISED = 4, + // TODO(crbug/1155729): Legacy supervised users are deprecated. Use + // USER_TYPE_CHILD instead. Remove this enum. + USER_TYPE_SUPERVISED_DEPRECATED = 4, USER_TYPE_KIOSK_APP = 5, USER_TYPE_CHILD = 6, USER_TYPE_ARC_KIOSK_APP = 7,
diff --git a/chrome/browser/federated_learning/floc_eligibility_browsertest.cc b/chrome/browser/federated_learning/floc_eligibility_browsertest.cc new file mode 100644 index 0000000..6ed725d9 --- /dev/null +++ b/chrome/browser/federated_learning/floc_eligibility_browsertest.cc
@@ -0,0 +1,246 @@ +// 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 "base/strings/strcat.h" +#include "base/test/bind.h" +#include "chrome/browser/federated_learning/floc_id_provider.h" +#include "chrome/browser/federated_learning/floc_id_provider_factory.h" +#include "chrome/browser/history/history_service_factory.h" +#include "chrome/browser/subresource_filter/subresource_filter_browser_test_harness.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/embedder_support/switches.h" +#include "components/history/core/browser/history_service.h" +#include "components/keyed_service/content/browser_context_dependency_manager.h" +#include "components/page_load_metrics/browser/page_load_metrics_test_waiter.h" +#include "components/subresource_filter/core/common/test_ruleset_utils.h" +#include "content/public/browser/navigation_handle.h" +#include "content/public/test/browser_test.h" +#include "content/public/test/browser_test_utils.h" +#include "content/public/test/test_frame_navigation_observer.h" +#include "content/public/test/test_host_resolver.h" +#include "content/public/test/test_navigation_observer.h" +#include "net/dns/mock_host_resolver.h" + +namespace { + +class FixedFlocIdProvider : public federated_learning::FlocIdProvider { + public: + FixedFlocIdProvider() = default; + ~FixedFlocIdProvider() override = default; + + std::string GetInterestCohortForJsApi( + const GURL& url, + const base::Optional<url::Origin>& top_frame_origin) const override { + return "12345.6.7.8.9"; + } +}; + +} // namespace + +class FlocEligibilityBrowserTest + : public subresource_filter::SubresourceFilterBrowserTest { + public: + void SetUpCommandLine(base::CommandLine* command_line) override { + command_line->AppendSwitchASCII(switches::kEnableBlinkFeatures, + "InterestCohortAPI"); + } + + // BrowserTestBase::SetUpInProcessBrowserTestFixture + void SetUpInProcessBrowserTestFixture() override { + subscription_ = + BrowserContextDependencyManager::GetInstance() + ->RegisterCreateServicesCallbackForTesting(base::BindRepeating( + &FlocEligibilityBrowserTest::OnWillCreateBrowserContextServices, + base::Unretained(this))); + } + + std::string InvokeInterestCohortJsApi( + const content::ToRenderFrameHost& adapter) { + return EvalJs(adapter, R"( + document.interestCohort() + .then(floc => floc) + .catch(error => 'rejected'); + )") + .ExtractString(); + } + + bool HistoryContainsUrlVisit(const GURL& url) { + return QueryUrl(url).success; + } + + bool IsUrlVisitEligibleToComputeFloc(const GURL& url) { + history::QueryURLResult result = QueryUrl(url); + EXPECT_EQ(1u, result.visits.size()); + return result.visits[0].floc_allowed; + } + + history::QueryURLResult QueryUrl(const GURL& url) { + history::QueryURLResult query_url_result; + + base::RunLoop run_loop; + base::CancelableTaskTracker tracker; + history_service()->QueryURL( + url, /*want_visits=*/true, + base::BindLambdaForTesting([&](history::QueryURLResult result) { + query_url_result = std::move(result); + run_loop.Quit(); + }), + &tracker); + run_loop.Run(); + + return query_url_result; + } + + void DeleteAllHistory() { + base::RunLoop run_loop; + base::CancelableTaskTracker tracker; + HistoryServiceFactory::GetForProfile(browser()->profile(), + ServiceAccessType::EXPLICIT_ACCESS) + ->ExpireHistoryBetween( + /*restrict_urls=*/{}, /*begin_time=*/base::Time(), + base::Time::Max(), + /*user_initiated=*/true, + base::BindLambdaForTesting([&]() { run_loop.Quit(); }), &tracker); + run_loop.Run(); + } + + content::WebContents* web_contents() { + return browser()->tab_strip_model()->GetActiveWebContents(); + } + + history::HistoryService* history_service() { + return HistoryServiceFactory::GetForProfile( + browser()->profile(), ServiceAccessType::IMPLICIT_ACCESS); + } + + void OnWillCreateBrowserContextServices(content::BrowserContext* context) { + federated_learning::FlocIdProviderFactory::GetInstance()->SetTestingFactory( + context, base::BindRepeating( + &FlocEligibilityBrowserTest::CreateFixedFlocIdProvider, + base::Unretained(this))); + } + + std::unique_ptr<KeyedService> CreateFixedFlocIdProvider( + content::BrowserContext* context) { + return std::make_unique<FixedFlocIdProvider>(); + } + + GURL NavigateToTestPage() { + auto waiter = + std::make_unique<page_load_metrics::PageLoadMetricsTestWaiter>( + web_contents()); + + GURL main_page_url(embedded_test_server()->GetURL( + "a.test", "/ad_tagging/frame_factory.html")); + + ui_test_utils::NavigateToURL(browser(), main_page_url); + + // Four resources in the main frame and one favicon. + waiter->AddMinimumCompleteResourcesExpectation(5); + waiter->Wait(); + + return main_page_url; + } + + protected: + base::CallbackListSubscription subscription_; +}; + +IN_PROC_BROWSER_TEST_F(FlocEligibilityBrowserTest, NotEligibleByDefault) { + net::IPAddress::ConsiderLoopbackIPToBePubliclyRoutableForTesting(); + + GURL main_page_url = NavigateToTestPage(); + + ASSERT_TRUE(HistoryContainsUrlVisit(main_page_url)); + + // Expect that the navigation history is not eligible for floc computation. + EXPECT_FALSE(IsUrlVisitEligibleToComputeFloc(main_page_url)); +} + +IN_PROC_BROWSER_TEST_F(FlocEligibilityBrowserTest, EligibleAfterAdResource) { + net::IPAddress::ConsiderLoopbackIPToBePubliclyRoutableForTesting(); + + SetRulesetWithRules( + {subresource_filter::testing::CreateSuffixRule("ad_script.js")}); + + GURL main_page_url = NavigateToTestPage(); + + // Expect that the navigation history is eligible for floc computation as the + // page contains an ad resource. + EXPECT_TRUE(IsUrlVisitEligibleToComputeFloc(main_page_url)); +} + +IN_PROC_BROWSER_TEST_F(FlocEligibilityBrowserTest, EligibleAfterApiCall) { + net::IPAddress::ConsiderLoopbackIPToBePubliclyRoutableForTesting(); + + GURL main_page_url = NavigateToTestPage(); + + ASSERT_TRUE(HistoryContainsUrlVisit(main_page_url)); + EXPECT_FALSE(IsUrlVisitEligibleToComputeFloc(main_page_url)); + + // Expect that the navigation history is eligible for floc computation after + // an API call. + EXPECT_EQ("12345.6.7.8.9", InvokeInterestCohortJsApi(web_contents())); + EXPECT_TRUE(IsUrlVisitEligibleToComputeFloc(main_page_url)); +} + +IN_PROC_BROWSER_TEST_F(FlocEligibilityBrowserTest, NotEligibleDueToPrivateIP) { + SetRulesetWithRules( + {subresource_filter::testing::CreateSuffixRule("ad_script.js")}); + + GURL main_page_url = NavigateToTestPage(); + + // Expect that the navigation history is not eligible for floc computation as + // the IP was not publicly routable. + EXPECT_FALSE(IsUrlVisitEligibleToComputeFloc(main_page_url)); +} + +IN_PROC_BROWSER_TEST_F(FlocEligibilityBrowserTest, NotEligibleSubframeHistory) { + net::IPAddress::ConsiderLoopbackIPToBePubliclyRoutableForTesting(); + + GURL main_page_url(embedded_test_server()->GetURL("a.test", "/iframe.html")); + GURL auto_subframe_url( + embedded_test_server()->GetURL("a.test", "/title1.html")); + + // Navigate to a page that contains an iframe ("title1.html"). + ui_test_utils::NavigateToURL(browser(), main_page_url); + + ASSERT_TRUE(HistoryContainsUrlVisit(main_page_url)); + ASSERT_FALSE(HistoryContainsUrlVisit(auto_subframe_url)); + + // Trigger an user-initiated navigation on the iframe, so that it will show up + // in history. + GURL manual_subframe_url( + embedded_test_server()->GetURL("a.test", "/title2.html")); + content::NavigateIframeToURL(web_contents(), + /*iframe_id=*/"test", manual_subframe_url); + ASSERT_TRUE(HistoryContainsUrlVisit(manual_subframe_url)); + + EXPECT_EQ("12345.6.7.8.9", InvokeInterestCohortJsApi(web_contents())); + EXPECT_EQ("12345.6.7.8.9", InvokeInterestCohortJsApi(content::ChildFrameAt( + web_contents()->GetMainFrame(), 0))); + + // Expect that only the main frame navigation history is eligible for floc + // computation. + EXPECT_TRUE(IsUrlVisitEligibleToComputeFloc(main_page_url)); + EXPECT_FALSE(IsUrlVisitEligibleToComputeFloc(manual_subframe_url)); +} + +IN_PROC_BROWSER_TEST_F(FlocEligibilityBrowserTest, + SettingFlocAllowedNoopOnDeletedHistory) { + net::IPAddress::ConsiderLoopbackIPToBePubliclyRoutableForTesting(); + + GURL main_page_url = NavigateToTestPage(); + + ASSERT_TRUE(HistoryContainsUrlVisit(main_page_url)); + + DeleteAllHistory(); + + // Expect that attempting to set the "floc allowed" bit will be a no-op if the + // page visit doesn't exist. + EXPECT_EQ("12345.6.7.8.9", InvokeInterestCohortJsApi(web_contents())); + ASSERT_FALSE(HistoryContainsUrlVisit(main_page_url)); +}
diff --git a/chrome/browser/federated_learning/floc_eligibility_observer.cc b/chrome/browser/federated_learning/floc_eligibility_observer.cc new file mode 100644 index 0000000..1528acf --- /dev/null +++ b/chrome/browser/federated_learning/floc_eligibility_observer.cc
@@ -0,0 +1,71 @@ +// 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/federated_learning/floc_eligibility_observer.h" + +#include "chrome/browser/history/history_service_factory.h" +#include "chrome/browser/profiles/profile.h" +#include "components/history/content/browser/history_context_helper.h" +#include "components/history/core/browser/history_service.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/navigation_entry.h" +#include "content/public/browser/web_contents.h" + +namespace federated_learning { + +FlocEligibilityObserver::~FlocEligibilityObserver() = default; + +page_load_metrics::PageLoadMetricsObserver::ObservePolicy +FlocEligibilityObserver::OnCommit( + content::NavigationHandle* navigation_handle) { + // At this point the add-page-to-history decision should have been made, + // because history is added in HistoryTabHelper::DidFinishNavigation, and this + // OnEligibleCommit method is invoked in the same broadcasting family through + // MetricsWebContentsObserver::DidFinishNavigation. + + // TODO(yaoxia): Perhaps we want an explicit signal for "the page was added + // to history or was ineligible". This way we don't need to count on the above + // relation, and can also stop observing if the history was not added. + + // If the IP was not publicly routable, the navigation history is not eligible + // for floc. We can stop observing now. + if (!navigation_handle->GetSocketAddress().address().IsPubliclyRoutable()) + return ObservePolicy::STOP_OBSERVING; + + DCHECK(!eligible_commit_); + eligible_commit_ = true; + + return ObservePolicy::CONTINUE_OBSERVING; +} + +void FlocEligibilityObserver::OnAdResource() { + MaybeSetFlocAllowedInHistory(); +} + +void FlocEligibilityObserver::OnInterestCohortApiUsed() { + MaybeSetFlocAllowedInHistory(); +} + +FlocEligibilityObserver::FlocEligibilityObserver(content::RenderFrameHost* rfh) + : web_contents_(content::WebContents::FromRenderFrameHost(rfh)) {} + +void FlocEligibilityObserver::MaybeSetFlocAllowedInHistory() { + if (!eligible_commit_ || did_set_floc_allowed_) + return; + + history::HistoryService* hs = HistoryServiceFactory::GetForProfile( + Profile::FromBrowserContext(web_contents_->GetBrowserContext()), + ServiceAccessType::IMPLICIT_ACCESS); + + hs->SetFlocAllowed( + history::ContextIDForWebContents(web_contents_), + web_contents_->GetController().GetLastCommittedEntry()->GetUniqueID(), + web_contents_->GetLastCommittedURL()); + + did_set_floc_allowed_ = true; +} + +RENDER_DOCUMENT_HOST_USER_DATA_KEY_IMPL(FlocEligibilityObserver) + +} // namespace federated_learning
diff --git a/chrome/browser/federated_learning/floc_eligibility_observer.h b/chrome/browser/federated_learning/floc_eligibility_observer.h new file mode 100644 index 0000000..f842fa71 --- /dev/null +++ b/chrome/browser/federated_learning/floc_eligibility_observer.h
@@ -0,0 +1,68 @@ +// 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_FEDERATED_LEARNING_FLOC_ELIGIBILITY_OBSERVER_H_ +#define CHROME_BROWSER_FEDERATED_LEARNING_FLOC_ELIGIBILITY_OBSERVER_H_ + +#include "components/page_load_metrics/browser/page_load_metrics_observer.h" +#include "content/public/browser/render_document_host_user_data.h" + +namespace content { +class WebContents; +} // namespace content + +namespace federated_learning { + +// This observer monitors page-level (i.e. main document) signals to determine +// whether the navigation's associated history entry is eligible for floc +// computation. The history entry is eligible for floc computation if all of the +// following conditions hold: +// 1) the IP of the navigation was publicly routable. +// 2) either the page has an ad resource, or the document.interestCohort API is +// used in the page. +// +// When the page is considered eligible for floc computation, a corresponding +// HistoryService API will be called to persistently set the eligibility bit. +class FlocEligibilityObserver + : public content::RenderDocumentHostUserData<FlocEligibilityObserver> { + public: + using ObservePolicy = + page_load_metrics::PageLoadMetricsObserver::ObservePolicy; + + ~FlocEligibilityObserver() override; + + // Called when the navigation has committed. Returns whether it should + // continue observing floc related signals. + ObservePolicy OnCommit(content::NavigationHandle* navigation_handle); + + // Called when an ad resource is seen in the page. + void OnAdResource(); + + // Called when the document.interestCohort API is used in the page. + void OnInterestCohortApiUsed(); + + private: + explicit FlocEligibilityObserver(content::RenderFrameHost* rfh); + + friend class content::RenderDocumentHostUserData<FlocEligibilityObserver>; + + void MaybeSetFlocAllowedInHistory(); + + content::WebContents* web_contents_; + + // |eligible_commit_| means all the commit time prerequisites are met + // (i.e. IP was publicly routable). It can only be set to true at commit time. + // When it's set, it also implies that the add-page-to-history decision has + // been made, i.e. either the page has been added to history, or has been + // skipped. + bool eligible_commit_ = false; + + bool did_set_floc_allowed_ = false; + + RENDER_DOCUMENT_HOST_USER_DATA_KEY_DECL(); +}; + +} // namespace federated_learning + +#endif // CHROME_BROWSER_FEDERATED_LEARNING_FLOC_ELIGIBILITY_OBSERVER_H_
diff --git a/chrome/browser/federated_learning/floc_eligibility_unittest.cc b/chrome/browser/federated_learning/floc_eligibility_unittest.cc new file mode 100644 index 0000000..3ecc3b9 --- /dev/null +++ b/chrome/browser/federated_learning/floc_eligibility_unittest.cc
@@ -0,0 +1,160 @@ +// 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 "base/test/bind.h" +#include "chrome/browser/federated_learning/floc_eligibility_observer.h" +#include "chrome/browser/history/history_service_factory.h" +#include "chrome/browser/page_load_metrics/observers/ad_metrics/floc_page_load_metrics_observer.h" +#include "chrome/test/base/chrome_render_view_host_test_harness.h" +#include "components/history/content/browser/history_context_helper.h" +#include "components/history/core/browser/history_service.h" +#include "components/page_load_metrics/browser/observers/page_load_metrics_observer_tester.h" +#include "components/page_load_metrics/browser/page_load_tracker.h" +#include "components/page_load_metrics/common/page_load_metrics.mojom.h" +#include "content/public/browser/navigation_entry.h" +#include "content/public/test/navigation_simulator.h" + +namespace federated_learning { + +class FlocEligibilityUnitTest : public ChromeRenderViewHostTestHarness { + public: + FlocEligibilityUnitTest() = default; + ~FlocEligibilityUnitTest() override = default; + + void SetUp() override { + ChromeRenderViewHostTestHarness::SetUp(); + ASSERT_TRUE(profile()->CreateHistoryService()); + + tester_ = + std::make_unique<page_load_metrics::PageLoadMetricsObserverTester>( + web_contents(), this, + base::BindRepeating(&FlocEligibilityUnitTest::RegisterObservers, + base::Unretained(this))); + } + + history::HistoryService* history_service() { + return HistoryServiceFactory::GetForProfile( + profile(), ServiceAccessType::EXPLICIT_ACCESS); + } + + bool IsUrlVisitEligibleToComputeFloc(const GURL& url) { + history::QueryURLResult result = QueryUrl(url); + EXPECT_EQ(1u, result.visits.size()); + return result.visits[0].floc_allowed; + } + + history::QueryURLResult QueryUrl(const GURL& url) { + history::QueryURLResult query_url_result; + + base::RunLoop run_loop; + base::CancelableTaskTracker tracker; + history_service()->QueryURL( + url, /*want_visits=*/true, + base::BindLambdaForTesting([&](history::QueryURLResult result) { + query_url_result = std::move(result); + run_loop.Quit(); + }), + &tracker); + run_loop.Run(); + + return query_url_result; + } + + void SimulateResourceDataUseUpdate(bool is_ad_resource) { + page_load_metrics::mojom::ResourceDataUpdatePtr resource = + page_load_metrics::mojom::ResourceDataUpdate::New(); + resource->reported_as_ad_resource = is_ad_resource; + resource->received_data_length = 1; + + std::vector<page_load_metrics::mojom::ResourceDataUpdatePtr> resources; + resources.push_back(std::move(resource)); + + tester_->SimulateResourceDataUseUpdate(resources, + web_contents()->GetMainFrame()); + } + + void NavigateToPage(const GURL& url, bool publicly_routable) { + auto simulator = content::NavigationSimulator::CreateBrowserInitiated( + url, web_contents()); + simulator->SetTransition(ui::PageTransition::PAGE_TRANSITION_TYPED); + + if (!publicly_routable) { + net::IPAddress address; + EXPECT_TRUE(address.AssignFromIPLiteral("0.0.0.0")); + simulator->SetSocketAddress(net::IPEndPoint(address, /*port=*/0)); + } + + simulator->Commit(); + + history_service()->AddPage( + url, base::Time::Now(), + history::ContextIDForWebContents(web_contents()), + web_contents()->GetController().GetLastCommittedEntry()->GetUniqueID(), + /*referrer=*/GURL(), + /*redirects=*/{}, ui::PageTransition::PAGE_TRANSITION_TYPED, + history::VisitSource::SOURCE_BROWSED, + /*did_replace_entry=*/false, + /*floc_allowed=*/false); + } + + FlocEligibilityObserver* GetFlocEligibilityObserver() { + return FlocEligibilityObserver::GetOrCreateForCurrentDocument( + web_contents()->GetMainFrame()); + } + + private: + void RegisterObservers(page_load_metrics::PageLoadTracker* tracker) { + auto floc_plm_observer = std::make_unique<FlocPageLoadMetricsObserver>(); + floc_plm_observer_ = floc_plm_observer.get(); + tracker->AddObserver(std::move(floc_plm_observer)); + } + + FlocPageLoadMetricsObserver* floc_plm_observer_; + std::unique_ptr<page_load_metrics::PageLoadMetricsObserverTester> tester_; +}; + +TEST_F(FlocEligibilityUnitTest, OnInterestCohortApiUsed) { + GURL url("https://foo.com"); + NavigateToPage(url, /*publicly_routable=*/true); + + EXPECT_FALSE(IsUrlVisitEligibleToComputeFloc(url)); + + GetFlocEligibilityObserver()->OnInterestCohortApiUsed(); + EXPECT_TRUE(IsUrlVisitEligibleToComputeFloc(url)); +} + +TEST_F(FlocEligibilityUnitTest, OnAdResourceObserved) { + GURL url("https://foo.com"); + NavigateToPage(url, /*publicly_routable=*/true); + + EXPECT_FALSE(IsUrlVisitEligibleToComputeFloc(url)); + + SimulateResourceDataUseUpdate(/*is_ad_resource=*/true); + EXPECT_TRUE(IsUrlVisitEligibleToComputeFloc(url)); +} + +TEST_F(FlocEligibilityUnitTest, OnNonAdResourceObserved) { + GURL url("https://foo.com"); + NavigateToPage(url, /*publicly_routable=*/true); + + EXPECT_FALSE(IsUrlVisitEligibleToComputeFloc(url)); + + SimulateResourceDataUseUpdate(/*is_ad_resource=*/false); + EXPECT_FALSE(IsUrlVisitEligibleToComputeFloc(url)); +} + +TEST_F(FlocEligibilityUnitTest, StopObservingPrivateIP) { + GURL url("https://foo.com"); + NavigateToPage(url, /*publicly_routable=*/false); + + EXPECT_FALSE(IsUrlVisitEligibleToComputeFloc(url)); + + SimulateResourceDataUseUpdate(/*is_ad_resource=*/true); + EXPECT_FALSE(IsUrlVisitEligibleToComputeFloc(url)); + + GetFlocEligibilityObserver()->OnInterestCohortApiUsed(); + EXPECT_FALSE(IsUrlVisitEligibleToComputeFloc(url)); +} + +} // namespace federated_learning
diff --git a/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.cc b/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.cc index 11459e1654a..b001aa3 100644 --- a/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.cc +++ b/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.cc
@@ -137,7 +137,7 @@ return "guest"; case user_manager::USER_TYPE_PUBLIC_ACCOUNT: return "public_account"; - case user_manager::USER_TYPE_SUPERVISED: + case user_manager::USER_TYPE_SUPERVISED_DEPRECATED: return "supervised"; case user_manager::USER_TYPE_KIOSK_APP: return "kiosk_app";
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 092abbea..f1df1d25 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -1067,7 +1067,7 @@ }, { "name": "dynamic-color-gamut", - "owners": [ "cblume", "khushalsagar", "ccameron" ], + "owners": [ "cblume", "ccameron" ], "expiry_milestone": 90 }, { @@ -1760,7 +1760,7 @@ }, { "name": "enable-image-reader", - "owners": [ "vikassoni", "khushalsagar" ], + "owners": [ "vikassoni", "liberato" ], "expiry_milestone": 90 }, { @@ -1993,12 +1993,12 @@ }, { "name": "enable-oop-rasterization", - "owners": [ "enne", "khushalsagar" ], + "owners": [ "sunnyps", "vasilyt" ], "expiry_milestone": 86 }, { "name": "enable-oop-rasterization-ddl", - "owners": [ "robertphillips", "khushalsagar" ], + "owners": [ "robertphillips", "penghuang" ], "expiry_milestone": 87 }, { @@ -2242,7 +2242,7 @@ }, { "name": "enable-surface-control", - "owners": [ "vikassoni", "khushalsagar" ], + "owners": [ "vikassoni", "vasilyt" ], "expiry_milestone": 90 }, { @@ -3528,11 +3528,6 @@ "expiry_milestone": 86 }, { - "name": "offline-pages-load-signal-collecting", - "owners": [ "sclittle", "srsudar", "offline-dev" ], - "expiry_milestone": 86 - }, - { "name": "offline-pages-pending-download", "owners": [ "sclittle", "srsudar", "offline-dev" ], "expiry_milestone": 76 @@ -3543,16 +3538,6 @@ "expiry_milestone": 76 }, { - "name": "offline-pages-renovations", - "owners": [ "sclittle", "srsudar", "offline-dev" ], - "expiry_milestone": 86 - }, - { - "name": "offline-pages-resource-based-snapshot", - "owners": [ "sclittle", "srsudar", "offline-dev" ], - "expiry_milestone": 86 - }, - { "name": "offlining-recent-pages", "owners": [ "sclittle", "srsudar", "offline-dev" ], "expiry_milestone": 76
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 8fdf87a..34cf6b2 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -2921,31 +2921,12 @@ "When enabled offline pages launched from the Downloads Home will be " "opened in Chrome Custom Tabs (CCT) instead of regular tabs."; -const char kOfflinePagesLoadSignalCollectingName[] = - "Enables collecting load timing data for offline page snapshots."; -const char kOfflinePagesLoadSignalCollectingDescription[] = - "Enables loading completeness data collection while writing an offline " - "page. This data is collected in the snapshotted offline page to allow " - "data analysis to improve deciding when to make the offline snapshot."; - const char kOfflinePagesPrefetchingName[] = "Enables suggested offline pages to be prefetched."; const char kOfflinePagesPrefetchingDescription[] = "Enables suggested offline pages to be prefetched, so useful content is " "available while offline."; -const char kOfflinePagesResourceBasedSnapshotName[] = - "Enables offline page snapshots to be based on percentage of page loaded."; -const char kOfflinePagesResourceBasedSnapshotDescription[] = - "Enables offline page snapshots to use a resource percentage based " - "approach for determining when the page is loaded as opposed to a time " - "based approach"; - -const char kOfflinePagesRenovationsName[] = "Enables offline page renovations."; -const char kOfflinePagesRenovationsDescription[] = - "Enables offline page renovations which correct issues with dynamic " - "content that occur when offlining pages that use JavaScript."; - const char kOfflinePagesLivePageSharingName[] = "Enables live page sharing of offline pages"; const char kOfflinePagesLivePageSharingDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index a887fc5..ea8bf99 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -1705,18 +1705,9 @@ extern const char kOfflinePagesInDownloadHomeOpenInCctName[]; extern const char kOfflinePagesInDownloadHomeOpenInCctDescription[]; -extern const char kOfflinePagesLoadSignalCollectingName[]; -extern const char kOfflinePagesLoadSignalCollectingDescription[]; - extern const char kOfflinePagesPrefetchingName[]; extern const char kOfflinePagesPrefetchingDescription[]; -extern const char kOfflinePagesResourceBasedSnapshotName[]; -extern const char kOfflinePagesResourceBasedSnapshotDescription[]; - -extern const char kOfflinePagesRenovationsName[]; -extern const char kOfflinePagesRenovationsDescription[]; - extern const char kOfflinePagesLivePageSharingName[]; extern const char kOfflinePagesLivePageSharingDescription[];
diff --git a/chrome/browser/history/history_tab_helper.cc b/chrome/browser/history/history_tab_helper.cc index 50ff785..10691cf 100644 --- a/chrome/browser/history/history_tab_helper.cc +++ b/chrome/browser/history/history_tab_helper.cc
@@ -96,18 +96,16 @@ page_transition); } - // In the future, this may encapsulate more conditions, e.g. page level - // opt-in, opt-out, etc. - bool floc_allowed = - navigation_handle->GetSocketAddress().address().IsPubliclyRoutable(); - + // Note: floc_allowed is set to false initially and is later updated by the + // floc eligibility observer. Eventually it will be removed from the history + // service API. history::HistoryAddPageArgs add_page_args( navigation_handle->GetURL(), timestamp, history::ContextIDForWebContents(web_contents()), nav_entry_id, navigation_handle->GetReferrer().url, navigation_handle->GetRedirectChain(), page_transition, hidden, history::SOURCE_BROWSED, navigation_handle->DidReplaceEntry(), - !content_suggestions_navigation, floc_allowed, + !content_suggestions_navigation, /*floc_allowed=*/false, navigation_handle->IsSameDocument() ? base::Optional<base::string16>( navigation_handle->GetWebContents()->GetTitle())
diff --git a/chrome/browser/history/top_sites_factory.cc b/chrome/browser/history/top_sites_factory.cc index 3829678e..6dbb94b 100644 --- a/chrome/browser/history/top_sites_factory.cc +++ b/chrome/browser/history/top_sites_factory.cc
@@ -15,7 +15,6 @@ #include "base/stl_util.h" #include "build/branding_buildflags.h" #include "build/build_config.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/engagement/site_engagement_service_factory.h" #include "chrome/browser/history/history_service_factory.h" #include "chrome/browser/history/history_utils.h" @@ -32,6 +31,7 @@ #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/pref_service.h" #include "components/search/ntp_features.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "components/strings/grit/components_strings.h" #include "content/public/browser/browser_thread.h" #include "ui/base/l10n/l10n_util.h"
diff --git a/chrome/browser/lookalikes/lookalike_url_navigation_throttle.cc b/chrome/browser/lookalikes/lookalike_url_navigation_throttle.cc index 39d36f8..ef249b1 100644 --- a/chrome/browser/lookalikes/lookalike_url_navigation_throttle.cc +++ b/chrome/browser/lookalikes/lookalike_url_navigation_throttle.cc
@@ -17,7 +17,6 @@ #include "base/metrics/histogram_macros.h" #include "base/stl_util.h" #include "base/strings/utf_string_conversions.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/lookalikes/lookalike_url_blocking_page.h" #include "chrome/browser/lookalikes/lookalike_url_controller_client.h" #include "chrome/browser/lookalikes/lookalike_url_service.h" @@ -30,6 +29,7 @@ #include "components/no_state_prefetch/browser/prerender_contents.h" #include "components/reputation/core/safety_tips_config.h" #include "components/security_interstitials/content/security_interstitial_tab_helper.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "components/ukm/content/source_url_recorder.h" #include "components/url_formatter/spoof_checks/top_domains/top500_domains.h" #include "components/url_formatter/spoof_checks/top_domains/top_domain_util.h"
diff --git a/chrome/browser/lookalikes/lookalike_url_navigation_throttle_browsertest.cc b/chrome/browser/lookalikes/lookalike_url_navigation_throttle_browsertest.cc index e4194e3..012646cd 100644 --- a/chrome/browser/lookalikes/lookalike_url_navigation_throttle_browsertest.cc +++ b/chrome/browser/lookalikes/lookalike_url_navigation_throttle_browsertest.cc
@@ -11,7 +11,6 @@ #include "base/test/scoped_feature_list.h" #include "base/test/simple_test_clock.h" #include "build/build_config.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/history/history_service_factory.h" #include "chrome/browser/history/history_test_utils.h" #include "chrome/browser/lookalikes/lookalike_url_blocking_page.h" @@ -33,6 +32,7 @@ #include "components/security_interstitials/content/security_interstitial_tab_helper.h" #include "components/security_interstitials/core/metrics_helper.h" #include "components/site_engagement/content/site_engagement_score.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "components/ukm/test_ukm_recorder.h" #include "content/public/browser/web_contents.h" #include "content/public/common/content_features.h"
diff --git a/chrome/browser/lookalikes/lookalike_url_service.cc b/chrome/browser/lookalikes/lookalike_url_service.cc index 72c67a66..01343e8 100644 --- a/chrome/browser/lookalikes/lookalike_url_service.cc +++ b/chrome/browser/lookalikes/lookalike_url_service.cc
@@ -15,7 +15,6 @@ #include "base/task/thread_pool.h" #include "base/time/default_clock.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/engagement/site_engagement_service_factory.h" #include "chrome/browser/profiles/incognito_helpers.h" #include "chrome/browser/profiles/profile.h" @@ -24,6 +23,7 @@ #include "components/keyed_service/content/browser_context_keyed_service_factory.h" #include "components/lookalikes/core/lookalike_url_util.h" #include "components/site_engagement/content/site_engagement_score.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "components/url_formatter/spoof_checks/top_domains/top_domain_util.h" #include "components/url_formatter/url_formatter.h" #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
diff --git a/chrome/browser/media/media_engagement_score_unittest.cc b/chrome/browser/media/media_engagement_score_unittest.cc index 0fc111d..ec35cf19 100644 --- a/chrome/browser/media/media_engagement_score_unittest.cc +++ b/chrome/browser/media/media_engagement_score_unittest.cc
@@ -13,11 +13,11 @@ #include "base/test/simple_test_clock.h" #include "base/values.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h" #include "chrome/test/base/testing_profile.h" #include "components/content_settings/core/browser/host_content_settings_map.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "media/base/media_switches.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h"
diff --git a/chrome/browser/notifications/persistent_notification_handler.cc b/chrome/browser/notifications/persistent_notification_handler.cc index 443fe4d69..6d5ba89 100644 --- a/chrome/browser/notifications/persistent_notification_handler.cc +++ b/chrome/browser/notifications/persistent_notification_handler.cc
@@ -8,7 +8,6 @@ #include "base/callback.h" #include "base/check_op.h" #include "base/metrics/histogram_macros.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/notifications/metrics/notification_metrics_logger.h" #include "chrome/browser/notifications/metrics/notification_metrics_logger_factory.h" #include "chrome/browser/notifications/notification_common.h" @@ -18,6 +17,7 @@ #include "chrome/browser/profiles/profile.h" #include "components/permissions/permission_uma_util.h" #include "components/permissions/permission_util.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/notification_event_dispatcher.h" #include "content/public/browser/permission_controller.h"
diff --git a/chrome/browser/notifications/platform_notification_service_interactive_uitest.cc b/chrome/browser/notifications/platform_notification_service_interactive_uitest.cc index 1c7fb14..13cfe98 100644 --- a/chrome/browser/notifications/platform_notification_service_interactive_uitest.cc +++ b/chrome/browser/notifications/platform_notification_service_interactive_uitest.cc
@@ -20,7 +20,6 @@ #include "base/time/time.h" #include "build/build_config.h" #include "build/chromeos_buildflags.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/notifications/notification_common.h" #include "chrome/browser/notifications/notification_display_service_impl.h" #include "chrome/browser/notifications/notification_display_service_tester.h" @@ -43,6 +42,7 @@ #include "components/permissions/permission_request_manager.h" #include "components/permissions/permission_result.h" #include "components/site_engagement/content/site_engagement_score.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "content/public/common/content_features.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h"
diff --git a/chrome/browser/offline_pages/background_loader_offliner.cc b/chrome/browser/offline_pages/background_loader_offliner.cc index 4b7b1d1d..97fdbd5 100644 --- a/chrome/browser/offline_pages/background_loader_offliner.cc +++ b/chrome/browser/offline_pages/background_loader_offliner.cc
@@ -24,15 +24,12 @@ #include "chrome/browser/ssl/security_state_tab_helper.h" #include "chrome/common/chrome_isolated_world_ids.h" #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_data.h" -#include "components/offline_pages/content/renovations/render_frame_script_injector.h" #include "components/offline_pages/core/background/offliner_policy.h" #include "components/offline_pages/core/background/save_page_request.h" #include "components/offline_pages/core/client_namespace_constants.h" #include "components/offline_pages/core/offline_page_client_policy.h" #include "components/offline_pages/core/offline_page_feature.h" #include "components/offline_pages/core/offline_page_model.h" -#include "components/offline_pages/core/renovations/page_renovation_loader.h" -#include "components/offline_pages/core/renovations/page_renovator.h" #include "components/previews/content/previews_user_data.h" #include "components/security_state/core/security_state.h" #include "content/public/browser/browser_context.h" @@ -49,10 +46,6 @@ namespace offline_pages { namespace { -const char kContentType[] = "text/plain"; -const char kContentTransferEncodingBinary[] = - "Content-Transfer-Encoding: binary"; -const char kXHeaderForSignals[] = "X-Chrome-Loading-Metrics-Data: 1"; std::string AddHistogramSuffix(const ClientId& client_id, const char* histogram_name) { @@ -171,26 +164,11 @@ completion_callback_ = std::move(completion_callback); progress_callback_ = progress_callback; - if (IsOfflinePagesRenovationsEnabled()) { - // Lazily create PageRenovationLoader - if (!page_renovation_loader_) - page_renovation_loader_ = std::make_unique<PageRenovationLoader>(); - - // Set up PageRenovator for this offlining instance. - auto script_injector = std::make_unique<RenderFrameScriptInjector>( - loader_->web_contents()->GetMainFrame(), - ISOLATED_WORLD_ID_CHROME_INTERNAL); - page_renovator_ = std::make_unique<PageRenovator>( - page_renovation_loader_.get(), std::move(script_injector), - request.url()); - } - // Load page attempt. loader_.get()->LoadPage(request.url()); snapshot_controller_ = std::make_unique<BackgroundSnapshotController>( - base::ThreadTaskRunnerHandle::Get(), this, - static_cast<bool>(page_renovator_)); + base::ThreadTaskRunnerHandle::Get(), this, false); return true; } @@ -437,41 +415,6 @@ save_state_ = SAVING; - // Capture loading signals to UMA. - RequestStats& image_stats = stats_[ResourceDataType::IMAGE]; - RequestStats& css_stats = stats_[ResourceDataType::TEXT_CSS]; - RequestStats& xhr_stats = stats_[ResourceDataType::XHR]; - - // Add loading signal into the MHTML that will be generated if the command - // line flag is set for it. - if (IsOfflinePagesLoadSignalCollectingEnabled()) { - // Write resource percentage signal data into extra data before emitting it - // to the MHTML. - signal_data_.SetDouble("StartedImages", image_stats.requested); - signal_data_.SetDouble("CompletedImages", image_stats.completed); - signal_data_.SetDouble("StartedCSS", css_stats.requested); - signal_data_.SetDouble("CompletedCSS", css_stats.completed); - signal_data_.SetDouble("StartedXHR", xhr_stats.requested); - signal_data_.SetDouble("CompletedXHR", xhr_stats.completed); - - // Stash loading signals for writing when we write out the MHTML. - std::string headers = base::StringPrintf( - "%s\r\n%s\r\n\r\n", kContentTransferEncodingBinary, kXHeaderForSignals); - std::string body; - base::JSONWriter::Write(signal_data_, &body); - std::string content_type = kContentType; - std::string content_location = base::StringPrintf( - "cid:signal-data-%" PRId64 "@mhtml.blink", request.request_id()); - - content::MHTMLExtraParts* extra_parts = - content::MHTMLExtraParts::FromWebContents(web_contents); - DCHECK(extra_parts); - if (extra_parts != nullptr) { - extra_parts->AddExtraMHTMLPart(content_type, content_location, headers, - body); - } - } - std::unique_ptr<OfflinePageArchiver> archiver(new OfflinePageMHTMLArchiver()); OfflinePageModel::SavePageParams params; @@ -495,14 +438,6 @@ weak_ptr_factory_.GetWeakPtr())); } -void BackgroundLoaderOffliner::RunRenovations() { - if (page_renovator_) { - page_renovator_->RunRenovations( - base::BindOnce(&BackgroundLoaderOffliner::RenovationsCompleted, - weak_ptr_factory_.GetWeakPtr())); - } -} - void BackgroundLoaderOffliner::OnPageSaved(SavePageResult save_result, int64_t offline_id) { if (!pending_request_)
diff --git a/chrome/browser/offline_pages/background_loader_offliner.h b/chrome/browser/offline_pages/background_loader_offliner.h index 8c96256..d353b02d 100644 --- a/chrome/browser/offline_pages/background_loader_offliner.h +++ b/chrome/browser/offline_pages/background_loader_offliner.h
@@ -30,7 +30,6 @@ class OfflinerPolicy; class OfflinePageModel; -class PageRenovationLoader; class PageRenovator; struct RequestStats { @@ -84,7 +83,6 @@ // BackgroundSnapshotController::Client implementation. void StartSnapshot() override; - void RunRenovations() override; void SetBackgroundSnapshotControllerForTest( std::unique_ptr<BackgroundSnapshotController> controller); @@ -170,11 +168,6 @@ // Whether we are on a low-end device. bool is_low_end_device_; - // PageRenovationLoader must live longer than the PageRenovator. - std::unique_ptr<PageRenovationLoader> page_renovation_loader_; - // Per-offliner PageRenovator instance. - std::unique_ptr<PageRenovator> page_renovator_; - // Save state. SaveState save_state_; // Page load state.
diff --git a/chrome/browser/offline_pages/background_loader_offliner_unittest.cc b/chrome/browser/offline_pages/background_loader_offliner_unittest.cc index 41bea3d..d1ef8f28 100644 --- a/chrome/browser/offline_pages/background_loader_offliner_unittest.cc +++ b/chrome/browser/offline_pages/background_loader_offliner_unittest.cc
@@ -968,9 +968,6 @@ } TEST_F(BackgroundLoaderOfflinerTest, SignalCollectionDisabled) { - // Ensure feature flag for Signal collection is off, - EXPECT_FALSE(offline_pages::IsOfflinePagesLoadSignalCollectingEnabled()); - base::Time creation_time = base::Time::Now(); SavePageRequest request(kRequestId, HttpUrl(), kClientId, creation_time, kUserRequested); @@ -980,75 +977,10 @@ CompleteLoading(); PumpLoop(); - // No extra parts should be added if the flag is off. + // No extra parts should be added. content::MHTMLExtraParts* extra_parts = content::MHTMLExtraParts::FromWebContents(offliner()->web_contents()); EXPECT_EQ(extra_parts->size(), 0); } -TEST_F(BackgroundLoaderOfflinerTest, SignalCollectionEnabled) { - // Ensure feature flag for signal collection is on. - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature( - kOfflinePagesLoadSignalCollectingFeature); - EXPECT_TRUE(IsOfflinePagesLoadSignalCollectingEnabled()); - - base::Time creation_time = base::Time::Now(); - SavePageRequest request(kRequestId, HttpUrl(), kClientId, creation_time, - kUserRequested); - EXPECT_TRUE(offliner()->LoadAndSave(request, completion_callback(), - progress_callback())); - - CompleteLoading(); - PumpLoop(); - - // One extra part should be added if the flag is on. - content::MHTMLExtraParts* extra_parts = - content::MHTMLExtraParts::FromWebContents(offliner()->web_contents()); - EXPECT_EQ(extra_parts->size(), 1); -} - -TEST_F(BackgroundLoaderOfflinerTest, ResourceSignalCollection) { - // Ensure feature flag for signal collection is on. - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature( - kOfflinePagesLoadSignalCollectingFeature); - EXPECT_TRUE(IsOfflinePagesLoadSignalCollectingEnabled()); - - base::Time creation_time = base::Time::Now(); - SavePageRequest request(kRequestId, HttpUrl(), kClientId, creation_time, - kUserRequested); - EXPECT_TRUE(offliner()->LoadAndSave(request, completion_callback(), - progress_callback())); - - // Simulate resource requests starting and completing - offliner()->ObserveResourceLoading( - ResourceLoadingObserver::ResourceDataType::IMAGE, true); - offliner()->ObserveResourceLoading( - ResourceLoadingObserver::ResourceDataType::IMAGE, false); - offliner()->ObserveResourceLoading( - ResourceLoadingObserver::ResourceDataType::TEXT_CSS, true); - offliner()->ObserveResourceLoading( - ResourceLoadingObserver::ResourceDataType::TEXT_CSS, true); - offliner()->ObserveResourceLoading( - ResourceLoadingObserver::ResourceDataType::XHR, true); - - CompleteLoading(); - PumpLoop(); - - // One extra part should be added if the flag is on. - content::MHTMLExtraParts* extra_parts = - content::MHTMLExtraParts::FromWebContents(offliner()->web_contents()); - EXPECT_EQ(extra_parts->size(), 1); - - offline_pages::RequestStats* stats = GetRequestStats(); - EXPECT_EQ(1, - stats[ResourceLoadingObserver::ResourceDataType::IMAGE].requested); - EXPECT_EQ(1, - stats[ResourceLoadingObserver::ResourceDataType::IMAGE].completed); - EXPECT_EQ( - 2, stats[ResourceLoadingObserver::ResourceDataType::TEXT_CSS].requested); - EXPECT_EQ(1, stats[ResourceLoadingObserver::ResourceDataType::XHR].requested); -} - } // namespace offline_pages
diff --git a/chrome/browser/optimization_guide/android/optimization_guide_bridge_unittest.cc b/chrome/browser/optimization_guide/android/optimization_guide_bridge_unittest.cc index ee11d5b..b1be12f1 100644 --- a/chrome/browser/optimization_guide/android/optimization_guide_bridge_unittest.cc +++ b/chrome/browser/optimization_guide/android/optimization_guide_bridge_unittest.cc
@@ -16,7 +16,6 @@ #include "chrome/test/base/testing_profile.h" #include "chrome/test/base/testing_profile_manager.h" #include "components/optimization_guide/core/optimization_guide_prefs.h" -#include "components/optimization_guide/core/optimization_guide_service.h" #include "components/prefs/pref_service.h" #include "components/prefs/testing_pref_service.h" #include "content/public/test/browser_task_environment.h" @@ -34,12 +33,8 @@ class MockOptimizationGuideHintsManager : public OptimizationGuideHintsManager { public: - MockOptimizationGuideHintsManager( - optimization_guide::OptimizationGuideService* optimization_guide_service, - Profile* profile, - PrefService* pref_service) - : OptimizationGuideHintsManager(optimization_guide_service, - profile, + MockOptimizationGuideHintsManager(Profile* profile, PrefService* pref_service) + : OptimizationGuideHintsManager(profile, pref_service, /*hint_store=*/nullptr, /*top_host_provider=*/nullptr, @@ -91,18 +86,14 @@ return std::make_unique< MockOptimizationGuideKeyedService>(context); }))); - optimization_guide_service_ = - std::make_unique<optimization_guide::OptimizationGuideService>( - task_environment_.GetMainThreadTaskRunner()); optimization_guide_hints_manager_ = std::make_unique<MockOptimizationGuideHintsManager>( - optimization_guide_service_.get(), profile_, pref_service_.get()); + profile_, pref_service_.get()); } void TearDown() override { optimization_guide_hints_manager_->Shutdown(); optimization_guide_hints_manager_.reset(); - optimization_guide_service_.reset(); } void RegisterOptimizationTypes() { @@ -123,8 +114,6 @@ base::test::TaskEnvironment::MainThreadType::UI}; TestingProfileManager profile_manager_; TestingProfile* profile_; - std::unique_ptr<optimization_guide::OptimizationGuideService> - optimization_guide_service_; base::ScopedTempDir temp_dir_; std::unique_ptr<TestingPrefServiceSimple> pref_service_; };
diff --git a/chrome/browser/optimization_guide/hints_fetcher_browsertest.cc b/chrome/browser/optimization_guide/hints_fetcher_browsertest.cc index b026f6d..17579ca5 100644 --- a/chrome/browser/optimization_guide/hints_fetcher_browsertest.cc +++ b/chrome/browser/optimization_guide/hints_fetcher_browsertest.cc
@@ -18,7 +18,6 @@ #include "build/build_config.h" #include "build/chromeos_buildflags.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/optimization_guide/optimization_guide_keyed_service.h" #include "chrome/browser/optimization_guide/optimization_guide_keyed_service_factory.h" #include "chrome/browser/profiles/profile.h" @@ -34,13 +33,14 @@ #include "components/optimization_guide/core/optimization_guide_enums.h" #include "components/optimization_guide/core/optimization_guide_features.h" #include "components/optimization_guide/core/optimization_guide_prefs.h" -#include "components/optimization_guide/core/optimization_guide_service.h" #include "components/optimization_guide/core/optimization_guide_store.h" #include "components/optimization_guide/core/optimization_guide_switches.h" +#include "components/optimization_guide/core/optimization_hints_component_update_listener.h" #include "components/optimization_guide/core/test_hints_component_creator.h" #include "components/optimization_guide/core/top_host_provider.h" #include "components/optimization_guide/proto/hints.pb.h" #include "components/prefs/pref_service.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "components/ukm/test_ukm_recorder.h" #include "components/variations/hashing.h" #include "content/public/browser/browser_task_traits.h" @@ -210,8 +210,8 @@ base::HistogramTester histogram_tester; - g_browser_process->optimization_guide_service()->MaybeUpdateHintsComponent( - component_info); + optimization_guide::OptimizationHintsComponentUpdateListener::GetInstance() + ->MaybeUpdateHintsComponent(component_info); RetryForHistogramUntilCountReached( &histogram_tester,
diff --git a/chrome/browser/optimization_guide/optimization_guide_hints_manager.cc b/chrome/browser/optimization_guide/optimization_guide_hints_manager.cc index 4f9c11c1..847f852b 100644 --- a/chrome/browser/optimization_guide/optimization_guide_hints_manager.cc +++ b/chrome/browser/optimization_guide/optimization_guide_hints_manager.cc
@@ -40,10 +40,10 @@ #include "components/optimization_guide/core/optimization_guide_enums.h" #include "components/optimization_guide/core/optimization_guide_features.h" #include "components/optimization_guide/core/optimization_guide_prefs.h" -#include "components/optimization_guide/core/optimization_guide_service.h" #include "components/optimization_guide/core/optimization_guide_store.h" #include "components/optimization_guide/core/optimization_guide_switches.h" #include "components/optimization_guide/core/optimization_guide_util.h" +#include "components/optimization_guide/core/optimization_hints_component_update_listener.h" #include "components/optimization_guide/core/optimization_metadata.h" #include "components/optimization_guide/core/top_host_provider.h" #include "components/optimization_guide/proto/models.pb.h" @@ -61,8 +61,8 @@ namespace { // The component version used with a manual config. This ensures that any hint -// component received from the OptimizationGuideService on a subsequent startup -// will have a newer version than it. +// component received from the Optimization Hints component on a subsequent +// startup will have a newer version than it. constexpr char kManualConfigComponentVersion[] = "0.0.0"; // Delay until successfully fetched hints should be updated by requesting from @@ -252,14 +252,12 @@ } // namespace OptimizationGuideHintsManager::OptimizationGuideHintsManager( - optimization_guide::OptimizationGuideService* optimization_guide_service, Profile* profile, PrefService* pref_service, optimization_guide::OptimizationGuideStore* hint_store, optimization_guide::TopHostProvider* top_host_provider, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) - : optimization_guide_service_(optimization_guide_service), - background_task_runner_(base::ThreadPool::CreateSequencedTaskRunner( + : background_task_runner_(base::ThreadPool::CreateSequencedTaskRunner( {base::MayBlock(), base::TaskPriority::BEST_EFFORT})), profile_(profile), pref_service_(pref_service), @@ -300,8 +298,8 @@ } void OptimizationGuideHintsManager::Shutdown() { - if (optimization_guide_service_) - optimization_guide_service_->RemoveObserver(this); + optimization_guide::OptimizationHintsComponentUpdateListener::GetInstance() + ->RemoveObserver(this); g_browser_process->network_quality_tracker() ->RemoveEffectiveConnectionTypeObserver(this); @@ -563,8 +561,8 @@ // Register as an observer regardless of hint proto override usage. This is // needed as a signal during testing. - if (optimization_guide_service_) - optimization_guide_service_->AddObserver(this); + optimization_guide::OptimizationHintsComponentUpdateListener::GetInstance() + ->AddObserver(this); } void OptimizationGuideHintsManager::UpdateComponentHints(
diff --git a/chrome/browser/optimization_guide/optimization_guide_hints_manager.h b/chrome/browser/optimization_guide/optimization_guide_hints_manager.h index 7ec386e..412cdba 100644 --- a/chrome/browser/optimization_guide/optimization_guide_hints_manager.h +++ b/chrome/browser/optimization_guide/optimization_guide_hints_manager.h
@@ -25,7 +25,7 @@ #include "components/optimization_guide/content/optimization_guide_decider.h" #include "components/optimization_guide/core/hints_component_info.h" #include "components/optimization_guide/core/hints_fetcher.h" -#include "components/optimization_guide/core/optimization_guide_service_observer.h" +#include "components/optimization_guide/core/optimization_hints_component_observer.h" #include "components/optimization_guide/proto/hints.pb.h" #include "components/optimization_guide/proto/models.pb.h" #include "net/nqe/effective_connection_type.h" @@ -44,7 +44,6 @@ class HintsFetcherFactory; class OptimizationFilter; class OptimizationMetadata; -class OptimizationGuideService; class OptimizationGuideStore; enum class OptimizationTargetDecision; enum class OptimizationTypeDecision; @@ -57,12 +56,11 @@ class Profile; class OptimizationGuideHintsManager - : public optimization_guide::OptimizationGuideServiceObserver, + : public optimization_guide::OptimizationHintsComponentObserver, public network::NetworkQualityTracker::EffectiveConnectionTypeObserver, public NavigationPredictorKeyedService::Observer { public: OptimizationGuideHintsManager( - optimization_guide::OptimizationGuideService* optimization_guide_service, Profile* profile, PrefService* pref_service, optimization_guide::OptimizationGuideStore* hint_store, @@ -79,7 +77,7 @@ GetOptimizationGuideDecisionFromOptimizationTypeDecision( optimization_guide::OptimizationTypeDecision optimization_type_decision); - // optimization_guide::OptimizationGuideServiceObserver implementation: + // optimization_guide::OptimizationHintsComponentObserver implementation: void OnHintsComponentAvailable( const optimization_guide::HintsComponentInfo& info) override; @@ -377,10 +375,6 @@ const GURL& navigation_url, optimization_guide::proto::OptimizationType optimization_type); - // The OptimizationGuideService that this guide is listening to. Not owned. - optimization_guide::OptimizationGuideService* const - optimization_guide_service_; - // The information of the latest component delivered by // |optimization_guide_service_|. base::Optional<optimization_guide::HintsComponentInfo> hints_component_info_;
diff --git a/chrome/browser/optimization_guide/optimization_guide_hints_manager_unittest.cc b/chrome/browser/optimization_guide/optimization_guide_hints_manager_unittest.cc index 9794ceda..e900839c 100644 --- a/chrome/browser/optimization_guide/optimization_guide_hints_manager_unittest.cc +++ b/chrome/browser/optimization_guide/optimization_guide_hints_manager_unittest.cc
@@ -29,7 +29,6 @@ #include "components/optimization_guide/core/optimization_guide_enums.h" #include "components/optimization_guide/core/optimization_guide_features.h" #include "components/optimization_guide/core/optimization_guide_prefs.h" -#include "components/optimization_guide/core/optimization_guide_service.h" #include "components/optimization_guide/core/optimization_guide_store.h" #include "components/optimization_guide/core/optimization_guide_switches.h" #include "components/optimization_guide/core/proto_database_provider_test_base.h" @@ -126,33 +125,6 @@ } // namespace -class TestOptimizationGuideService - : public optimization_guide::OptimizationGuideService { - public: - explicit TestOptimizationGuideService( - const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner) - : OptimizationGuideService(ui_task_runner) {} - - ~TestOptimizationGuideService() override = default; - - void AddObserver( - optimization_guide::OptimizationGuideServiceObserver* observer) override { - add_observer_called_ = true; - } - - void RemoveObserver( - optimization_guide::OptimizationGuideServiceObserver* observer) override { - remove_observer_called_ = true; - } - - bool AddObserverCalled() const { return add_observer_called_; } - bool RemoveObserverCalled() const { return remove_observer_called_; } - - private: - bool add_observer_called_ = false; - bool remove_observer_called_ = false; -}; - // A mock class implementation of TopHostProvider. class FakeTopHostProvider : public optimization_guide::TopHostProvider { public: @@ -285,7 +257,7 @@ void SetUp() override { optimization_guide::ProtoDatabaseProviderTestBase::SetUp(); web_contents_factory_ = std::make_unique<content::TestWebContentsFactory>(); - CreateServiceAndHintsManager(/*top_host_provider=*/nullptr); + CreateHintsManager(/*top_host_provider=*/nullptr); } void TearDown() override { @@ -293,14 +265,11 @@ ResetHintsManager(); } - void CreateServiceAndHintsManager( + void CreateHintsManager( optimization_guide::TopHostProvider* top_host_provider) { if (hints_manager_) { ResetHintsManager(); } - optimization_guide_service_ = - std::make_unique<TestOptimizationGuideService>( - task_environment_.GetMainThreadTaskRunner()); pref_service_ = std::make_unique<TestingPrefServiceSimple>(); optimization_guide::prefs::RegisterProfilePrefs(pref_service_->registry()); @@ -311,18 +280,15 @@ hint_store_ = std::make_unique<optimization_guide::OptimizationGuideStore>( db_provider_.get(), temp_dir(), task_environment_.GetMainThreadTaskRunner()); + hints_manager_ = std::make_unique<OptimizationGuideHintsManager>( - optimization_guide_service_.get(), &testing_profile_, - pref_service_.get(), hint_store_.get(), top_host_provider, - url_loader_factory_); + &testing_profile_, pref_service_.get(), hint_store_.get(), + top_host_provider, url_loader_factory_); hints_manager_->SetClockForTesting(task_environment_.GetMockClock()); - // Add observer is called after the HintCache is fully initialized, - // indicating that the OptimizationGuideHintsManager is ready to process - // hints. - while (!optimization_guide_service_->AddObserverCalled()) { - RunUntilIdle(); - } + // Run until hint cache is initialized and the OptimizationGuideHintsManager + // is ready to process hints. + RunUntilIdle(); } void ResetHintsManager() { @@ -454,7 +420,6 @@ std::unique_ptr<content::TestWebContentsFactory> web_contents_factory_; std::unique_ptr<optimization_guide::OptimizationGuideStore> hint_store_; std::unique_ptr<OptimizationGuideHintsManager> hints_manager_; - std::unique_ptr<TestOptimizationGuideService> optimization_guide_service_; std::unique_ptr<TestingPrefServiceSimple> pref_service_; scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_; network::TestURLLoaderFactory test_url_loader_factory_; @@ -493,7 +458,7 @@ base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( optimization_guide::switches::kHintsProtoOverride, encoded_config); - CreateServiceAndHintsManager(/*top_host_provider=*/nullptr); + CreateHintsManager(/*top_host_provider=*/nullptr); hints_manager()->RegisterOptimizationTypes( {optimization_guide::proto::LITE_PAGE_REDIRECT}); @@ -530,7 +495,7 @@ base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( optimization_guide::switches::kHintsProtoOverride, "this-is-not-a-proto"); - CreateServiceAndHintsManager(/*top_host_provider=*/nullptr); + CreateHintsManager(/*top_host_provider=*/nullptr); // The below histogram should not be recorded since hints weren't coming // directly from the component. @@ -560,7 +525,7 @@ base::HistogramTester histogram_tester; base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( optimization_guide::switches::kHintsProtoOverride, encoded_config); - CreateServiceAndHintsManager(/*top_host_provider=*/nullptr); + CreateHintsManager(/*top_host_provider=*/nullptr); // The below histogram should not be recorded since hints weren't coming // directly from the component. histogram_tester.ExpectTotalCount("OptimizationGuide.ProcessHintsResult", @@ -1898,7 +1863,7 @@ std::make_unique<FakeTopHostProvider>( std::vector<std::string>({"example1.com", "example2.com"})); - CreateServiceAndHintsManager(top_host_provider.get()); + CreateHintsManager(top_host_provider.get()); InitializeWithDefaultConfig("1.0.0"); // Force timer to expire and schedule a hints fetch. @@ -1987,7 +1952,7 @@ HintsFetchNotAllowedIfFeatureIsEnabledButUserNotAllowed) { base::CommandLine::ForCurrentProcess()->RemoveSwitch( optimization_guide::switches::kDisableCheckingUserPermissionsForTesting); - CreateServiceAndHintsManager(/*top_host_provider=*/nullptr); + CreateHintsManager(/*top_host_provider=*/nullptr); hints_manager()->RegisterOptimizationTypes( {optimization_guide::proto::DEFER_ALL_SCRIPT}); hints_manager()->SetHintsFetcherFactoryForTesting( @@ -2005,7 +1970,7 @@ HintsFetchNotAllowedIfFeatureIsEnabledButTopHostProviderIsNotProvided) { base::CommandLine::ForCurrentProcess()->AppendSwitch( optimization_guide::switches::kDisableCheckingUserPermissionsForTesting); - CreateServiceAndHintsManager(/*top_host_provider=*/nullptr); + CreateHintsManager(/*top_host_provider=*/nullptr); hints_manager()->RegisterOptimizationTypes( {optimization_guide::proto::DEFER_ALL_SCRIPT}); hints_manager()->SetHintsFetcherFactoryForTesting( @@ -2027,7 +1992,7 @@ base::CommandLine::ForCurrentProcess()->AppendSwitch( optimization_guide::switches::kDisableCheckingUserPermissionsForTesting); - CreateServiceAndHintsManager(top_host_provider.get()); + CreateHintsManager(top_host_provider.get()); hints_manager()->SetHintsFetcherFactoryForTesting( BuildTestHintsFetcherFactory( @@ -2047,7 +2012,7 @@ optimization_guide::switches::kDisableCheckingUserPermissionsForTesting); std::unique_ptr<FakeTopHostProvider> top_host_provider = std::make_unique<FakeTopHostProvider>(std::vector<std::string>({})); - CreateServiceAndHintsManager(top_host_provider.get()); + CreateHintsManager(top_host_provider.get()); hints_manager()->RegisterOptimizationTypes( {optimization_guide::proto::DEFER_ALL_SCRIPT}); @@ -2070,7 +2035,7 @@ std::unique_ptr<FakeTopHostProvider> top_host_provider = std::make_unique<FakeTopHostProvider>( std::vector<std::string>({"example1.com", "example2.com"})); - CreateServiceAndHintsManager(top_host_provider.get()); + CreateHintsManager(top_host_provider.get()); hints_manager()->RegisterOptimizationTypes( {optimization_guide::proto::DEFER_ALL_SCRIPT}); hints_manager()->SetHintsFetcherFactoryForTesting( @@ -2099,7 +2064,7 @@ std::make_unique<FakeTopHostProvider>( std::vector<std::string>({"example1.com", "example2.com"})); - CreateServiceAndHintsManager(top_host_provider.get()); + CreateHintsManager(top_host_provider.get()); hints_manager()->RegisterOptimizationTypes( {optimization_guide::proto::DEFER_ALL_SCRIPT}); hints_manager()->SetHintsFetcherFactoryForTesting( @@ -2126,7 +2091,7 @@ std::vector<std::string>({"example1.com", "example2.com"})); // Force hints fetch scheduling. - CreateServiceAndHintsManager(top_host_provider.get()); + CreateHintsManager(top_host_provider.get()); hints_manager()->RegisterOptimizationTypes( {optimization_guide::proto::DEFER_ALL_SCRIPT}); hints_manager()->SetHintsFetcherFactoryForTesting( @@ -3713,7 +3678,7 @@ std::vector<std::string>({"example1.com", "example2.com"})); // Force hints fetch scheduling. - CreateServiceAndHintsManager(top_host_provider.get()); + CreateHintsManager(top_host_provider.get()); hints_manager()->RegisterOptimizationTypes( {optimization_guide::proto::DEFER_ALL_SCRIPT}); hints_manager()->SetHintsFetcherFactoryForTesting(
diff --git a/chrome/browser/optimization_guide/optimization_guide_keyed_service.cc b/chrome/browser/optimization_guide/optimization_guide_keyed_service.cc index f5df625..acdaa6cc 100644 --- a/chrome/browser/optimization_guide/optimization_guide_keyed_service.cc +++ b/chrome/browser/optimization_guide/optimization_guide_keyed_service.cc
@@ -25,7 +25,6 @@ #include "components/optimization_guide/core/hints_processing_util.h" #include "components/optimization_guide/core/optimization_guide_constants.h" #include "components/optimization_guide/core/optimization_guide_features.h" -#include "components/optimization_guide/core/optimization_guide_service.h" #include "components/optimization_guide/core/optimization_guide_store.h" #include "components/optimization_guide/core/optimization_guide_util.h" #include "components/optimization_guide/core/top_host_provider.h" @@ -172,8 +171,7 @@ } hints_manager_ = std::make_unique<OptimizationGuideHintsManager>( - g_browser_process->optimization_guide_service(), profile, - profile->GetPrefs(), hint_store, top_host_provider_.get(), + profile, profile->GetPrefs(), hint_store, top_host_provider_.get(), url_loader_factory); prediction_manager_ = std::make_unique<optimization_guide::PredictionManager>( prediction_model_and_features_store, top_host_provider_.get(),
diff --git a/chrome/browser/optimization_guide/optimization_guide_keyed_service_browsertest.cc b/chrome/browser/optimization_guide/optimization_guide_keyed_service_browsertest.cc index 7216e87..ce3fc62 100644 --- a/chrome/browser/optimization_guide/optimization_guide_keyed_service_browsertest.cc +++ b/chrome/browser/optimization_guide/optimization_guide_keyed_service_browsertest.cc
@@ -10,7 +10,6 @@ #include "build/build_config.h" #include "build/chromeos_buildflags.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/optimization_guide/optimization_guide_hints_manager.h" #include "chrome/browser/optimization_guide/optimization_guide_keyed_service.h" #include "chrome/browser/optimization_guide/optimization_guide_keyed_service_factory.h" @@ -25,10 +24,12 @@ #include "components/optimization_guide/core/optimization_guide_prefs.h" #include "components/optimization_guide/core/optimization_guide_store.h" #include "components/optimization_guide/core/optimization_guide_switches.h" +#include "components/optimization_guide/core/optimization_hints_component_update_listener.h" #include "components/optimization_guide/core/test_hints_component_creator.h" #include "components/optimization_guide/proto/hints.pb.h" #include "components/prefs/pref_service.h" #include "components/previews/core/previews_switches.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "components/ukm/test_ukm_recorder.h" #include "components/variations/active_field_trials.h" #include "components/variations/hashing.h" @@ -222,8 +223,8 @@ optimization_guide::proto::NOSCRIPT, {url_with_hints_.host()}, "simple.html"); - g_browser_process->optimization_guide_service()->MaybeUpdateHintsComponent( - component_info); + optimization_guide::OptimizationHintsComponentUpdateListener::GetInstance() + ->MaybeUpdateHintsComponent(component_info); run_loop.Run(); }
diff --git a/chrome/browser/optimization_guide/optimization_guide_top_host_provider.cc b/chrome/browser/optimization_guide/optimization_guide_top_host_provider.cc index a80b79e3..284b325 100644 --- a/chrome/browser/optimization_guide/optimization_guide_top_host_provider.cc +++ b/chrome/browser/optimization_guide/optimization_guide_top_host_provider.cc
@@ -9,7 +9,6 @@ #include "base/metrics/histogram_macros.h" #include "base/time/default_clock.h" #include "base/values.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/optimization_guide/optimization_guide_permissions_util.h" #include "chrome/browser/profiles/profile.h" #include "components/optimization_guide/core/hints_processing_util.h" @@ -18,6 +17,7 @@ #include "components/prefs/pref_service.h" #include "components/prefs/scoped_user_pref_update.h" #include "components/site_engagement/content/site_engagement_score.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "components/site_engagement/core/mojom/site_engagement_details.mojom.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/navigation_handle.h"
diff --git a/chrome/browser/optimization_guide/optimization_guide_top_host_provider_unittest.cc b/chrome/browser/optimization_guide/optimization_guide_top_host_provider_unittest.cc index f2aa3b2..2185318 100644 --- a/chrome/browser/optimization_guide/optimization_guide_top_host_provider_unittest.cc +++ b/chrome/browser/optimization_guide/optimization_guide_top_host_provider_unittest.cc
@@ -8,7 +8,6 @@ #include "base/test/simple_test_clock.h" #include "base/time/default_clock.h" #include "base/values.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/previews/previews_https_notification_infobar_decider.h" #include "chrome/browser/previews/previews_service.h" #include "chrome/browser/previews/previews_service_factory.h" @@ -22,6 +21,7 @@ #include "components/optimization_guide/core/optimization_guide_switches.h" #include "components/prefs/pref_service.h" #include "components/site_engagement/content/site_engagement_score.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "content/public/test/mock_navigation_handle.h" #include "content/public/test/web_contents_tester.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/optimization_guide/prediction/prediction_manager.cc b/chrome/browser/optimization_guide/prediction/prediction_manager.cc index 5f0d201..b31581ce 100644 --- a/chrome/browser/optimization_guide/prediction/prediction_manager.cc +++ b/chrome/browser/optimization_guide/prediction/prediction_manager.cc
@@ -23,7 +23,6 @@ #include "base/time/default_clock.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/download/download_service_factory.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/optimization_guide/optimization_guide_navigation_data.h" #include "chrome/browser/optimization_guide/optimization_guide_permissions_util.h" #include "chrome/browser/optimization_guide/prediction/prediction_model_download_manager.h" @@ -45,6 +44,7 @@ #include "components/optimization_guide/core/top_host_provider.h" #include "components/optimization_guide/proto/models.pb.h" #include "components/prefs/pref_service.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/network_service_instance.h" #include "content/public/browser/web_contents.h"
diff --git a/chrome/browser/optimization_guide/prediction/prediction_manager_unittest.cc b/chrome/browser/optimization_guide/prediction/prediction_manager_unittest.cc index f1dd17a..0d336fba 100644 --- a/chrome/browser/optimization_guide/prediction/prediction_manager_unittest.cc +++ b/chrome/browser/optimization_guide/prediction/prediction_manager_unittest.cc
@@ -24,7 +24,6 @@ #include "components/leveldb_proto/testing/fake_db.h" #include "components/optimization_guide/core/optimization_guide_features.h" #include "components/optimization_guide/core/optimization_guide_prefs.h" -#include "components/optimization_guide/core/optimization_guide_service.h" #include "components/optimization_guide/core/optimization_guide_store.h" #include "components/optimization_guide/core/optimization_guide_switches.h" #include "components/optimization_guide/core/optimization_guide_util.h"
diff --git a/chrome/browser/optimization_guide/prediction/prediction_model_download_manager_unittest.cc b/chrome/browser/optimization_guide/prediction/prediction_model_download_manager_unittest.cc index b89fcc4..49dfe47 100644 --- a/chrome/browser/optimization_guide/prediction/prediction_model_download_manager_unittest.cc +++ b/chrome/browser/optimization_guide/prediction/prediction_model_download_manager_unittest.cc
@@ -154,6 +154,32 @@ switches::kDisableModelDownloadVerificationForTesting); } + // Retries until the path has been deleted or until all handles to |path| have + // been closed. Returns whether |path| has been deleted. + // + // See crbug/1156112#c1 for suggested mitigation steps. + bool HasPathBeenDeleted(const base::FilePath& path) { + while (true) { + RunUntilIdle(); + + bool path_exists = base::PathExists(path); + if (!path_exists) + return true; + + base::File::Error file_error = base::File::GetLastFileError(); + // In the event this does not fix the flake, log the error so we know what + // it is. + // TODO(crbug/1156112): Remove this log once the flake has been resolved. + DLOG(ERROR) << "Path Exists Error: " << file_error; + + if (file_error != base::File::FILE_ERROR_ACCESS_DENIED) + return !path_exists; + + // Retry if the last file error is access denied since it's likely that + // the file is in the process of being deleted. + } + } + private: void WriteFileForStatus(PredictionModelDownloadFileStatus status) { if (status == PredictionModelDownloadFileStatus::kVerifiedCrxWithNoFiles || @@ -383,7 +409,7 @@ RunUntilIdle(); EXPECT_FALSE(observer.last_ready_model().has_value()); - EXPECT_FALSE(base::PathExists(GetFilePathForDownloadFileStatus( + EXPECT_TRUE(HasPathBeenDeleted(GetFilePathForDownloadFileStatus( PredictionModelDownloadFileStatus::kUnverifiedFile))); histogram_tester.ExpectUniqueSample( "OptimizationGuide.PredictionModelDownloadManager." @@ -403,7 +429,7 @@ RunUntilIdle(); EXPECT_FALSE(observer.last_ready_model().has_value()); - EXPECT_FALSE(base::PathExists(GetFilePathForDownloadFileStatus( + EXPECT_TRUE(HasPathBeenDeleted(GetFilePathForDownloadFileStatus( PredictionModelDownloadFileStatus::kVerifiedCrxWithNoFiles))); histogram_tester.ExpectUniqueSample( @@ -426,7 +452,7 @@ RunUntilIdle(); EXPECT_FALSE(observer.last_ready_model().has_value()); - EXPECT_FALSE(base::PathExists(GetFilePathForDownloadFileStatus( + EXPECT_TRUE(HasPathBeenDeleted(GetFilePathForDownloadFileStatus( PredictionModelDownloadFileStatus::kVerifiedCrxWithBadModelInfoFile))); histogram_tester.ExpectUniqueSample( @@ -449,7 +475,7 @@ RunUntilIdle(); EXPECT_FALSE(observer.last_ready_model().has_value()); - EXPECT_FALSE(base::PathExists(GetFilePathForDownloadFileStatus( + EXPECT_TRUE(HasPathBeenDeleted(GetFilePathForDownloadFileStatus( PredictionModelDownloadFileStatus::kVerifiedCrxWithInvalidModelInfo))); histogram_tester.ExpectUniqueSample( @@ -471,7 +497,7 @@ RunUntilIdle(); EXPECT_FALSE(observer.last_ready_model().has_value()); - EXPECT_FALSE(base::PathExists(GetFilePathForDownloadFileStatus( + EXPECT_TRUE(HasPathBeenDeleted(GetFilePathForDownloadFileStatus( PredictionModelDownloadFileStatus:: kVerfiedCrxWithValidModelInfoNoModelFile))); @@ -506,7 +532,7 @@ .value(), FILE_PATH_LITERAL("OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD_123.tflite")); // Downloaded file should still be deleted. - EXPECT_FALSE(base::PathExists(GetFilePathForDownloadFileStatus( + EXPECT_TRUE(HasPathBeenDeleted(GetFilePathForDownloadFileStatus( PredictionModelDownloadFileStatus::kVerifiedCrxWithGoodModelFiles))); histogram_tester.ExpectUniqueSample(
diff --git a/chrome/browser/page_load_metrics/observers/ad_metrics/floc_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/ad_metrics/floc_page_load_metrics_observer.cc new file mode 100644 index 0000000..eb4eef0a --- /dev/null +++ b/chrome/browser/page_load_metrics/observers/ad_metrics/floc_page_load_metrics_observer.cc
@@ -0,0 +1,40 @@ +// 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/page_load_metrics/observers/ad_metrics/floc_page_load_metrics_observer.h" + +#include "chrome/browser/federated_learning/floc_eligibility_observer.h" +#include "content/public/browser/web_contents.h" + +FlocPageLoadMetricsObserver::FlocPageLoadMetricsObserver() = default; + +FlocPageLoadMetricsObserver::~FlocPageLoadMetricsObserver() = default; + +page_load_metrics::PageLoadMetricsObserver::ObservePolicy +FlocPageLoadMetricsObserver::OnCommit( + content::NavigationHandle* navigation_handle, + ukm::SourceId source_id) { + return federated_learning::FlocEligibilityObserver:: + GetOrCreateForCurrentDocument(navigation_handle->GetRenderFrameHost()) + ->OnCommit(navigation_handle); +} + +void FlocPageLoadMetricsObserver::OnResourceDataUseObserved( + content::RenderFrameHost* rfh, + const std::vector<page_load_metrics::mojom::ResourceDataUpdatePtr>& + resources) { + bool any_ads_resource = base::ranges::any_of( + resources, + [](const page_load_metrics::mojom::ResourceDataUpdatePtr& resource) { + return resource->reported_as_ad_resource && + resource->received_data_length > 0; + }); + + if (any_ads_resource) { + content::WebContents* web_contents = GetDelegate().GetWebContents(); + federated_learning::FlocEligibilityObserver::GetOrCreateForCurrentDocument( + web_contents->GetMainFrame()) + ->OnAdResource(); + } +}
diff --git a/chrome/browser/page_load_metrics/observers/ad_metrics/floc_page_load_metrics_observer.h b/chrome/browser/page_load_metrics/observers/ad_metrics/floc_page_load_metrics_observer.h new file mode 100644 index 0000000..9f719647 --- /dev/null +++ b/chrome/browser/page_load_metrics/observers/ad_metrics/floc_page_load_metrics_observer.h
@@ -0,0 +1,36 @@ +// 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_PAGE_LOAD_METRICS_OBSERVERS_AD_METRICS_FLOC_PAGE_LOAD_METRICS_OBSERVER_H_ +#define CHROME_BROWSER_PAGE_LOAD_METRICS_OBSERVERS_AD_METRICS_FLOC_PAGE_LOAD_METRICS_OBSERVER_H_ + +#include "base/macros.h" +#include "components/page_load_metrics/browser/page_load_metrics_observer.h" + +// This observer monitors navigation commit and resource usages, which may +// affect whether the navigation's associated history entry is eligible for floc +// computation. +// +// The final eligibility decision may be based on other signals. See the +// FlocEligibilityObserver class for the full criteria. +class FlocPageLoadMetricsObserver + : public page_load_metrics::PageLoadMetricsObserver { + public: + FlocPageLoadMetricsObserver(); + ~FlocPageLoadMetricsObserver() override; + + FlocPageLoadMetricsObserver(const FlocPageLoadMetricsObserver&) = delete; + FlocPageLoadMetricsObserver& operator=(const FlocPageLoadMetricsObserver&) = + delete; + + // page_load_metrics::PageLoadMetricsObserver + ObservePolicy OnCommit(content::NavigationHandle* navigation_handle, + ukm::SourceId source_id) override; + void OnResourceDataUseObserved( + content::RenderFrameHost* rfh, + const std::vector<page_load_metrics::mojom::ResourceDataUpdatePtr>& + resources) override; +}; + +#endif // CHROME_BROWSER_PAGE_LOAD_METRICS_OBSERVERS_AD_METRICS_FLOC_PAGE_LOAD_METRICS_OBSERVER_H_
diff --git a/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer.cc index b4e816f..7db09d1 100644 --- a/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer.cc +++ b/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer.cc
@@ -16,7 +16,6 @@ #include "cc/metrics/ukm_smoothness_data.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/content_settings/cookie_settings_factory.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/prefetch/no_state_prefetch/prerender_manager_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/search_engines/template_url_service_factory.h" @@ -35,6 +34,7 @@ #include "components/page_load_metrics/browser/protocol_util.h" #include "components/prefs/pref_service.h" #include "components/search_engines/template_url_service.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/web_contents.h" #include "media/base/mime_util.h"
diff --git a/chrome/browser/page_load_metrics/observers/security_state_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/security_state_page_load_metrics_observer.cc index 4ccc9fc6..7000966 100644 --- a/chrome/browser/page_load_metrics/observers/security_state_page_load_metrics_observer.cc +++ b/chrome/browser/page_load_metrics/observers/security_state_page_load_metrics_observer.cc
@@ -9,11 +9,11 @@ #include "base/check.h" #include "base/metrics/histogram_functions.h" #include "base/time/time.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/engagement/site_engagement_service_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ssl/security_state_tab_helper.h" #include "components/security_state/core/security_state.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "content/public/browser/navigation_handle.h" #include "services/metrics/public/cpp/metrics_utils.h" #include "services/metrics/public/cpp/ukm_builders.h"
diff --git a/chrome/browser/page_load_metrics/page_load_metrics_initialize.cc b/chrome/browser/page_load_metrics/page_load_metrics_initialize.cc index 11fab4e..5c45f2fc 100644 --- a/chrome/browser/page_load_metrics/page_load_metrics_initialize.cc +++ b/chrome/browser/page_load_metrics/page_load_metrics_initialize.cc
@@ -11,6 +11,7 @@ #include "build/build_config.h" #include "chrome/browser/page_load_metrics/observers/aborts_page_load_metrics_observer.h" #include "chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.h" +#include "chrome/browser/page_load_metrics/observers/ad_metrics/floc_page_load_metrics_observer.h" #include "chrome/browser/page_load_metrics/observers/core/amp_page_load_metrics_observer.h" #include "chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer.h" #include "chrome/browser/page_load_metrics/observers/data_saver_site_breakdown_metrics_observer.h" @@ -128,6 +129,7 @@ if (ads_observer) tracker->AddObserver(std::move(ads_observer)); + tracker->AddObserver(std::make_unique<FlocPageLoadMetricsObserver>()); tracker->AddObserver(std::make_unique<ThirdPartyMetricsObserver>()); std::unique_ptr<page_load_metrics::PageLoadMetricsObserver> ukm_observer =
diff --git a/chrome/browser/paint_preview/paint_preview_browsertest.cc b/chrome/browser/paint_preview/paint_preview_browsertest.cc index d4bc4ff..84be6cb 100644 --- a/chrome/browser/paint_preview/paint_preview_browsertest.cc +++ b/chrome/browser/paint_preview/paint_preview_browsertest.cc
@@ -376,6 +376,9 @@ #endif IN_PROC_BROWSER_TEST_P(PaintPreviewBrowserTest, MAYBE_DontReloadInRenderProcessExit) { + // In the FileSystem variant of this test, blocking needs to be permitted to + // allow cleanup to work during the crash. + base::ScopedAllowBlockingForTesting scope; LoadPage(http_server_.GetURL("a.com", "/title1.html")); content::WebContents* web_contents = GetWebContents(); @@ -414,15 +417,12 @@ .Then(loop.QuitClosure())); // Crash the renderer. - { - base::ScopedAllowBlockingForTesting scope; - content::RenderProcessHost* process = - GetWebContents()->GetMainFrame()->GetProcess(); - content::RenderProcessHostWatcher crash_observer( - process, content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); - process->Shutdown(0); - crash_observer.Wait(); - } + content::RenderProcessHost* process = + GetWebContents()->GetMainFrame()->GetProcess(); + content::RenderProcessHostWatcher crash_observer( + process, content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); + process->Shutdown(0); + crash_observer.Wait(); // The browser would have crashed before the loop exited if the callback was // not posted.
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.cc b/chrome/browser/password_manager/chrome_password_manager_client.cc index 1337a64a..0c91780 100644 --- a/chrome/browser/password_manager/chrome_password_manager_client.cc +++ b/chrome/browser/password_manager/chrome_password_manager_client.cc
@@ -24,7 +24,6 @@ #include "build/buildflag.h" #include "build/chromeos_buildflags.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/favicon/favicon_service_factory.h" #include "chrome/browser/metrics/chrome_metrics_service_accessor.h" #include "chrome/browser/password_manager/account_password_store_factory.h" @@ -76,6 +75,7 @@ #include "components/sessions/content/content_record_password_state.h" #include "components/signin/public/base/signin_metrics.h" #include "components/signin/public/identity_manager/identity_manager.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "components/site_isolation/site_isolation_policy.h" #include "components/sync/driver/sync_service.h" #include "components/sync/driver/sync_user_settings.h"
diff --git a/chrome/browser/pdf/pdf_extension_test.cc b/chrome/browser/pdf/pdf_extension_test.cc index 21d62c0..4f5eb97 100644 --- a/chrome/browser/pdf/pdf_extension_test.cc +++ b/chrome/browser/pdf/pdf_extension_test.cc
@@ -23,6 +23,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/synchronization/lock.h" #include "base/test/bind.h" +#include "base/test/icu_test_util.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/metrics/user_action_tester.h" #include "base/test/test_timeouts.h" @@ -918,6 +919,8 @@ IN_PROC_BROWSER_TEST_F(PDFExtensionJSUpdatesEnabledTest, ViewerPropertiesDialogTest) { + // The properties dialog formats some values based on locale. + base::test::ScopedRestoreICUDefaultLocale scoped_locale{"en_US"}; RunTestsInJsModule("viewer_properties_dialog_test.js", "document_info.pdf"); }
diff --git a/chrome/browser/permissions/chrome_permission_request_manager_unittest.cc b/chrome/browser/permissions/chrome_permission_request_manager_unittest.cc index 707025b..83050808 100644 --- a/chrome/browser/permissions/chrome_permission_request_manager_unittest.cc +++ b/chrome/browser/permissions/chrome_permission_request_manager_unittest.cc
@@ -16,7 +16,6 @@ #include "base/util/values/values_util.h" #include "build/build_config.h" #include "build/chromeos_buildflags.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/permissions/adaptive_quiet_notification_permission_ui_enabler.h" #include "chrome/browser/permissions/quiet_notification_permission_ui_config.h" #include "chrome/browser/permissions/quiet_notification_permission_ui_state.h" @@ -36,6 +35,7 @@ #include "components/permissions/test/mock_permission_request.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/scoped_user_pref_update.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "components/ukm/content/source_url_recorder.h" #include "components/ukm/test_ukm_recorder.h" #include "components/user_manager/scoped_user_manager.h"
diff --git a/chrome/browser/permissions/chrome_permissions_client.cc b/chrome/browser/permissions/chrome_permissions_client.cc index 8ca1a6f..c8d5867 100644 --- a/chrome/browser/permissions/chrome_permissions_client.cc +++ b/chrome/browser/permissions/chrome_permissions_client.cc
@@ -14,7 +14,6 @@ #include "chrome/browser/content_settings/cookie_settings_factory.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/engagement/important_sites_util.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/metrics/ukm_background_recorder_service.h" #include "chrome/browser/permissions/abusive_origin_permission_revocation_request.h" #include "chrome/browser/permissions/adaptive_quiet_notification_permission_ui_enabler.h" @@ -35,6 +34,7 @@ #include "components/google/core/common/google_util.h" #include "components/permissions/features.h" #include "components/prefs/pref_service.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "components/subresource_filter/content/browser/subresource_filter_content_settings_manager.h" #include "components/subresource_filter/content/browser/subresource_filter_profile_context.h" #include "components/ukm/content/source_url_recorder.h"
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc index b73a41e2..171c537 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc
@@ -523,6 +523,9 @@ const char kAssistantQuickAnswersEnabled[] = "settings.voice_interaction.quick_answers.enabled"; +// Deprecated 01/2021 +const char kGoogleServicesHostedDomain[] = "google.services.hosted_domain"; + // Register local state used only for migration (clearing or moving to a new // key). void RegisterLocalStatePrefsForMigration(PrefRegistrySimple* registry) { @@ -618,6 +621,8 @@ #endif // BUILDFLAG(IS_CHROMEOS_ASH) registry->RegisterBooleanPref(kAssistantQuickAnswersEnabled, true); + + registry->RegisterStringPref(kGoogleServicesHostedDomain, std::string()); } } // namespace @@ -1261,6 +1266,9 @@ // Added 12/2020 profile_prefs->ClearPref(kAssistantQuickAnswersEnabled); + // Added 01/2021 + profile_prefs->ClearPref(kGoogleServicesHostedDomain); + // Please don't delete the following line. It is used by PRESUBMIT.py. // END_MIGRATE_OBSOLETE_PROFILE_PREFS }
diff --git a/chrome/browser/previews/defer_all_script_browsertest.cc b/chrome/browser/previews/defer_all_script_browsertest.cc index db47ce0..8897db5 100644 --- a/chrome/browser/previews/defer_all_script_browsertest.cc +++ b/chrome/browser/previews/defer_all_script_browsertest.cc
@@ -14,7 +14,6 @@ #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "build/build_config.h" -#include "chrome/browser/browser_process.h" #include "chrome/browser/optimization_guide/optimization_guide_keyed_service.h" #include "chrome/browser/optimization_guide/optimization_guide_keyed_service_factory.h" #include "chrome/browser/previews/previews_service.h" @@ -31,7 +30,7 @@ #include "components/optimization_guide/core/hints_component_util.h" #include "components/optimization_guide/core/optimization_guide_constants.h" #include "components/optimization_guide/core/optimization_guide_features.h" -#include "components/optimization_guide/core/optimization_guide_service.h" +#include "components/optimization_guide/core/optimization_hints_component_update_listener.h" #include "components/optimization_guide/core/test_hints_component_creator.h" #include "components/optimization_guide/proto/hints.pb.h" #include "components/prefs/pref_service.h" @@ -121,8 +120,8 @@ const optimization_guide::HintsComponentInfo& component_info) { base::HistogramTester histogram_tester; - g_browser_process->optimization_guide_service()->MaybeUpdateHintsComponent( - component_info); + optimization_guide::OptimizationHintsComponentUpdateListener::GetInstance() + ->MaybeUpdateHintsComponent(component_info); RetryForHistogramUntilCountReached( &histogram_tester,
diff --git a/chrome/browser/previews/defer_all_script_priority_browsertest.cc b/chrome/browser/previews/defer_all_script_priority_browsertest.cc index 64123b2..124e0df 100644 --- a/chrome/browser/previews/defer_all_script_priority_browsertest.cc +++ b/chrome/browser/previews/defer_all_script_priority_browsertest.cc
@@ -12,8 +12,6 @@ #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "build/build_config.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_process_impl.h" #include "chrome/browser/chrome_content_browser_client.h" #include "chrome/browser/optimization_guide/optimization_guide_keyed_service.h" #include "chrome/browser/optimization_guide/optimization_guide_keyed_service_factory.h" @@ -27,7 +25,7 @@ #include "components/optimization_guide/core/hints_component_util.h" #include "components/optimization_guide/core/optimization_guide_constants.h" #include "components/optimization_guide/core/optimization_guide_features.h" -#include "components/optimization_guide/core/optimization_guide_service.h" +#include "components/optimization_guide/core/optimization_hints_component_update_listener.h" #include "components/optimization_guide/core/test_hints_component_creator.h" #include "components/optimization_guide/proto/hints.pb.h" #include "components/previews/core/previews_features.h" @@ -179,8 +177,8 @@ const optimization_guide::HintsComponentInfo& component_info) { base::HistogramTester histogram_tester; - g_browser_process->optimization_guide_service()->MaybeUpdateHintsComponent( - component_info); + optimization_guide::OptimizationHintsComponentUpdateListener::GetInstance() + ->MaybeUpdateHintsComponent(component_info); RetryForHistogramUntilCountReached( &histogram_tester,
diff --git a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc index 8ddea2f..9640573 100644 --- a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc +++ b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
@@ -30,7 +30,6 @@ #include "chrome/browser/domain_reliability/service_factory.h" #include "chrome/browser/download/download_core_service_factory.h" #include "chrome/browser/download/download_service_factory.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/engagement/site_engagement_service_factory.h" #include "chrome/browser/favicon/favicon_service_factory.h" #include "chrome/browser/favicon/history_ui_favicon_request_handler_factory.h" @@ -106,6 +105,7 @@ #include "components/reading_list/features/reading_list_switches.h" #include "components/safe_browsing/buildflags.h" #include "components/signin/public/base/signin_buildflags.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "components/spellcheck/spellcheck_buildflags.h" #include "extensions/buildflags/buildflags.h" #include "media/base/media_switches.h"
diff --git a/chrome/browser/profiles/gaia_info_update_service.cc b/chrome/browser/profiles/gaia_info_update_service.cc index 8d01b1f..3ff8b96 100644 --- a/chrome/browser/profiles/gaia_info_update_service.cc +++ b/chrome/browser/profiles/gaia_info_update_service.cc
@@ -37,12 +37,10 @@ GAIAInfoUpdateService::GAIAInfoUpdateService( signin::IdentityManager* identity_manager, ProfileAttributesStorage* profile_attributes_storage, - const base::FilePath& profile_path, - PrefService* profile_prefs) + const base::FilePath& profile_path) : identity_manager_(identity_manager), profile_attributes_storage_(profile_attributes_storage), - profile_path_(profile_path), - profile_prefs_(profile_prefs) { + profile_path_(profile_path) { identity_manager_->AddObserver(this); if (!ShouldUpdatePrimaryAccount()) { @@ -94,11 +92,7 @@ gaia_id_of_profile_attribute_entry_ = info.gaia; entry->SetGAIAGivenName(base::UTF8ToUTF16(info.given_name)); entry->SetGAIAName(base::UTF8ToUTF16(info.full_name)); - entry->SetHostedDomain(info.hosted_domain); - const base::string16 hosted_domain = base::UTF8ToUTF16(info.hosted_domain); - profile_prefs_->SetString(prefs::kGoogleServicesHostedDomain, - base::UTF16ToUTF8(hosted_domain)); if (info.picture_url == kNoPictureURLFound) { entry->SetGAIAPicture(std::string(), gfx::Image()); @@ -147,8 +141,6 @@ entry->SetGAIAGivenName(base::string16()); entry->SetGAIAPicture(std::string(), gfx::Image()); entry->SetHostedDomain(std::string()); - // Unset the cached URL. - profile_prefs_->ClearPref(prefs::kGoogleServicesHostedDomain); } void GAIAInfoUpdateService::Shutdown() {
diff --git a/chrome/browser/profiles/gaia_info_update_service.h b/chrome/browser/profiles/gaia_info_update_service.h index 8f7be0f3..bf32d51 100644 --- a/chrome/browser/profiles/gaia_info_update_service.h +++ b/chrome/browser/profiles/gaia_info_update_service.h
@@ -26,8 +26,7 @@ public: GAIAInfoUpdateService(signin::IdentityManager* identity_manager, ProfileAttributesStorage* profile_attributes_storage, - const base::FilePath& profile_path, - PrefService* prefs); + const base::FilePath& profile_path); ~GAIAInfoUpdateService() override; @@ -58,7 +57,6 @@ signin::IdentityManager* identity_manager_; ProfileAttributesStorage* profile_attributes_storage_; const base::FilePath profile_path_; - PrefService* profile_prefs_; // TODO(msalama): remove when |SigninProfileAttributesUpdater| is folded into // |GAIAInfoUpdateService|. std::string gaia_id_of_profile_attribute_entry_;
diff --git a/chrome/browser/profiles/gaia_info_update_service_factory.cc b/chrome/browser/profiles/gaia_info_update_service_factory.cc index bf39ce76..53aa77cf 100644 --- a/chrome/browser/profiles/gaia_info_update_service_factory.cc +++ b/chrome/browser/profiles/gaia_info_update_service_factory.cc
@@ -47,7 +47,7 @@ return new GAIAInfoUpdateService( IdentityManagerFactory::GetForProfile(profile), &g_browser_process->profile_manager()->GetProfileAttributesStorage(), - profile->GetPath(), profile->GetPrefs()); + profile->GetPath()); } bool GAIAInfoUpdateServiceFactory::ServiceIsNULLWhileTesting() const {
diff --git a/chrome/browser/profiles/gaia_info_update_service_unittest.cc b/chrome/browser/profiles/gaia_info_update_service_unittest.cc index e40602e..0508d2a 100644 --- a/chrome/browser/profiles/gaia_info_update_service_unittest.cc +++ b/chrome/browser/profiles/gaia_info_update_service_unittest.cc
@@ -88,7 +88,7 @@ service_.reset(new GAIAInfoUpdateService( identity_test_env_.identity_manager(), testing_profile_manager_.profile_attributes_storage(), - profile()->GetPath(), profile()->GetPrefs())); + profile()->GetPath())); } void TearDown() override { @@ -166,9 +166,6 @@ EXPECT_EQ(entry->GetGAIAGivenName(), base::UTF8ToUTF16("Pat")); EXPECT_EQ(entry->GetGAIAName(), base::UTF8ToUTF16("Pat Foo")); EXPECT_EQ(entry->GetHostedDomain(), kNoHostedDomainFound); - EXPECT_EQ( - profile()->GetPrefs()->GetString(prefs::kGoogleServicesHostedDomain), - kNoHostedDomainFound); gfx::Image gaia_picture = gfx::test::CreateImage(256, 256); signin::SimulateAccountImageFetch(identity_test_env()->identity_manager(), @@ -183,10 +180,6 @@ EXPECT_TRUE(entry->GetGAIAName().empty()); EXPECT_EQ(nullptr, entry->GetGAIAPicture()); EXPECT_TRUE(entry->GetHostedDomain().empty()); - EXPECT_TRUE(profile() - ->GetPrefs() - ->GetString(prefs::kGoogleServicesHostedDomain) - .empty()); } #if BUILDFLAG(ENABLE_DICE_SUPPORT) @@ -229,9 +222,6 @@ EXPECT_EQ(entry->GetGAIAGivenName(), base::UTF8ToUTF16("Pat")); EXPECT_EQ(entry->GetGAIAName(), base::UTF8ToUTF16("Pat Foo")); EXPECT_EQ(entry->GetHostedDomain(), kNoHostedDomainFound); - EXPECT_EQ( - profile()->GetPrefs()->GetString(prefs::kGoogleServicesHostedDomain), - kNoHostedDomainFound); EXPECT_TRUE(gfx::test::AreImagesEqual(gaia_picture, entry->GetAvatarIcon())); } @@ -253,9 +243,6 @@ EXPECT_EQ(entry->GetGAIAGivenName(), base::UTF8ToUTF16("Pat")); EXPECT_EQ(entry->GetGAIAName(), base::UTF8ToUTF16("Pat Foo")); EXPECT_EQ(entry->GetHostedDomain(), kNoHostedDomainFound); - EXPECT_EQ( - profile()->GetPrefs()->GetString(prefs::kGoogleServicesHostedDomain), - kNoHostedDomainFound); gfx::Image gaia_picture = gfx::test::CreateImage(256, 256); signin::SimulateAccountImageFetch(identity_test_env()->identity_manager(), @@ -272,10 +259,6 @@ EXPECT_TRUE(entry->GetGAIAName().empty()); EXPECT_EQ(nullptr, entry->GetGAIAPicture()); EXPECT_TRUE(entry->GetHostedDomain().empty()); - EXPECT_TRUE(profile() - ->GetPrefs() - ->GetString(prefs::kGoogleServicesHostedDomain) - .empty()); } TEST_F(GAIAInfoUpdateServiceTest, LogInLogOutLogIn) {
diff --git a/chrome/browser/profiles/profile_manager.cc b/chrome/browser/profiles/profile_manager.cc index 0c11f4e0..12bf3d9 100644 --- a/chrome/browser/profiles/profile_manager.cc +++ b/chrome/browser/profiles/profile_manager.cc
@@ -1413,12 +1413,6 @@ ChildAccountServiceFactory::GetForProfile(profile)->Init(); SupervisedUserServiceFactory::GetForProfile(profile)->Init(); #endif -#if !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH) - // If the lock enabled algorithm changed, update this profile's lock status. - // This depends on services which shouldn't be initialized until - // DoFinalInitForServices. - profiles::UpdateIsProfileLockEnabledIfNeeded(profile); -#endif // Activate data reduction proxy. This creates a request context and makes a // URL request to check if the data reduction proxy server is reachable.
diff --git a/chrome/browser/profiles/profile_window.cc b/chrome/browser/profiles/profile_window.cc index 3186fb97..ae751d549 100644 --- a/chrome/browser/profiles/profile_window.cc +++ b/chrome/browser/profiles/profile_window.cc
@@ -347,21 +347,16 @@ return false; } - std::string hosted_domain = profile->GetPrefs()-> - GetString(prefs::kGoogleServicesHostedDomain); - // TODO(mlerman): After one release remove any hosted_domain reference to the - // pref, since all users will have this in the AccountTrackerService. - if (hosted_domain.empty()) { - signin::IdentityManager* identity_manager = - IdentityManagerFactory::GetForProfile(profile); - - base::Optional<AccountInfo> primary_account_info = - identity_manager->FindExtendedAccountInfoForAccountWithRefreshToken( - identity_manager->GetPrimaryAccountInfo()); - - if (primary_account_info.has_value()) - hosted_domain = primary_account_info.value().hosted_domain; - } + signin::IdentityManager* identity_manager = + IdentityManagerFactory::GetForProfile(profile); + if (!identity_manager->HasPrimaryAccount()) + return false; + base::Optional<AccountInfo> primary_account_info = + identity_manager->FindExtendedAccountInfoForAccountWithRefreshToken( + identity_manager->GetPrimaryAccountInfo()); + std::string hosted_domain = primary_account_info.has_value() + ? primary_account_info.value().hosted_domain + : ""; // TODO(mlerman): Prohibit only users who authenticate using SAML. Until then, // prohibited users who use hosted domains (aside from google.com).
diff --git a/chrome/browser/profiles/profiles_state.cc b/chrome/browser/profiles/profiles_state.cc index fe05d39..94e30b2 100644 --- a/chrome/browser/profiles/profiles_state.cc +++ b/chrome/browser/profiles/profiles_state.cc
@@ -210,14 +210,6 @@ } #if !BUILDFLAG(IS_CHROMEOS_ASH) -void UpdateIsProfileLockEnabledIfNeeded(Profile* profile) { - if (!profile->GetPrefs()->GetString(prefs::kGoogleServicesHostedDomain). - empty()) - return; - - UpdateGaiaProfileInfoIfNeeded(profile); -} - void UpdateGaiaProfileInfoIfNeeded(Profile* profile) { DCHECK(profile);
diff --git a/chrome/browser/profiles/profiles_state.h b/chrome/browser/profiles/profiles_state.h index dff8e968..a0ae957 100644 --- a/chrome/browser/profiles/profiles_state.h +++ b/chrome/browser/profiles/profiles_state.h
@@ -92,10 +92,6 @@ bool IsProfileLocked(const base::FilePath& profile_path); #if !BUILDFLAG(IS_CHROMEOS_ASH) -// If the lock-enabled information for this profile is not up to date, starts -// an update for the Gaia profile info. -void UpdateIsProfileLockEnabledIfNeeded(Profile* profile); - // Starts an update for a new version of the Gaia profile picture and other // profile info. void UpdateGaiaProfileInfoIfNeeded(Profile* profile);
diff --git a/chrome/browser/profiles/reporting_util.cc b/chrome/browser/profiles/reporting_util.cc index 4c5556a0..78780bc5 100644 --- a/chrome/browser/profiles/reporting_util.cc +++ b/chrome/browser/profiles/reporting_util.cc
@@ -17,31 +17,31 @@ #include "chrome/browser/profiles/profile_manager.h" #include "components/account_id/account_id.h" #include "components/policy/core/common/cloud/cloud_policy_store.h" +#include "components/policy/core/common/cloud/user_cloud_policy_manager.h" #include "components/policy/proto/device_management_backend.pb.h" #include "components/user_manager/user.h" #include "components/user_manager/user_manager.h" -#ifdef OS_CHROMEOS +#if defined(OS_CHROMEOS) #include "chrome/browser/chromeos/login/users/affiliation.h" #include "chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" -#endif // OS_CHROMEOS +#endif // defined(OS_CHROMEOS) namespace { -#ifdef OS_CHROMEOS -// A callback which fetches device dm_token based on user affiliation. -using DeviceDMTokenCallback = base::RepeatingCallback<std::string( - const std::vector<std::string>& user_affiliation_ids)>; - // Returns policy for the given |profile|. If failed to get policy returns // nullptr. const enterprise_management::PolicyData* GetPolicyData(Profile* profile) { if (!profile) return nullptr; - policy::UserCloudPolicyManagerChromeOS* manager = + auto* manager = +#if defined(OS_CHROMEOS) profile->GetUserCloudPolicyManagerChromeOS(); +#else + profile->GetUserCloudPolicyManager(); +#endif if (!manager) return nullptr; @@ -52,6 +52,28 @@ return store->policy(); } +// Returns User DMToken for a given |profile| if: +// * |profile| is NOT incognito profile. +// * |profile| is NOT sign-in screen profile +// * user corresponding to a |profile| is managed. +// Otherwise returns empty string. More about DMToken: +// go/dmserver-domain-model#dmtoken. +std::string GetUserDmToken(Profile* profile) { + if (!profile) + return std::string(); + + const enterprise_management::PolicyData* policy = GetPolicyData(profile); + if (!policy || !policy->has_request_token()) + return std::string(); + + return policy->request_token(); +} + +#if defined(OS_CHROMEOS) +// A callback which fetches device dm_token based on user affiliation. +using DeviceDMTokenCallback = base::RepeatingCallback<std::string( + const std::vector<std::string>& user_affiliation_ids)>; + // Returns the Device DMToken for the given |profile| if: // * |profile| is NOT incognito profile // * user corresponding to a given |profile| is affiliated. @@ -81,23 +103,7 @@ return device_dm_token_callback.Run(user_affiliation_ids); } -// Returns User DMToken for a given |profile| if: -// * |profile| is NOT incognito profile. -// * |profile| is NOT sign-in screen profile -// * user corresponding to a |profile| is managed. -// Otherwise returns empty string. More about DMToken: -// go/dmserver-domain-model#dmtoken. -std::string GetUserDmToken(Profile* profile) { - if (!profile) - return std::string(); - - const enterprise_management::PolicyData* policy = GetPolicyData(profile); - if (!policy || !policy->has_request_token()) - return std::string(); - - return policy->request_token(); -} -#endif // OS_CHROMEOS +#endif // defined(OS_CHROMEOS) } // namespace @@ -120,22 +126,22 @@ context.SetStringPath("profile.profilePath", profile->GetPath().value()); -#ifdef OS_CHROMEOS const enterprise_management::PolicyData* policy = GetPolicyData(profile); if (policy) { if (policy->has_device_id()) context.SetStringPath("profile.clientId", policy->device_id()); +#if defined(OS_CHROMEOS) std::string device_dm_token = GetDeviceDmToken(profile); if (!device_dm_token.empty()) context.SetStringPath("device.dmToken", device_dm_token); +#endif std::string user_dm_token = GetUserDmToken(profile); if (!user_dm_token.empty()) context.SetStringPath("profile.dmToken", user_dm_token); } -#endif // OS_CHROMEOS return context; }
diff --git a/chrome/browser/push_messaging/budget_database.cc b/chrome/browser/push_messaging/budget_database.cc index 400d8f7..78b851cb 100644 --- a/chrome/browser/push_messaging/budget_database.cc +++ b/chrome/browser/push_messaging/budget_database.cc
@@ -11,11 +11,11 @@ #include "base/task/thread_pool.h" #include "base/time/clock.h" #include "base/time/default_clock.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/push_messaging/budget.pb.h" #include "components/leveldb_proto/public/proto_database_provider.h" #include "components/site_engagement/content/site_engagement_score.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/storage_partition.h" #include "url/gurl.h"
diff --git a/chrome/browser/push_messaging/budget_database_unittest.cc b/chrome/browser/push_messaging/budget_database_unittest.cc index 7d714e7..edc60fac 100644 --- a/chrome/browser/push_messaging/budget_database_unittest.cc +++ b/chrome/browser/push_messaging/budget_database_unittest.cc
@@ -12,12 +12,12 @@ #include "base/run_loop.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/simple_test_clock.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/push_messaging/budget.pb.h" #include "chrome/test/base/testing_profile.h" #include "components/leveldb_proto/public/proto_database.h" #include "components/leveldb_proto/public/proto_database_provider.h" #include "components/site_engagement/content/site_engagement_score.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "content/public/browser/browser_thread.h" #include "content/public/test/browser_task_environment.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/push_messaging/push_messaging_browsertest.cc b/chrome/browser/push_messaging/push_messaging_browsertest.cc index a6ffbd8..8d4f119 100644 --- a/chrome/browser/push_messaging/push_messaging_browsertest.cc +++ b/chrome/browser/push_messaging/push_messaging_browsertest.cc
@@ -23,7 +23,6 @@ #include "chrome/browser/browsing_data/chrome_browsing_data_remover_constants.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/gcm/gcm_profile_service_factory.h" #include "chrome/browser/gcm/instance_id/instance_id_profile_service_factory.h" #include "chrome/browser/notifications/notification_display_service_tester.h" @@ -59,6 +58,7 @@ #include "components/network_session_configurator/common/network_switches.h" #include "components/permissions/permission_request_manager.h" #include "components/site_engagement/content/site_engagement_score.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "content/public/browser/browsing_data_remover.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/web_contents.h"
diff --git a/chrome/browser/push_messaging/push_messaging_notification_manager.cc b/chrome/browser/push_messaging/push_messaging_notification_manager.cc index 3133819..53c6ec4 100644 --- a/chrome/browser/push_messaging/push_messaging_notification_manager.cc +++ b/chrome/browser/push_messaging/push_messaging_notification_manager.cc
@@ -17,12 +17,12 @@ #include "base/strings/utf_string_conversions.h" #include "base/task/post_task.h" #include "build/chromeos_buildflags.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/notifications/platform_notification_service_factory.h" #include "chrome/browser/notifications/platform_notification_service_impl.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/push_messaging/push_messaging_constants.h" #include "chrome/grit/generated_resources.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "components/url_formatter/elide_url.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_task_traits.h"
diff --git a/chrome/browser/reading_list/android/empty_reading_list_manager.cc b/chrome/browser/reading_list/android/empty_reading_list_manager.cc index 9376e8f..d4e4d81a 100644 --- a/chrome/browser/reading_list/android/empty_reading_list_manager.cc +++ b/chrome/browser/reading_list/android/empty_reading_list_manager.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/reading_list/android/empty_reading_list_manager.h" +#include "base/logging.h" #include "components/bookmarks/browser/bookmark_utils.h" EmptyReadingListManager::EmptyReadingListManager() = default; @@ -17,6 +18,7 @@ const bookmarks::BookmarkNode* EmptyReadingListManager::Add( const GURL& url, const std::string& title) { + LOG(ERROR) << "Try to add reading list with empty reading list backend."; return nullptr; }
diff --git a/chrome/browser/reading_list/android/reading_list_manager.h b/chrome/browser/reading_list/android/reading_list_manager.h index efa7e53..28b589a3 100644 --- a/chrome/browser/reading_list/android/reading_list_manager.h +++ b/chrome/browser/reading_list/android/reading_list_manager.h
@@ -47,7 +47,7 @@ // Adds a reading list article to the unread section, and return the bookmark // node representation. The bookmark node is owned by this class. If there is // a duplicate URL, a new bookmark node will be created, and the old bookmark - // node pointer will be invalidated. + // node pointer will be invalidated. May return nullptr on error. virtual const bookmarks::BookmarkNode* Add(const GURL& url, const std::string& title) = 0;
diff --git a/chrome/browser/reading_list/android/reading_list_manager_impl.cc b/chrome/browser/reading_list/android/reading_list_manager_impl.cc index 98b8bcc..b2bf08d 100644 --- a/chrome/browser/reading_list/android/reading_list_manager_impl.cc +++ b/chrome/browser/reading_list/android/reading_list_manager_impl.cc
@@ -132,13 +132,13 @@ const BookmarkNode* ReadingListManagerImpl::Add(const GURL& url, const std::string& title) { DCHECK(reading_list_model_->loaded()); + if (!reading_list_model_->IsUrlSupported(url)) + return nullptr; // Add or swap the reading list entry. const auto& new_entry = reading_list_model_->AddEntry( url, title, reading_list::ADDED_VIA_CURRENT_APP); const auto* node = FindBookmarkByURL(new_entry.URL()); - DCHECK(node) - << "Bookmark node should have been create in ReadingListDidAddEntry()."; return node; }
diff --git a/chrome/browser/reading_list/android/reading_list_manager_impl_unittest.cc b/chrome/browser/reading_list/android/reading_list_manager_impl_unittest.cc index 1ca6a98..57670f5 100644 --- a/chrome/browser/reading_list/android/reading_list_manager_impl_unittest.cc +++ b/chrome/browser/reading_list/android/reading_list_manager_impl_unittest.cc
@@ -32,6 +32,7 @@ constexpr char kReadStatusKey[] = "read_status"; constexpr char kReadStatusRead[] = "true"; constexpr char kReadStatusUnread[] = "false"; +constexpr char kInvalidUTF8[] = "\xc3\x28"; class MockObserver : public ReadingListManager::Observer { public: @@ -228,6 +229,31 @@ EXPECT_EQ(url, new_node->url()); } +// If Add() with an invalid title, nullptr will be returned. +TEST_F(ReadingListManagerImplTest, AddInvalidTitle) { + GURL url(kURL); + + // Use an invalid UTF8 string. + base::string16 dummy; + EXPECT_FALSE( + base::UTF8ToUTF16(kInvalidUTF8, base::size(kInvalidUTF8), &dummy)); + const auto* new_node = Add(url, std::string(kInvalidUTF8)); + EXPECT_EQ(nullptr, new_node) + << "Should return nullptr when failed to parse the title."; +} + +// If Add() with an invalid URL, nullptr will be returned. +TEST_F(ReadingListManagerImplTest, AddInvalidURL) { + GURL invalid_url("chrome://flags"); + EXPECT_FALSE(reading_list_model()->IsUrlSupported(invalid_url)); + + // Use an invalid URL, the observer method ReadingListDidAddEntry() won't be + // invoked. + const auto* new_node = manager()->Add(invalid_url, kTitle); + EXPECT_EQ(nullptr, new_node) + << "Should return nullptr when the URL scheme is not supported."; +} + // Verifes SetReadStatus()/GetReadStatus() API. TEST_F(ReadingListManagerImplTest, ReadStatus) { GURL url(kURL);
diff --git a/chrome/browser/resource_coordinator/session_restore_policy.cc b/chrome/browser/resource_coordinator/session_restore_policy.cc index 2e4409f..d9e83dc 100644 --- a/chrome/browser/resource_coordinator/session_restore_policy.cc +++ b/chrome/browser/resource_coordinator/session_restore_policy.cc
@@ -18,7 +18,6 @@ #include "base/sequence_checker.h" #include "base/system/sys_info.h" #include "base/threading/sequenced_task_runner_handle.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/resource_coordinator/tab_manager_features.h" #include "chrome/common/url_constants.h" @@ -26,6 +25,7 @@ #include "components/performance_manager/public/graph/graph.h" #include "components/performance_manager/public/performance_manager.h" #include "components/performance_manager/public/persistence/site_data/site_data_reader.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/navigation_controller.h"
diff --git a/chrome/browser/resource_coordinator/tab_activity_watcher_unittest.cc b/chrome/browser/resource_coordinator/tab_activity_watcher_unittest.cc index ed86c99..f2563e97 100644 --- a/chrome/browser/resource_coordinator/tab_activity_watcher_unittest.cc +++ b/chrome/browser/resource_coordinator/tab_activity_watcher_unittest.cc
@@ -11,7 +11,6 @@ #include "base/test/scoped_feature_list.h" #include "base/test/simple_test_tick_clock.h" #include "build/chromeos_buildflags.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/resource_coordinator/lifecycle_unit.h" #include "chrome/browser/resource_coordinator/tab_activity_watcher.h" #include "chrome/browser/resource_coordinator/tab_lifecycle_unit.h" @@ -26,6 +25,7 @@ #include "chrome/test/base/chrome_render_view_host_test_harness.h" #include "chrome/test/base/test_browser_window.h" #include "chrome/test/base/testing_profile.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "components/ukm/content/source_url_recorder.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/render_widget_host.h"
diff --git a/chrome/browser/resource_coordinator/tab_metrics_logger.cc b/chrome/browser/resource_coordinator/tab_metrics_logger.cc index bc09856..0c46381 100644 --- a/chrome/browser/resource_coordinator/tab_metrics_logger.cc +++ b/chrome/browser/resource_coordinator/tab_metrics_logger.cc
@@ -12,7 +12,6 @@ #include "base/notreached.h" #include "base/time/time.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/resource_coordinator/tab_lifecycle_unit_external.h" #include "chrome/browser/resource_coordinator/tab_manager_features.h" @@ -28,6 +27,7 @@ #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/recently_audible_helper.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/web_contents.h"
diff --git a/chrome/browser/resource_coordinator/tab_metrics_logger_unittest.cc b/chrome/browser/resource_coordinator/tab_metrics_logger_unittest.cc index b412585d..6dfa9db 100644 --- a/chrome/browser/resource_coordinator/tab_metrics_logger_unittest.cc +++ b/chrome/browser/resource_coordinator/tab_metrics_logger_unittest.cc
@@ -12,7 +12,6 @@ #include "base/memory/ptr_util.h" #include "base/test/task_environment.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/resource_coordinator/tab_metrics_event.pb.h" #include "chrome/browser/resource_coordinator/tab_ranker/tab_features.h" #include "chrome/browser/resource_coordinator/tab_ranker/tab_features_test_helper.h" @@ -25,6 +24,7 @@ #include "chrome/test/base/chrome_render_view_host_test_harness.h" #include "chrome/test/base/test_browser_window.h" #include "chrome/test/base/testing_profile.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "components/ukm/test_ukm_recorder.h" #include "content/public/browser/web_contents.h" #include "content/public/test/web_contents_tester.h"
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn b/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn index 39009ad..185cb16 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn
@@ -453,6 +453,7 @@ "background/cursors_test.js", "background/download_handler_test.js", "background/editing/editing_test.js", + "background/editing/intent_handler_test.js", "background/keyboard_handler_test.js", "background/live_regions_test.js", "background/locale_output_helper_test.js",
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing/editable_line.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing/editable_line.js index ca8bf55..2791e5f 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing/editable_line.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing/editable_line.js
@@ -386,6 +386,11 @@ return this.startContainerValue_; } + /** @return {!cursors.Cursor} */ + get startCursor() { + return this.start_; + } + /** @return {boolean} */ hasCollapsedSelection() { return this.start_.equals(this.end_);
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing/intent_handler.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing/intent_handler.js index 4ae374f..05ea0e5 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing/intent_handler.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing/intent_handler.js
@@ -8,12 +8,18 @@ goog.provide('IntentHandler'); +goog.require('constants'); goog.require('editing.EditableLine'); +goog.require('Output'); goog.scope(function() { const AutomationIntent = chrome.automation.AutomationIntent; +const Dir = constants.Dir; const IntentCommandType = chrome.automation.IntentCommandType; const IntentTextBoundaryType = chrome.automation.IntentTextBoundaryType; +const Movement = cursors.Movement; +const Range = cursors.Range; +const Unit = cursors.Unit; /** * A stateless class that turns intents into speech. @@ -95,6 +101,26 @@ cur.speakLine(prev); return true; + case IntentTextBoundaryType.WORD_END: + case IntentTextBoundaryType.WORD_START: + const pos = cur.startCursor; + + // When movement goes to the end of a word, we actually want to describe + // the word itself; this is considered the previous word so impacts the + // movement type below. We can give further context e.g. by saying "end + // of word", if we chose to be more verbose. + const shouldMoveToPreviousWord = + intent.textBoundary === IntentTextBoundaryType.WORD_END; + const start = pos.move( + Unit.WORD, + shouldMoveToPreviousWord ? Movement.DIRECTIONAL : Movement.BOUND, + Dir.BACKWARD); + const end = pos.move(Unit.WORD, Movement.BOUND, Dir.FORWARD); + new Output() + .withSpeech(new Range(start, end), null, Output.EventType.NAVIGATE) + .go(); + return true; + // TODO: implement support. case IntentTextBoundaryType.FORMAT: case IntentTextBoundaryType.OBJECT: @@ -108,8 +134,6 @@ case IntentTextBoundaryType.SENTENCE_START: case IntentTextBoundaryType.SENTENCE_START_OR_END: case IntentTextBoundaryType.WEB_PAGE: - case IntentTextBoundaryType.WORD_END: - case IntentTextBoundaryType.WORD_START: case IntentTextBoundaryType.WORD_START_OR_END: break; }
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing/intent_handler_test.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing/intent_handler_test.js new file mode 100644 index 0000000..f668a3b --- /dev/null +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing/intent_handler_test.js
@@ -0,0 +1,136 @@ +// 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. + +GEN_INCLUDE([ + '../../testing/chromevox_next_e2e_test_base.js', + '../../../common/testing/assert_additions.js', +]); + +/** + * Test fixture for intent handler tests. + * These tests are written to be as "unit" test like as possible e.g. mocking + * out classes not under test but it runs under a full extension test + * environment to get things like extension api literals. + */ +ChromeVoxIntentHandlerTest = class extends ChromeVoxNextE2ETest { + /** @override */ + setUp() { + window.Dir = constants.Dir; + window.IntentTextBoundaryType = chrome.automation.IntentTextBoundaryType; + window.Movement = cursors.Movement; + window.Unit = cursors.Unit; + } +}; + +SYNC_TEST_F('ChromeVoxIntentHandlerTest', 'MoveByCharacter', function() { + let lastSpoken; + ChromeVox.tts.speak = (text) => lastSpoken = text; + + const intent = {textBoundary: IntentTextBoundaryType.CHARACTER}; + const move = IntentHandler.onMoveSelection.bind(null, intent); + + move({text: 'hello', startOffset: 0}); + assertEquals('h', lastSpoken); + move({text: 'hello', startOffset: 1}); + assertEquals('e', lastSpoken); + move({text: 'hello', startOffset: 2}); + assertEquals('l', lastSpoken); + move({text: 'hello', startOffset: 3}); + assertEquals('l', lastSpoken); + move({text: 'hello', startOffset: 4}); + assertEquals('o', lastSpoken); + move({text: 'hello', startOffset: 5}); + assertEquals('\n', lastSpoken); +}); + +SYNC_TEST_F('ChromeVoxIntentHandlerTest', 'MoveByWord', function() { + let calls = []; + const fakeLine = new class { + constructor() {} + + get startCursor() { + return new class { + move(...args) { + calls.push(['move', ...args]); + } + }; + } + }; + + Output.prototype.withSpeech = function(...args) { + calls.push(['withSpeech', ...args]); + return this; + }; + + Output.prototype.go = function() { + calls.push(['go']); + }; + + let intent = {textBoundary: IntentTextBoundaryType.WORD_END}; + IntentHandler.onMoveSelection(intent, fakeLine); + assertEquals(4, calls.length); + assertArraysEquals( + ['move', Unit.WORD, Movement.DIRECTIONAL, Dir.BACKWARD], calls[0]); + assertArraysEquals( + ['move', Unit.WORD, Movement.BOUND, Dir.FORWARD], calls[1]); + assertArraysEquals( + ['withSpeech', {}, null, Output.EventType.NAVIGATE], calls[2]); + assertArraysEquals(['go'], calls[3]); + + calls = []; + intent = {textBoundary: IntentTextBoundaryType.WORD_START}; + IntentHandler.onMoveSelection(intent, fakeLine); + assertEquals(4, calls.length); + assertArraysEquals( + ['move', Unit.WORD, Movement.BOUND, Dir.BACKWARD], calls[0]); + assertArraysEquals( + ['move', Unit.WORD, Movement.BOUND, Dir.FORWARD], calls[1]); + assertArraysEquals( + ['withSpeech', {}, null, Output.EventType.NAVIGATE], calls[2]); + assertArraysEquals(['go'], calls[3]); + + calls = []; + intent = {textBoundary: IntentTextBoundaryType.WORD_START_OR_END}; + IntentHandler.onMoveSelection(intent, fakeLine); + assertEquals(0, calls.length); +}); + +SYNC_TEST_F('ChromeVoxIntentHandlerTest', 'MoveByLine', function() { + const fakeLine = new class { + constructor() { + this.speakLineCount = 0; + } + + speakLine() { + this.speakLineCount++; + } + + get startCursor() { + return new class { + move() {} + }; + } + }; + + Output.prototype.withSpeech = function() { + return this; + }; + Output.prototype.go = function() {}; + + let intent = {textBoundary: IntentTextBoundaryType.LINE_END}; + IntentHandler.onMoveSelection(intent, fakeLine); + assertEquals(1, fakeLine.speakLineCount); + + intent = {textBoundary: IntentTextBoundaryType.LINE_START}; + IntentHandler.onMoveSelection(intent, fakeLine); + assertEquals(2, fakeLine.speakLineCount); + + intent = {textBoundary: IntentTextBoundaryType.LINE_START_OR_END}; + IntentHandler.onMoveSelection(intent, fakeLine); + assertEquals(3, fakeLine.speakLineCount); + + intent = {textBoundary: IntentTextBoundaryType.WORD_START}; + IntentHandler.onMoveSelection(intent, fakeLine); + assertEquals(3, fakeLine.speakLineCount); +});
diff --git a/chrome/browser/resources/chromeos/emoji_picker/BUILD.gn b/chrome/browser/resources/chromeos/emoji_picker/BUILD.gn index 1903bc3..220440c 100644 --- a/chrome/browser/resources/chromeos/emoji_picker/BUILD.gn +++ b/chrome/browser/resources/chromeos/emoji_picker/BUILD.gn
@@ -10,29 +10,33 @@ component_js_files = [ "emoji_picker.js", "emoji_group.js", + "emoji_group_button.js", "icons.js", ] -polymer_deps = - [ "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled" ] - resources_grd_file = "$target_gen_dir/resources.grd" components_grdp_file = "$target_gen_dir/components.grdp" +data_grdp_file = "$target_gen_dir/data.grdp" generate_grd("build_grd") { - deps = [ ":build_grdp" ] + deps = [ + ":build_components_grdp", + ":build_data_grdp", + ] grd_prefix = "emoji_picker" out_grd = resources_grd_file input_files = [ "index.html", "types.js", - "emoji_ordering.json", ] - grdp_files = [ components_grdp_file ] + grdp_files = [ + components_grdp_file, + data_grdp_file, + ] input_files_base_dir = rebase_path(".", "//") } -generate_grd("build_grdp") { +generate_grd("build_components_grdp") { deps = [ ":web_components" ] grd_prefix = "emoji_picker" out_grd = components_grdp_file @@ -40,6 +44,13 @@ input_files_base_dir = rebase_path(target_gen_dir, root_build_dir) } +generate_grd("build_data_grdp") { + grd_prefix = "emoji_picker" + out_grd = data_grdp_file + input_files = [ "emoji_13_1_ordering.json" ] + input_files_base_dir = rebase_path("//third_party/emoji-metadata/src", "//") +} + grit("resources") { # These arguments are needed since the grd is generated at build time. enable_input_discovery_for_gn_analyze = false @@ -56,21 +67,34 @@ js_library("emoji_picker") { deps = [ - ":types", - ":icons", - ":emoji_group", - "//ui/webui/resources/js:load_time_data.m", - "//third_party/polymer/v3_0/components-chromium/iron-icon", - ] + polymer_deps + ":emoji_group", + ":emoji_group_button", + ":types", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:assert.m", + ] } js_library("emoji_group") { - deps = [ ":types" ] + polymer_deps + deps = [ + ":types", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + ] +} + +js_library("emoji_group_button") { + deps = [ + ":icons", + "//third_party/polymer/v3_0/components-chromium/iron-icon", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + ] } js_library("icons") { - deps = [ "//third_party/polymer/v3_0/components-chromium/iron-iconset-svg" ] + - polymer_deps + deps = [ + "//third_party/polymer/v3_0/components-chromium/iron-iconset-svg", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + ] } js_library("types") { @@ -80,6 +104,7 @@ is_polymer3 = true deps = [ ":emoji_group", + ":emoji_group_button", ":emoji_picker", ":icons", ":types",
diff --git a/chrome/browser/resources/chromeos/emoji_picker/emoji_group_button.html b/chrome/browser/resources/chromeos/emoji_picker/emoji_group_button.html new file mode 100644 index 0000000..29022fd --- /dev/null +++ b/chrome/browser/resources/chromeos/emoji_picker/emoji_group_button.html
@@ -0,0 +1,21 @@ +<style> + button { + background-color: transparent; + border: 5px solid transparent; + padding: 0; + width: 36px; + } + + button:hover { + color: red; + } + + .active { + border-bottom: 5px solid blue; + color: blue; + } +</style> + +<button class$="[[_className(active)]]" on-click="handleClick"> + <iron-icon icon="[[icon]]"></iron-icon> +</button> \ No newline at end of file
diff --git a/chrome/browser/resources/chromeos/emoji_picker/emoji_group_button.js b/chrome/browser/resources/chromeos/emoji_picker/emoji_group_button.js new file mode 100644 index 0000000..b0c46bf --- /dev/null +++ b/chrome/browser/resources/chromeos/emoji_picker/emoji_group_button.js
@@ -0,0 +1,47 @@ +// Copyright 2020 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 './icons.js'; +import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js'; + +import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {GROUP_BUTTON_EVENT, GroupButtonEvent} from './types.js'; + +class EmojiGroupButton extends PolymerElement { + static get is() { + return 'emoji-group-button'; + } + + static get template() { + return html`{__html_template__}`; + } + + static get properties() { + return { + /** @type {string} */ + icon: {type: String}, + group: {type: String}, + active: {type: Boolean, value: false}, + }; + } + + constructor() { + super(); + } + + handleClick(ev) { + /** @type {GroupButtonEvent} */ + const event = new CustomEvent( + GROUP_BUTTON_EVENT, + {bubbles: true, composed: true, detail: {group: this.group}}); + this.dispatchEvent(event); + } + + _className(active) { + return active ? 'active' : ''; + } +} + +customElements.define(EmojiGroupButton.is, EmojiGroupButton);
diff --git a/chrome/browser/resources/chromeos/emoji_picker/emoji_picker.html b/chrome/browser/resources/chromeos/emoji_picker/emoji_picker.html index 20f790d8..d087a7f 100644 --- a/chrome/browser/resources/chromeos/emoji_picker/emoji_picker.html +++ b/chrome/browser/resources/chromeos/emoji_picker/emoji_picker.html
@@ -8,6 +8,17 @@ min-height: 343px; width: calc(36px * 7); } + + .emoji-tabs { + display: flex; + overflow-x: scroll; + width: 100%; + } + + .emoji-groups { + max-height: 400px; + overflow-y: scroll; + } </style> <div class="emoji-picker"> @@ -18,21 +29,24 @@ ></input> <div class="emoji-tabs"> - <iron-icon icon="emoji_picker:schedule"></iron-icon> - <iron-icon icon="emoji_picker:insert_emoticon"></iron-icon> - <iron-icon icon="emoji_picker:emoji_people"></iron-icon> - <iron-icon icon="emoji_picker:emoji_nature"></iron-icon> - <iron-icon icon="emoji_picker:emoji_food_beverage"></iron-icon> - <iron-icon icon="emoji_picker:emoji_transportation"></iron-icon> - <iron-icon icon="emoji_picker:emoji_events"></iron-icon> - <iron-icon icon="emoji_picker:emoji_objects"></iron-icon> - <iron-icon icon="emoji_picker:emoji_symbols"></iron-icon> - <iron-icon icon="emoji_picker:flag"></iron-icon> + <template is="dom-repeat" items="[[groups]]"> + <emoji-group-button group="[[item.group]]" active="[[item.active]]" + icon="[[item.icon]]"></emoji-group-button> + </template> </div> <div class="emoji-groups w-100"> - <template is="dom-repeat" items="{{emojiData}}"> - <emoji-group data="[[item]]"></emoji-group> + <!-- + group-history is the "frequently used" group and is populated in code, + whereas the other groups are created from the emoji metadata. + --> + <div id="group-history"> + <emoji-group data="[[history]]"></emoji-group> + </div> + <template is="dom-repeat" items="[[emojiData]]"> + <div id="group-[[index]]"> + <emoji-group data="[[item]]"></emoji-group> + </div> </template> </div> </div> \ No newline at end of file
diff --git a/chrome/browser/resources/chromeos/emoji_picker/emoji_picker.js b/chrome/browser/resources/chromeos/emoji_picker/emoji_picker.js index 0527ede..2670e75 100644 --- a/chrome/browser/resources/chromeos/emoji_picker/emoji_picker.js +++ b/chrome/browser/resources/chromeos/emoji_picker/emoji_picker.js
@@ -2,17 +2,29 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import './strings.m.js'; -import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js'; import './icons.js'; import './emoji_group.js'; +import './emoji_group_button.js'; -import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; +import {assert} from 'chrome://resources/js/assert.m.js'; import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {EmojiData} from './types.js'; +import {EmojiData, EmojiGroup, GROUP_BUTTON_EVENT} from './types.js'; -const EMOJI_ORDERING_JSON = '/emoji_ordering.json'; +const EMOJI_ORDERING_JSON = '/emoji_13_1_ordering.json'; + +const GROUP_TABS = [ + {icon: 'emoji_picker:schedule', group: 'history', active: true}, + {icon: 'emoji_picker:insert_emoticon', group: '0', active: false}, + {icon: 'emoji_picker:emoji_people', group: '1', active: false}, + {icon: 'emoji_picker:emoji_nature', group: '2', active: false}, + {icon: 'emoji_picker:emoji_food_beverage', group: '3', active: false}, + {icon: 'emoji_picker:emoji_transportation', group: '4', active: false}, + {icon: 'emoji_picker:emoji_events', group: '5', active: false}, + {icon: 'emoji_picker:emoji_objects', group: '6', active: false}, + {icon: 'emoji_picker:emoji_symbols', group: '7', active: false}, + {icon: 'emoji_picker:flag', group: '8', active: false}, +]; class EmojiPicker extends PolymerElement { static get is() { @@ -25,9 +37,11 @@ static get properties() { return { - emoji: {type: Array}, + groups: {type: Array}, /** @type {?EmojiData} */ emojiData: {type: Object}, + /** @type {EmojiGroup} */ + history: {type: Object}, search: {type: String}, }; } @@ -35,14 +49,55 @@ constructor() { super(); + this.groups = GROUP_TABS; + this.emojiData = []; + // TODO(https://crbug.com/1164828): replace placeholder frequently used + // data. + this.history = { + 'group': 'Frequently used', + 'emoji': [ + { + 'base': [128512], + 'alternates': [], + }, + { + 'base': [128513], + 'alternates': [], + }, + ], + }; + this.search = ''; + } + + ready() { + super.ready(); + const xhr = new XMLHttpRequest(); xhr.onloadend = () => this.onEmojiDataLoaded(xhr.responseText); xhr.open('GET', EMOJI_ORDERING_JSON); xhr.send(); - this.emojiData = []; - this.emoji = loadTimeData.getString('emoji').split(','); - this.search = ''; + this.addEventListener( + GROUP_BUTTON_EVENT, ev => this.selectGroup(ev.detail.group)); + } + + /** + * @param {string} newGroup + */ + selectGroup(newGroup) { + let activeGroup = null; + // set active to true for selected group and false for others. + this.groups.forEach((g, i) => { + const isActive = g.group === newGroup; + this.set(['groups', i, 'active'], isActive); + if (isActive) { + activeGroup = g; + } + }); + assert(activeGroup, 'no group button was activated'); + // scroll to selected group's element. + this.shadowRoot.getElementById(`group-${activeGroup.group}`) + .scrollIntoView(); } _formatEmojiData(emojiData) {
diff --git a/chrome/browser/resources/chromeos/emoji_picker/emoji_ordering.json b/chrome/browser/resources/chromeos/emoji_picker/emoji_test_ordering.json similarity index 100% rename from chrome/browser/resources/chromeos/emoji_picker/emoji_ordering.json rename to chrome/browser/resources/chromeos/emoji_picker/emoji_test_ordering.json
diff --git a/chrome/browser/resources/chromeos/emoji_picker/types.js b/chrome/browser/resources/chromeos/emoji_picker/types.js index b43121af..d83b712 100644 --- a/chrome/browser/resources/chromeos/emoji_picker/types.js +++ b/chrome/browser/resources/chromeos/emoji_picker/types.js
@@ -15,4 +15,11 @@ /** * @typedef {Array<EmojiGroup>} EmojiData */ -export let EmojiData; \ No newline at end of file +export let EmojiData; + +/** + * @typedef {!CustomEvent<{group: string}>} GroupButtonEvent + */ +export let GroupButtonEvent; + +export const GROUP_BUTTON_EVENT = 'group-button';
diff --git a/chrome/browser/resources/new_tab_page/app.html b/chrome/browser/resources/new_tab_page/app.html index 057ffc2df..c9b5252 100644 --- a/chrome/browser/resources/new_tab_page/app.html +++ b/chrome/browser/resources/new_tab_page/app.html
@@ -82,15 +82,6 @@ width: var(--ntp-search-box-width); } - :host([modules-enabled_]) ntp-middle-slot-promo { - width: var(--ntp-search-box-width); - } - - :host(:not([modules-enabled_])) ntp-middle-slot-promo { - bottom: 16px; - position: fixed; - } - ntp-realbox { visibility: hidden; } @@ -244,19 +235,6 @@ font-size: .75rem; } - @keyframes fadein { - from { - opacity: 0; - } - to { - opacity: 1; - } - } - - .fadein { - animation: 100ms ease-in-out fadein; - } - svg { position: fixed; } @@ -361,6 +339,13 @@ <div id="oneGoogleBarOverlayBackdrop"></div> <svg> <defs> - <clipPath id="oneGoogleBarClipPath"></clipPath> + <clipPath id="oneGoogleBarClipPath"> + <!-- Set an initial non-empty clip-path so the OneGoogleBar resize events + are processed. When the clip-path is empty, it's possible for the + OneGoogleBar to get into a state where it does not send the + 'overlayUpdates' message which is used to populate this + clip-path. --> + <rect x="0" y="0" width="1" height="1"></rect> + </clipPath> </defs> </svg>
diff --git a/chrome/browser/resources/new_tab_page/app.js b/chrome/browser/resources/new_tab_page/app.js index a054f731..69b35034 100644 --- a/chrome/browser/resources/new_tab_page/app.js +++ b/chrome/browser/resources/new_tab_page/app.js
@@ -858,19 +858,6 @@ /** @private */ onMiddleSlotPromoLoaded_() { this.middleSlotPromoLoaded_ = true; - // The promo is always shown when modules are enabled since it will not - // overlap with other elements. - if (this.modulesEnabled_) { - return; - } - const onResize = () => { - const promoElement = $$(this, 'ntp-middle-slot-promo'); - promoElement.hidden = - $$(this, '#mostVisited').getBoundingClientRect().bottom >= - promoElement.offsetTop; - }; - this.eventTracker_.add(window, 'resize', onResize); - onResize(); } /** @private */
diff --git a/chrome/browser/resources/new_tab_page/middle_slot_promo.html b/chrome/browser/resources/new_tab_page/middle_slot_promo.html index f2657ea4..e0b9364 100644 --- a/chrome/browser/resources/new_tab_page/middle_slot_promo.html +++ b/chrome/browser/resources/new_tab_page/middle_slot_promo.html
@@ -1,15 +1,8 @@ <style> :host { font-size: 12px; - white-space: pre; - } - - :host([modules-enabled_]):host { - font-size: 13px; - } - - :host(:not([modules-enabled_])):host { max-width: 537px; + white-space: pre; } #container { @@ -27,11 +20,6 @@ padding-inline-start: 8px; } - :host([modules-enabled_]) #container { - border-radius: 5px; - height: 48px; - } - a { color: var(--cr-link-color); cursor: pointer; @@ -59,13 +47,6 @@ width: 24px; } - :host([modules-enabled_]) img { - background-color: var(--google-grey-refresh-100); - height: 22px; - padding: 5px; - width: 22px; - } - @media (prefers-color-scheme: dark) { img { background-color: var(--google-grey-200); @@ -78,4 +59,3 @@ } </style> <!-- Promo parts are added by JS. --> -<div id="container"></div>
diff --git a/chrome/browser/resources/new_tab_page/middle_slot_promo.js b/chrome/browser/resources/new_tab_page/middle_slot_promo.js index e011aaa..7de830c 100644 --- a/chrome/browser/resources/new_tab_page/middle_slot_promo.js +++ b/chrome/browser/resources/new_tab_page/middle_slot_promo.js
@@ -4,119 +4,28 @@ import 'chrome://resources/cr_elements/shared_vars_css.m.js'; -import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; - import {BrowserProxy} from './browser_proxy.js'; import {ImgElement} from './img.js'; import {PromoBrowserCommandProxy} from './promo_browser_command_proxy.js'; -// Element that requests and renders the middle-slot promo. The element is -// hidden until the promo is rendered, If no promo exists or the promo is empty, -// the element remains hidden. -class MiddleSlotPromoElement extends PolymerElement { - static get is() { - return 'ntp-middle-slot-promo'; +/** + * If a promo exists with content and can be shown, an element containing + * the rendered promo is returned with an id #container. Otherwise, null is + * returned. + * @return {!Promise<Element>} + */ +export async function renderPromo() { + const browserHandler = BrowserProxy.getInstance().handler; + const promoBrowserCommandHandler = + PromoBrowserCommandProxy.getInstance().handler; + const {promo} = await browserHandler.getPromo(); + if (!promo) { + return null; } - static get template() { - return html`{__html_template__}`; - } - - static get properties() { - return { - /** @type {boolean} */ - hidden: { - type: Boolean, - value: true, - reflectToAttribute: true, - }, - - /** @private */ - modulesEnabled_: { - type: Boolean, - value: () => loadTimeData.getBoolean('modulesEnabled'), - reflectToAttribute: true, - }, - - /** - * The list of browser commands to run, if any. Used to decide whether the - * promo can be shown. - * @type {!Array<number>} - * @private - */ - /** @private */ - commandIds_: { - type: Object, - value: () => [], - }, - }; - } - - constructor() { - super(); - /** @private {newTabPage.mojom.PageHandlerRemote} */ - this.pageHandler_ = BrowserProxy.getInstance().handler; - } - - /** @override */ - connectedCallback() { - super.connectedCallback(); - this.pageHandler_.getPromo().then(({promo}) => { - if (promo) { - promo.middleSlotParts.forEach(({image, link, text}) => { - let el; - if (image) { - el = new ImgElement(); - el.autoSrc = image.imageUrl.url; - if (image.target) { - const anchor = this.createAnchor_(image.target); - if (anchor) { - anchor.appendChild(el); - el = anchor; - } - } - el.classList.add('image'); - } else if (link) { - el = this.createAnchor_(link.url); - } else if (text) { - el = document.createElement('span'); - } - const linkOrText = link || text; - if (el && linkOrText) { - el.innerText = linkOrText.text; - if (linkOrText.color) { - el.style.color = linkOrText.color; - } - } - if (el) { - this.$.container.appendChild(el); - } - }); - this.maybeShowPromo_().then(canShow => { - if (canShow) { - this.pageHandler_.onPromoRendered( - BrowserProxy.getInstance().now(), promo.logUrl || null); - this.hidden = false; - } - this.dispatchEvent(new Event( - 'ntp-middle-slot-promo-loaded', {bubbles: true, composed: true})); - }); - } else { - // Dispatch this event even if there is no promo as Modules wait for the - // promo to be loaded before showing. - this.dispatchEvent(new Event( - 'ntp-middle-slot-promo-loaded', {bubbles: true, composed: true})); - } - }); - } - - /** - * @param {!url.mojom.Url} target - * @return {HTMLAnchorElement} - * @private - */ - createAnchor_(target) { + const commandIds = []; + const createAnchor = target => { const commandIdMatch = /^command:(\d+)$/.exec(target.url); if (!commandIdMatch && !target.url.startsWith('https://')) { return null; @@ -132,38 +41,98 @@ .includes(commandId)) { commandId = promoBrowserCommand.mojom.Command.kUnknownCommand; } - this.commandIds_.push(commandId); + commandIds.push(commandId); } const onClick = event => { if (commandId !== null) { - PromoBrowserCommandProxy.getInstance().handler.executeCommand( - commandId, { - middleButton: event.button === 1, - altKey: event.altKey, - ctrlKey: event.ctrlKey, - metaKey: event.metaKey, - shiftKey: event.shiftKey, - }); + promoBrowserCommandHandler.executeCommand(commandId, { + middleButton: event.button === 1, + altKey: event.altKey, + ctrlKey: event.ctrlKey, + metaKey: event.metaKey, + shiftKey: event.shiftKey, + }); } - this.pageHandler_.onPromoLinkClicked(); + browserHandler.onPromoLinkClicked(); }; // 'auxclick' handles the middle mouse button which does not trigger a // 'click' event. el.addEventListener('auxclick', onClick); el.addEventListener('click', onClick); return el; + }; + + let hasContent = false; + const container = document.createElement('div'); + container.id = 'container'; + promo.middleSlotParts.forEach(({image, link, text}) => { + let el; + if (image) { + el = new ImgElement(); + el.autoSrc = image.imageUrl.url; + if (image.target) { + const anchor = createAnchor(image.target); + if (anchor) { + anchor.appendChild(el); + el = anchor; + } + } + el.classList.add('image'); + } else if (link) { + el = createAnchor(link.url); + } else if (text) { + el = document.createElement('span'); + } + const linkOrText = link || text; + if (el && linkOrText) { + el.innerText = linkOrText.text; + if (linkOrText.color) { + el.style.color = linkOrText.color; + } + } + if (el) { + hasContent = true; + container.appendChild(el); + } + }); + + const canShow = + (await Promise.all(commandIds.map( + commandId => + promoBrowserCommandHandler.canShowPromoWithCommand(commandId)))) + .every(({canShow}) => canShow); + if (hasContent && canShow) { + browserHandler.onPromoRendered( + BrowserProxy.getInstance().now(), promo.logUrl || null); + return container; + } + return null; +} + +// Element that requests and renders the middle-slot promo. The element is +// hidden until the promo is rendered, If no promo exists or the promo is empty, +// the element remains hidden. +class MiddleSlotPromoElement extends PolymerElement { + static get is() { + return 'ntp-middle-slot-promo'; } - /** - * @return {!Promise<boolean>} Whether or not the promo can be shown by - * checking all command IDs seen in the promo. - * @private - */ - async maybeShowPromo_() { - const {handler} = PromoBrowserCommandProxy.getInstance(); - const promises = this.commandIds_.map( - commandId => handler.canShowPromoWithCommand(commandId)); - return (await Promise.all(promises)).every(({canShow}) => canShow); + static get template() { + return html`{__html_template__}`; + } + + /** @override */ + ready() { + super.ready(); + this.hidden = true; + renderPromo().then(container => { + if (container) { + this.shadowRoot.appendChild(container); + this.hidden = false; + } + this.dispatchEvent(new Event( + 'ntp-middle-slot-promo-loaded', {bubbles: true, composed: true})); + }); } }
diff --git a/chrome/browser/resources/pdf/constants.js b/chrome/browser/resources/pdf/constants.js index 9baa2a5..df87987 100644 --- a/chrome/browser/resources/pdf/constants.js +++ b/chrome/browser/resources/pdf/constants.js
@@ -19,12 +19,13 @@ /** * @typedef {{ - * title: string, * author: string, - * subject: string, + * canSerializeDocument: boolean, * creator: string, * producer: string, - * canSerializeDocument: boolean, + * subject: string, + * title: string, + * version: string, * }} */ export let DocumentMetadata;
diff --git a/chrome/browser/resources/pdf/elements/viewer-properties-dialog.html b/chrome/browser/resources/pdf/elements/viewer-properties-dialog.html index cf85812..7279aad 100644 --- a/chrome/browser/resources/pdf/elements/viewer-properties-dialog.html +++ b/chrome/browser/resources/pdf/elements/viewer-properties-dialog.html
@@ -88,7 +88,9 @@ </tr> <tr> <td class="name">$i18n{propertiesPdfVersion}</td> - <td class="value" id="pdf-version">-</td> + <td class="value" id="pdf-version"> + [[getOrPlaceholder_(documentMetadata.version)]] + </td> </tr> <tr> <td class="name">$i18n{propertiesPageCount}</td>
diff --git a/chrome/browser/resources/pdf/navigator.js b/chrome/browser/resources/pdf/navigator.js index 5388ffa..1e37b1e 100644 --- a/chrome/browser/resources/pdf/navigator.js +++ b/chrome/browser/resources/pdf/navigator.js
@@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {NativeEventTarget as EventTarget} from 'chrome://resources/js/cr/event_target.m.js'; import {OpenPdfParamsParser} from './open_pdf_params_parser.js'; import {Viewport} from './viewport.js'; @@ -104,14 +103,6 @@ /** @private {!NavigatorDelegate} */ this.navigatorDelegate_ = navigatorDelegate; - - /** @private {!EventTarget} */ - this.eventTarget_ = new EventTarget(); - } - - /** @return {!EventTarget} */ - getEventTarget() { - return this.eventTarget_; } /** @@ -120,10 +111,11 @@ * @param {string} urlString The URL to navigate to. * @param {!WindowOpenDisposition} disposition The window open * disposition when navigating to the new URL. + * @return {!Promise<void>} When navigation has completed (used for testing). */ navigate(urlString, disposition) { if (urlString.length === 0) { - return; + return Promise.resolve(); } // If |urlFragment| starts with '#', then it's for the same URL with a @@ -145,17 +137,19 @@ try { url = new URL(urlString); } catch (err) { - return; + return Promise.reject(err); } if (!this.isValidUrl_(url)) { - return; + return Promise.resolve(); } + let whenDone = Promise.resolve(); + switch (disposition) { case WindowOpenDisposition.CURRENT_TAB: - this.paramsParser_.getViewportFromUrlParams( - url.href, this.onViewportReceived_.bind(this)); + whenDone = this.paramsParser_.getViewportFromUrlParams(url.href).then( + this.onViewportReceived_.bind(this)); break; case WindowOpenDisposition.NEW_BACKGROUND_TAB: this.navigatorDelegate_.navigateInNewTab(url.href, false); @@ -169,15 +163,14 @@ case WindowOpenDisposition.SAVE_TO_DISK: // TODO(jaepark): Alt + left clicking a link in PDF should // download the link. - this.paramsParser_.getViewportFromUrlParams( - url.href, this.onViewportReceived_.bind(this)); + whenDone = this.paramsParser_.getViewportFromUrlParams(url.href).then( + this.onViewportReceived_.bind(this)); break; default: break; } - // Dispatch events for tests. - this.eventTarget_.dispatchEvent(new CustomEvent('navigate-for-testing')); + return whenDone; } /**
diff --git a/chrome/browser/resources/pdf/open_pdf_params_parser.js b/chrome/browser/resources/pdf/open_pdf_params_parser.js index 1828eaa8..7ded80f 100644 --- a/chrome/browser/resources/pdf/open_pdf_params_parser.js +++ b/chrome/browser/resources/pdf/open_pdf_params_parser.js
@@ -11,11 +11,11 @@ * url: (string|undefined), * zoom: (number|undefined), * view: (!FittingType|undefined), - * viewPosition: (!Point|undefined), + * viewPosition: (number|undefined), * position: (!Object|undefined), * }} */ -let OpenPdfParams; +export let OpenPdfParams; // Parses the open pdf parameters passed in the url to set initial viewport // settings for opening the pdf. @@ -224,10 +224,9 @@ * See http://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/ * pdfs/pdf_open_parameters.pdf for details. * @param {string} url that needs to be parsed. - * @param {function(!OpenPdfParams)} callback function to be called with - * viewport info. + * @return {!Promise<!OpenPdfParams>} */ - getViewportFromUrlParams(url, callback) { + async getViewportFromUrlParams(url) { const params = {}; params['url'] = url; @@ -254,22 +253,23 @@ } if (params.page === undefined && urlParams.has('nameddest')) { - this.getNamedDestinationCallback_( - /** @type {string} */ (urlParams.get('nameddest'))) - .then(data => { - if (data.pageNumber !== -1) { - params.page = data.pageNumber; - } - if (data.namedDestinationView) { - Object.assign( - params, - this.parseNameddestViewParam_( - /** @type {string} */ (data.namedDestinationView))); - } - callback(params); - }); - } else { - callback(params); + const data = await this.getNamedDestinationCallback_( + /** @type {string} */ (urlParams.get('nameddest'))); + + if (data.pageNumber !== -1) { + params.page = data.pageNumber; + } + + if (data.namedDestinationView) { + Object.assign( + params, + this.parseNameddestViewParam_( + /** @type {string} */ (data.namedDestinationView))); + } + + return params; } + + return Promise.resolve(params); } }
diff --git a/chrome/browser/resources/pdf/pdf_viewer_base.js b/chrome/browser/resources/pdf/pdf_viewer_base.js index 068b345..40cfb5e3 100644 --- a/chrome/browser/resources/pdf/pdf_viewer_base.js +++ b/chrome/browser/resources/pdf/pdf_viewer_base.js
@@ -12,7 +12,7 @@ import {FittingType, Point} from './constants.js'; import {ContentController, MessageData, PluginController, PluginControllerEventType} from './controller.js'; import {PDFMetrics, UserAction} from './metrics.js'; -import {OpenPdfParamsParser} from './open_pdf_params_parser.js'; +import {OpenPdfParams, OpenPdfParamsParser} from './open_pdf_params_parser.js'; import {LoadState} from './pdf_scripting_api.js'; import {DocumentDimensionsMessageData, MessageObject} from './pdf_viewer_utils.js'; import {Viewport} from './viewport.js'; @@ -318,8 +318,8 @@ if (this.lastViewportPosition) { this.viewport_.position = this.lastViewportPosition; } - this.paramsParser.getViewportFromUrlParams( - this.originalUrl, params => this.handleURLParams_(params)); + this.paramsParser.getViewportFromUrlParams(this.originalUrl) + .then(this.handleURLParams_.bind(this)); this.setLoadState(LoadState.SUCCESS); this.sendDocumentLoadedMessage(); while (this.delayedScriptingMessages_.length > 0) { @@ -497,7 +497,7 @@ * Handle open pdf parameters. This function updates the viewport as per * the parameters mentioned in the url while opening pdf. The order is * important as later actions can override the effects of previous actions. - * @param {Object} params The open params passed in the URL. + * @param {!OpenPdfParams} params The open params passed in the URL. * @private */ handleURLParams_(params) {
diff --git a/chrome/browser/resources/settings/about_page/about_page_browser_proxy.js b/chrome/browser/resources/settings/about_page/about_page_browser_proxy.js index 4942b9f..276bf6a 100644 --- a/chrome/browser/resources/settings/about_page/about_page_browser_proxy.js +++ b/chrome/browser/resources/settings/about_page/about_page_browser_proxy.js
@@ -194,6 +194,9 @@ // </if> // <if expr="chromeos"> + /** Opens the diagnostics page. */ + openDiagnostics() {} + /** Opens the OS help page. */ openOsHelpPage() {} @@ -308,6 +311,11 @@ // <if expr="chromeos"> /** @override */ + openDiagnostics() { + chrome.send('openDiagnostics'); + } + + /** @override */ openOsHelpPage() { chrome.send('openOsHelpPage'); }
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 a02f118..a5c8652 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
@@ -183,6 +183,12 @@ deep-link-focus-id$="[[Setting.kReportAnIssue]]"> </cr-link-row> </if> + <cr-link-row class="hr" id="diagnostics" + on-click="onDiagnosticsClick_" + hidden$="[[!showDiagnosticsApp_]]" + label="$i18n{aboutDiagnostics}" external + deep-link-focus-id$="[[Setting.kDiagnostics]]"> + </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 916177b..e2a905b 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
@@ -114,6 +114,14 @@ 'currentUpdateStatusEvent_, hasCheckedForUpdates_, hasEndOfLife_)', }, + /** @private */ + showDiagnosticsApp_: { + type: Boolean, + value: function() { + return loadTimeData.getBoolean('diagnosticsAppEnabled'); + } + }, + /** @private {!Map<string, string>} */ focusConfig_: { type: Object, @@ -168,6 +176,7 @@ chromeos.settings.mojom.Setting.kGetHelpWithChromeOs, chromeos.settings.mojom.Setting.kReportAnIssue, chromeos.settings.mojom.Setting.kTermsOfService, + chromeos.settings.mojom.Setting.kDiagnostics, ]), }, }, @@ -301,6 +310,13 @@ }, /** @private */ + onDiagnosticsClick_() { + assert(this.showDiagnosticsApp_); + this.aboutBrowserProxy_.openDiagnostics(); + settings.recordSettingChange(chromeos.settings.mojom.Setting.kDiagnostics); + }, + + /** @private */ onRelaunchClick_() { settings.recordSettingChange(); this.lifetimeBrowserProxy_.relaunch();
diff --git a/chrome/browser/resources/settings/site_settings/chooser_exception_list.js b/chrome/browser/resources/settings/site_settings/chooser_exception_list.js index 89328e6..bbab832 100644 --- a/chrome/browser/resources/settings/site_settings/chooser_exception_list.js +++ b/chrome/browser/resources/settings/site_settings/chooser_exception_list.js
@@ -197,7 +197,7 @@ if (!this.updateList( 'chooserExceptions', x => x.displayName, exceptions, - true /* uidBasedUpdate */)) { + true /* identityBasedUpdate= */)) { // The chooser objects have not been changed, so check if their site // permissions have changed. The |exceptions| and |this.chooserExceptions| // arrays should be the same length.
diff --git a/chrome/browser/resources/signin/profile_picker/BUILD.gn b/chrome/browser/resources/signin/profile_picker/BUILD.gn index 1cd3987..bed524dd 100644 --- a/chrome/browser/resources/signin/profile_picker/BUILD.gn +++ b/chrome/browser/resources/signin/profile_picker/BUILD.gn
@@ -213,6 +213,7 @@ ":profile_card_menu", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//ui/webui/resources/cr_elements/cr_button:cr_button.m", + "//ui/webui/resources/js:i18n_behavior.m", ] }
diff --git a/chrome/browser/resources/signin/profile_picker/manage_profiles_browser_proxy.js b/chrome/browser/resources/signin/profile_picker/manage_profiles_browser_proxy.js index 304dea62..c953358 100644 --- a/chrome/browser/resources/signin/profile_picker/manage_profiles_browser_proxy.js +++ b/chrome/browser/resources/signin/profile_picker/manage_profiles_browser_proxy.js
@@ -129,6 +129,9 @@ * @param {string} profileName */ setProfileName(profilePath, profileName) {} + + /** Records impression of a sign-in promo to metrics. */ + recordSignInPromoImpression() {} } /** @implements {ManageProfilesBrowserProxy} */ @@ -195,6 +198,11 @@ setProfileName(profilePath, profileName) { chrome.send('setProfileName', [profilePath, profileName]); } + + /** @override */ + recordSignInPromoImpression() { + chrome.send('recordSignInPromoImpression'); + } } addSingletonGetter(ManageProfilesBrowserProxyImpl);
diff --git a/chrome/browser/resources/signin/profile_picker/profile_card.html b/chrome/browser/resources/signin/profile_picker/profile_card.html index 7add1911..78207f4 100644 --- a/chrome/browser/resources/signin/profile_picker/profile_card.html +++ b/chrome/browser/resources/signin/profile_picker/profile_card.html
@@ -135,7 +135,7 @@ <div id="profileCardContainer"> <cr-button on-click="onProfileClick_" - aria-label="[[profileState.localProfileName]]"> + aria-label="[[i18n('profileCardButtonLabel', profileState.localProfileName)]]"> <div id="avatarContainer"> <img class="profile-avatar" alt="" src="[[profileState.avatarIcon]]"> <div id="iconContainer" hidden="[[!profileState.isManaged]]">
diff --git a/chrome/browser/resources/signin/profile_picker/profile_card.js b/chrome/browser/resources/signin/profile_picker/profile_card.js index 8c2803b7..feba5dd 100644 --- a/chrome/browser/resources/signin/profile_picker/profile_card.js +++ b/chrome/browser/resources/signin/profile_picker/profile_card.js
@@ -8,7 +8,9 @@ import './profile_picker_shared_css.js'; import 'chrome://resources/cr_elements/cr_input/cr_input.m.js'; +import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js'; import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + import {ManageProfilesBrowserProxy, ManageProfilesBrowserProxyImpl, ProfileState} from './manage_profiles_browser_proxy.js'; Polymer({ @@ -16,6 +18,8 @@ _template: html`{__html_template__}`, + behaviors: [I18nBehavior], + properties: { /** @type {!ProfileState} */ profileState: {
diff --git a/chrome/browser/resources/signin/profile_picker/profile_creation_flow/profile_type_choice.js b/chrome/browser/resources/signin/profile_picker/profile_creation_flow/profile_type_choice.js index 708aeb29..aecfe98 100644 --- a/chrome/browser/resources/signin/profile_picker/profile_creation_flow/profile_type_choice.js +++ b/chrome/browser/resources/signin/profile_picker/profile_creation_flow/profile_type_choice.js
@@ -11,7 +11,7 @@ import {WebUIListenerBehavior} from 'chrome://resources/js/web_ui_listener_behavior.m.js'; import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {AutogeneratedThemeColorInfo} from '../manage_profiles_browser_proxy.js'; +import {AutogeneratedThemeColorInfo, ManageProfilesBrowserProxyImpl} from '../manage_profiles_browser_proxy.js'; import {navigateToPreviousRoute, navigateToStep, ProfileCreationSteps, Routes} from '../navigation_behavior.js'; Polymer({ @@ -43,6 +43,7 @@ 'load-signin-finished', success => this.handleLoadSigninFinished_(success)); FocusOutlineManager.forDocument(document); + ManageProfilesBrowserProxyImpl.getInstance().recordSignInPromoImpression(); }, /** @private */
diff --git a/chrome/browser/resources/tab_search/BUILD.gn b/chrome/browser/resources/tab_search/BUILD.gn index a32940b..ab330aa6 100644 --- a/chrome/browser/resources/tab_search/BUILD.gn +++ b/chrome/browser/resources/tab_search/BUILD.gn
@@ -182,6 +182,7 @@ deps = [ "//third_party/polymer/v3_0/components-chromium/iron-selector:iron-selector", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:list_property_update_behavior.m", ] }
diff --git a/chrome/browser/resources/tab_search/app.html b/chrome/browser/resources/tab_search/app.html index c054c21..78cc37b 100644 --- a/chrome/browser/resources/tab_search/app.html +++ b/chrome/browser/resources/tab_search/app.html
@@ -58,7 +58,7 @@ search-result-text="[[searchResultText_]]"> </tab-search-search-field> <div hidden="[[!filteredOpenTabs_.length]]"> - <infinite-list id="tabsList" items="[[filteredOpenTabs_]]" > + <infinite-list id="tabsList" items="[[filteredOpenTabs_]]"> <template is="dom-repeat"> <tab-search-item id="[[item.tab.tabId]]" aria-label="[[ariaLabel_(item)]]" class="mwb-list-item" data="[[item]]" on-click="onItemClick_"
diff --git a/chrome/browser/resources/tab_search/app.js b/chrome/browser/resources/tab_search/app.js index 6f154ac1..3d28fb4 100644 --- a/chrome/browser/resources/tab_search/app.js +++ b/chrome/browser/resources/tab_search/app.js
@@ -40,10 +40,9 @@ value: '', }, - /** @private {?Array<!WindowTabs>} */ + /** @private {?Array<!TabData>}*/ openTabs_: { type: Array, - observer: 'openTabsChanged_', }, /** @private {!Array<!TabData>} */ @@ -169,7 +168,7 @@ 'Tabs.TabSearch.WebUI.TabListDataReceived', Math.round(Date.now() - getTabsStartTimestamp)); - this.openTabs_ = profileTabs.windows; + this.openTabsChanged_(profileTabs.windows); }); } @@ -178,19 +177,13 @@ * @private */ onTabUpdated_(updatedTab) { - const updatedTabId = updatedTab.tabId; - const windows = this.openTabs_; - if (windows) { - for (const window of windows) { - const {tabs} = window; - for (let i = 0; i < tabs.length; ++i) { - // Replace the tab with the same tabId and trigger rerender. - if (tabs[i].tabId === updatedTabId) { - tabs[i] = updatedTab; - this.openTabs_ = windows.concat(); - return; - } - } + // Replace the tab with the same tabId and trigger rerender. + for (let i = 0; i < this.openTabs_.length; ++i) { + if (this.openTabs_[i].tab.tabId === updatedTab.tabId) { + this.openTabs_[i] = + this.tabData_(updatedTab, this.openTabs_[i].inActiveWindow); + this.updateFilteredTabs_(this.openTabs_); + return; } } } @@ -200,14 +193,21 @@ * @private */ onTabsRemoved_(tabIds) { - const windows = this.openTabs_; - if (windows) { - const ids = new Set(tabIds); - for (const window of windows) { - window.tabs = window.tabs.filter(tab => (!ids.has(tab.tabId))); - } - this.openTabs_ = windows.concat(); + if (!this.openTabs_) { + return; } + + const ids = new Set(tabIds); + // Splicing in descending index order to avoid affecting preceding indices + // that are to be removed. + for (let i = this.openTabs_.length - 1; i >= 0; i--) { + if (ids.has(this.openTabs_[i].tab.tabId)) { + this.openTabs_.splice(i, 1); + } + } + + this.filteredOpenTabs_ = + this.filteredOpenTabs_.filter(tabData => !ids.has(tabData.tab.tabId)); } /** @@ -304,11 +304,17 @@ } /** - * @param {!Array<!WindowTabs>} newOpenTabs + * @param {!Array<!WindowTabs>} newOpenWindowTabs * @private */ - openTabsChanged_(newOpenTabs) { - this.updateFilteredTabs_(newOpenTabs); + openTabsChanged_(newOpenWindowTabs) { + this.openTabs_ = []; + newOpenWindowTabs.forEach(({active, tabs}) => { + tabs.forEach(tab => { + this.openTabs_.push(this.tabData_(tab, active)); + }); + }); + this.updateFilteredTabs_(this.openTabs_); // If there was no previously selected index, set the first item as // selected; else retain the currently selected index. If the list @@ -415,19 +421,22 @@ } /** - * @param {!Array<!WindowTabs>} windowTabs + * @param {!Tab} tab + * @param {boolean} inActiveWindow + * @return {!TabData} * @private */ - updateFilteredTabs_(windowTabs) { - const result = []; - windowTabs.forEach(window => { - window.tabs.forEach(tab => { - const hostname = new URL(tab.url).hostname; - const inActiveWindow = window.active; - result.push({hostname, inActiveWindow, tab}); - }); - }); - result.sort((a, b) => { + tabData_(tab, inActiveWindow) { + const hostname = new URL(tab.url).hostname; + return /** @type {!TabData} */ ({hostname, inActiveWindow, tab}); + } + + /** + * @param {!Array<!TabData>} tabs + * @private + */ + updateFilteredTabs_(tabs) { + tabs.sort((a, b) => { // Move the active tab to the bottom of the list // because it's not likely users want to click on it. if (this.moveActiveTabToBottom_) { @@ -444,8 +453,9 @@ a.tab.lastActiveTimeTicks.internalValue) : 0; }); + this.filteredOpenTabs_ = - fuzzySearch(this.searchText_, result, this.fuzzySearchOptions_); + fuzzySearch(this.searchText_, tabs, this.fuzzySearchOptions_); this.searchResultText_ = this.getA11ySearchResultText_(); }
diff --git a/chrome/browser/resources/tab_search/fuzzy_search.js b/chrome/browser/resources/tab_search/fuzzy_search.js index 88f08205..b2a6950 100644 --- a/chrome/browser/resources/tab_search/fuzzy_search.js +++ b/chrome/browser/resources/tab_search/fuzzy_search.js
@@ -11,11 +11,12 @@ * @param {string} input * @param {!Array<!TabData>} records * @param {!Object} options - * @return {!Array<!TabData>} + * @return {!Array<!TabData>} A new array of entries satisfying the input. If no + * search input is present, returns a shallow copy of the records. */ export function fuzzySearch(input, records, options) { if (input.length === 0) { - return records; + return [...records]; } // Fuse does not handle exact match searches well. It indiscriminately // searches for direct matches that appear anywhere in the string. This
diff --git a/chrome/browser/resources/tab_search/infinite_list.html b/chrome/browser/resources/tab_search/infinite_list.html index 2778c25bc..55b5dfe2 100644 --- a/chrome/browser/resources/tab_search/infinite_list.html +++ b/chrome/browser/resources/tab_search/infinite_list.html
@@ -9,7 +9,6 @@ </style> <div id="items"> <iron-selector id="selector" on-keydown="onKeyDown_" - on-iron-items-changed="updateScrollerSize_" on-iron-select="onSelectedChanged_" role="listbox" selected-class="selected"> <slot></slot>
diff --git a/chrome/browser/resources/tab_search/infinite_list.js b/chrome/browser/resources/tab_search/infinite_list.js index 96e232d..38deb66 100644 --- a/chrome/browser/resources/tab_search/infinite_list.js +++ b/chrome/browser/resources/tab_search/infinite_list.js
@@ -20,6 +20,7 @@ import 'chrome://resources/polymer/v3_0/iron-selector/iron-selector.js'; import {assert, assertInstanceof} from 'chrome://resources/js/assert.m.js'; +import {updateListProperty} from 'chrome://resources/js/list_property_update_behavior.m.js'; import {listenOnce} from 'chrome://resources/js/util.m.js'; import {afterNextRender, DomRepeat, html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; @@ -92,9 +93,9 @@ /** @private */ getDomItems_() { - const selectorChildren = this.$.selector.children; + const selector = /** @type {!IronSelectorElement} */ (this.$.selector); return Array.prototype.slice.call( - selectorChildren, 0, selectorChildren.length - 1); + selector.children, 0, selector.children.length - 1); } /** @@ -155,6 +156,7 @@ if (aboveScrollTopItemCount + this.chunkItemThreshold > this.domRepeat_.items.length) { this.ensureDomItemsAvailableStartingAt_(aboveScrollTopItemCount); + this.updateScrollerSize_(); } } } @@ -189,12 +191,13 @@ * @private */ domItemAverageHeight_() { - if (!this.$.selector.items || this.$.selector.items.length === 0) { + const selector = /** @type {!IronSelectorElement} */ (this.$.selector); + if (!selector.items || selector.items.length === 0) { return 0; } - const domItemCount = this.$.selector.items.length; - const lastDomItem = this.$.selector.items[domItemCount - 1]; + const domItemCount = selector.items.length; + const lastDomItem = selector.items[domItemCount - 1]; return (lastDomItem.offsetTop + lastDomItem.offsetHeight) / domItemCount; } @@ -202,17 +205,32 @@ * Ensures that when the items property changes, only a chunk of the items * needed to fill the current scroll position view are added to the DOM, thus * improving rendering performance. + * + * @param {!Array} newItems + * @param {!Array} oldItems * @private */ - onItemsChanged_() { - if (this.domRepeat_ && this.items) { - const domItemAvgHeight = this.domItemAverageHeight_(); - const aboveScrollTopItemCount = domItemAvgHeight !== 0 ? - Math.round(this.scrollTop / domItemAvgHeight) : - 0; + onItemsChanged_(newItems, oldItems) { + if (!this.domRepeat_) { + return; + } + if (!oldItems || oldItems.length === 0) { this.domRepeat_.set('items', []); - this.ensureDomItemsAvailableStartingAt_(aboveScrollTopItemCount); + this.ensureDomItemsAvailableStartingAt_(0); + listenOnce(this.$.selector, 'iron-items-changed', () => { + this.updateScrollerSize_(); + }); + + return; + } + + updateListProperty( + this.domRepeat_, 'items', tabData => tabData, + newItems.slice(0, this.domRepeat_.items.length), + true /* identityBasedUpdate= */); + + if (newItems.length !== oldItems.length) { this.updateScrollerSize_(); } }
diff --git a/chrome/browser/resources/tools/optimize_webui.py b/chrome/browser/resources/tools/optimize_webui.py index 8d9c7da..ddada8e 100755 --- a/chrome/browser/resources/tools/optimize_webui.py +++ b/chrome/browser/resources/tools/optimize_webui.py
@@ -119,7 +119,8 @@ # TODO(dbeam): can we make this stricter? return url -def _request_list_path(out_path, host): +def _request_list_path(out_path, host_url): + host = host_url[host_url.find('://') + 3:-1] return os.path.join(out_path, host + '_requestlist.txt') # Get a list of all files that were bundled with polymer-bundler and update the @@ -142,7 +143,7 @@ # current working directory. url_mappings = _URL_MAPPINGS + [ ('/', os.path.relpath(in_path, _CWD)), - ('chrome://%s/' % args.host, os.path.relpath(in_path, _CWD)), + (args.host_url, os.path.relpath(in_path, _CWD)), ] deps = [_undo_mapping(url_mappings, u) for u in request_list] @@ -158,10 +159,8 @@ # Autogenerate a rollup config file so that we can import the plugin and # pass it information about the location of the directories and files to exclude # from the bundle. -def _generate_rollup_config(tmp_out_dir, path_to_plugin, in_path, host, +def _generate_rollup_config(tmp_out_dir, path_to_plugin, in_path, host_url, excludes, external_paths): - scheme_end_index = host.find('://') - host_url = 'chrome://%s/' % host if scheme_end_index == -1 else host rollup_config_file = os.path.join(tmp_out_dir, 'rollup.config.js') config_content = r''' import plugin from '{plugin_path}'; @@ -211,7 +210,7 @@ path_to_plugin = os.path.join( os.path.abspath(_HERE_PATH), 'rollup_plugin.js') rollup_config_file = _generate_rollup_config(tmp_out_dir, path_to_plugin, - in_path, args.host, excludes, + in_path, args.host_url, excludes, external_paths) rollup_args = [os.path.join(in_path, f) for f in args.js_module_in_files] @@ -282,7 +281,7 @@ [ '--manifest-out', manifest_out_path, '--root', in_path, - '--redirect', 'chrome://%s/|%s' % (args.host, in_path + '/'), + '--redirect', '%s|%s' % (args.host_url, in_path + '/'), '--out-dir', os.path.relpath(tmp_out_dir, _CWD).replace('\\', '/'), '--shell', args.html_in_files[0], ] + in_html_args) @@ -325,7 +324,7 @@ def _optimize(in_folder, args): in_path = os.path.normpath(os.path.join(_CWD, in_folder)).replace('\\', '/') out_path = os.path.join(_CWD, args.out_folder).replace('\\', '/') - manifest_out_path = _request_list_path(out_path, args.host) + manifest_out_path = _request_list_path(out_path, args.host_url) tmp_out_dir = tempfile.mkdtemp(dir=out_path).replace('\\', '/') excludes = _BASE_EXCLUDES + [ @@ -333,8 +332,8 @@ # URL for both the relative URL and chrome:// URL syntax. 'strings.js', 'strings.m.js', - 'chrome://%s/strings.js' % args.host, - 'chrome://%s/strings.m.js' % args.host, + '%s/strings.js' % args.host_url, + '%s/strings.m.js' % args.host_url, ] excludes.extend(args.exclude or []) external_paths = args.external_paths or [] @@ -347,7 +346,8 @@ external_paths) else: # Ensure Polymer 2 and Polymer 3 request lists don't collide. - manifest_out_path = _request_list_path(out_path, args.host + '-v2') + manifest_out_path = _request_list_path(out_path, + args.host_url[:-1] + '-v2/') pcb_out_paths = [os.path.join(out_path, f) for f in args.html_out_files] bundled_paths = _bundle_v2(tmp_out_dir, in_path, out_path, manifest_out_path, args, excludes) @@ -397,6 +397,11 @@ args.depfile = os.path.normpath(args.depfile) args.input = os.path.normpath(args.input) args.out_folder = os.path.normpath(args.out_folder) + scheme_end_index = args.host.find('://') + if (scheme_end_index == -1): + args.host_url = 'chrome://%s/' % args.host + else: + args.host_url = args.host manifest_out_path = _optimize(args.input, args)
diff --git a/chrome/browser/resources/tools/optimize_webui_test.py b/chrome/browser/resources/tools/optimize_webui_test.py index 1015fe6..0ec62373e 100755 --- a/chrome/browser/resources/tools/optimize_webui_test.py +++ b/chrome/browser/resources/tools/optimize_webui_test.py
@@ -53,7 +53,6 @@ # TODO(dbeam): make it possible to _run_optimize twice? Is that useful? args = input_args + [ '--depfile', os.path.join(self._out_folder, 'depfile.d'), - '--host', 'fake-host', '--input', self._tmp_src_dir, '--out_folder', self._out_folder, ] @@ -157,6 +156,7 @@ def testSimpleOptimize(self): self._write_files_to_src_dir() args = [ + '--host', 'fake-host', '--html_in_files', 'ui.html', '--html_out_files', 'fast.html', '--js_out_files', 'fast.js', @@ -172,6 +172,7 @@ def testV3SimpleOptimize(self): self._write_v3_files_to_src_dir() args = [ + '--host', 'fake-host', '--js_module_in_files', 'ui.js', '--js_out_files', 'ui.rollup.js', ] @@ -185,6 +186,7 @@ resources_path = os.path.join( 'gen', 'ui', 'webui', 'resources', 'preprocessed') args = [ + '--host', 'fake-host', '--js_module_in_files', 'ui.js', '--js_out_files', 'ui.rollup.js', '--external_paths', 'chrome://resources|%s' % resources_path, @@ -215,6 +217,7 @@ ''') args = [ + '--host', 'fake-host', '--js_module_in_files', 'ui.js', 'lazy.js', '--js_out_files', 'ui.rollup.js', 'lazy.rollup.js', 'shared.rollup.js', '--out-manifest', os.path.join(self._out_folder, 'out_manifest.json'), @@ -259,6 +262,7 @@ resources_path = os.path.join( 'gen', 'ui', 'webui', 'resources', 'preprocessed') args = [ + '--host', 'fake-host', '--js_module_in_files', 'ui.js', '--js_out_files', 'ui.rollup.js', '--external_paths', @@ -284,5 +288,23 @@ 'external_element_dep.js')), depfile_d) + def testV3SimpleOptimizeExcludes(self): + self._write_v3_files_to_src_dir() + args = [ + '--host', 'chrome-extension://myextensionid/', + '--js_module_in_files', 'ui.js', + '--js_out_files', 'ui.rollup.js', + '--exclude', 'element_in_dir/element_in_dir.js', + ] + self._run_optimize(args) + + output_js = self._read_out_file('ui.rollup.js') + self.assertIn('yay', output_js) + self.assertNotIn('hello from element_in_dir', output_js) + depfile_d = self._read_out_file('depfile.d') + self.assertIn('element.js', depfile_d) + self.assertNotIn('element_in_dir', depfile_d) + + if __name__ == '__main__': unittest.main()
diff --git a/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_test_utils.cc b/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_test_utils.cc index e85bf92..cf93e40 100644 --- a/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_test_utils.cc +++ b/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_test_utils.cc
@@ -53,8 +53,9 @@ content_size_ = expected_content_size; result_ = expected_result; username_ = expected_username; - EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _)) - .WillOnce([this](content::BrowserContext* context, base::Value& report, + EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _, _)) + .WillOnce([this](content::BrowserContext* context, + bool include_device_info, base::Value& report, base::OnceCallback<void(bool)>& callback) { ValidateReport(&report); if (!done_closure_.is_null()) @@ -82,8 +83,9 @@ content_size_ = expected_content_size; result_ = expected_result; username_ = expected_username; - EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _)) - .WillOnce([this](content::BrowserContext* context, base::Value& report, + EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _, _)) + .WillOnce([this](content::BrowserContext* context, + bool include_device_info, base::Value& report, base::OnceCallback<void(bool)>& callback) { ValidateReport(&report); if (!done_closure_.is_null()) @@ -112,8 +114,9 @@ content_size_ = expected_content_size; result_ = expected_result; username_ = expected_username; - EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _)) - .WillOnce([this](content::BrowserContext* context, base::Value& report, + EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _, _)) + .WillOnce([this](content::BrowserContext* context, + bool include_device_info, base::Value& report, base::OnceCallback<void(bool)>& callback) { ValidateReport(&report); if (!done_closure_.is_null()) @@ -144,13 +147,15 @@ content_size_ = expected_content_size; result_ = expected_result; username_ = expected_username; - EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _)) - .WillOnce([this](content::BrowserContext* context, base::Value& report, + EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _, _)) + .WillOnce([this](content::BrowserContext* context, + bool include_device_info, base::Value& report, base::OnceCallback<void(bool)>& callback) { ValidateReport(&report); }) .WillOnce([this, expected_dlp_verdict]( - content::BrowserContext* context, base::Value& report, + content::BrowserContext* context, bool include_device_info, + base::Value& report, base::OnceCallback<void(bool)>& callback) { event_key_ = SafeBrowsingPrivateEventRouter::kKeySensitiveDataEvent; threat_type_ = base::nullopt; @@ -184,13 +189,15 @@ result_ = expected_result; dlp_verdict_ = expected_dlp_verdict; username_ = expected_username; - EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _)) - .WillOnce([this](content::BrowserContext* context, base::Value& report, + EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _, _)) + .WillOnce([this](content::BrowserContext* context, + bool include_device_info, base::Value& report, base::OnceCallback<void(bool)>& callback) { ValidateReport(&report); }) .WillOnce([this, expected_threat_type]( - content::BrowserContext* context, base::Value& report, + content::BrowserContext* context, bool include_device_info, + base::Value& report, base::OnceCallback<void(bool)>& callback) { event_key_ = SafeBrowsingPrivateEventRouter::kKeyDangerousDownloadEvent; threat_type_ = expected_threat_type; @@ -221,8 +228,9 @@ content_size_ = expected_content_size; result_ = expected_result; username_ = expected_username; - EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _)) - .WillOnce([this](content::BrowserContext* context, base::Value& report, + EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _, _)) + .WillOnce([this](content::BrowserContext* context, + bool include_device_info, base::Value& report, base::OnceCallback<void(bool)>& callback) { ValidateReport(&report); if (!done_closure_.is_null()) @@ -335,7 +343,7 @@ } void EventReportValidator::ExpectNoReport() { - EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _)).Times(0); + EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _, _)).Times(0); } void EventReportValidator::SetDoneClosure(base::RepeatingClosure closure) {
diff --git a/chrome/browser/search_engines/template_url_service_unittest.cc b/chrome/browser/search_engines/template_url_service_unittest.cc index fd2058df..0a169bf 100644 --- a/chrome/browser/search_engines/template_url_service_unittest.cc +++ b/chrome/browser/search_engines/template_url_service_unittest.cc
@@ -1732,7 +1732,7 @@ // Checks that correct priority is applied when resolving conflicts between the // omnibox extension, search engine extension and user search engines with same // keyword. -TEST_F(TemplateURLServiceTest, CheckEnginesWithSameKeywords) { +TEST_F(TemplateURLServiceTest, KeywordConflictNonReplaceableEngines) { test_util()->VerifyLoad(); // TemplateURLData used for user engines. std::unique_ptr<TemplateURLData> turl_data = @@ -1845,7 +1845,7 @@ "behavior on ApplyDefaultSearchChangeNoMetrics."; } -TEST_F(TemplateURLServiceTest, ConflictingReplaceableEnginesShouldOverwrite) { +TEST_F(TemplateURLServiceTest, ReplaceableEngineUpdateHandlesKeywordConflicts) { test_util()->VerifyLoad(); // Add 2 replaceable user engine with different keywords. TemplateURL* user1 = @@ -1869,6 +1869,33 @@ EXPECT_EQ(user2, model()->GetTemplateURLForKeyword(ASCIIToUTF16("user2"))); } +// Verifies that we favor prepopulated engines over other safe_for_autoreplace() +// engines, even if they are newer. https://crbug.com/1164024 +TEST_F(TemplateURLServiceTest, KeywordConflictFavorsPrepopulatedEngines) { + test_util()->VerifyLoad(); + + // Add prepopulated engine with prepopulate_id == 42. + TemplateURL* prepopulated = model()->Add(CreateKeywordWithDate( + model(), "prepopulated", "common_keyword", "http://test1", std::string(), + std::string(), std::string(), true, 42, "UTF-8", + base::Time::FromTimeT(0))); + ASSERT_TRUE(prepopulated); + TemplateURLData prepopulated_data = prepopulated->data(); + + // Add a newer autogenerated engine with the same keyword. + TemplateURL* newer_autogenerated_engine = AddKeywordWithDate( + "autogenerated", "common_keyword", "http://test2", std::string(), + std::string(), std::string(), true, "UTF-8", base::Time::FromTimeT(20)); + + // Verify that the prepopulated engine was added, and the newer autogenerated + // engine was discarded. Also check that data has not changed. + EXPECT_EQ(nullptr, newer_autogenerated_engine); + EXPECT_EQ(prepopulated, + model()->GetTemplateURLForKeyword(ASCIIToUTF16("common_keyword"))); + EXPECT_TRUE(TemplateURL::MatchesData(prepopulated, &prepopulated_data, + model()->search_terms_data())); +} + TEST_F(TemplateURLServiceTest, CheckNonreplaceableEnginesKeywordsConflicts) { test_util()->VerifyLoad();
diff --git a/chrome/browser/spellchecker/spellcheck_service.cc b/chrome/browser/spellchecker/spellcheck_service.cc index 1a5d8bf3..d56c8c8 100644 --- a/chrome/browser/spellchecker/spellcheck_service.cc +++ b/chrome/browser/spellchecker/spellcheck_service.cc
@@ -527,18 +527,6 @@ (!hunspell_dictionaries_.empty() || enable_if_uninitialized); } -bool SpellcheckService::LoadExternalDictionary(std::string language, - std::string locale, - std::string path, - DictionaryFormat format) { - return false; -} - -bool SpellcheckService::UnloadExternalDictionary( - const std::string& /* path */) { - return false; -} - void SpellcheckService::Observe(int type, const content::NotificationSource& source, const content::NotificationDetails& details) {
diff --git a/chrome/browser/spellchecker/spellcheck_service.h b/chrome/browser/spellchecker/spellcheck_service.h index 29ea018..a810ed51 100644 --- a/chrome/browser/spellchecker/spellcheck_service.h +++ b/chrome/browser/spellchecker/spellcheck_service.h
@@ -62,13 +62,6 @@ BDICT_CORRUPTED, }; - // Dictionary format used for loading an external dictionary. - enum DictionaryFormat { - DICT_HUNSPELL, - DICT_TEXT, - DICT_UNKNOWN, - }; - // A dictionary that can be used for spellcheck. struct Dictionary { // The shortest unambiguous identifier for a language from @@ -141,17 +134,6 @@ // dictionaries available. bool IsSpellcheckEnabled() const; - // Load a dictionary from a given path. Format specifies how the dictionary - // is stored. Return value is true if successful. - bool LoadExternalDictionary(std::string language, - std::string locale, - std::string path, - DictionaryFormat format); - - // Unload a dictionary. The path is given to identify the dictionary. - // Return value is true if successful. - bool UnloadExternalDictionary(const std::string& /* path */); - // NotificationProfile implementation. void Observe(int type, const content::NotificationSource& source,
diff --git a/chrome/browser/ssl/typed_navigation_upgrade_throttle_browsertest.cc b/chrome/browser/ssl/typed_navigation_upgrade_throttle_browsertest.cc index a145ef2b..025696b 100644 --- a/chrome/browser/ssl/typed_navigation_upgrade_throttle_browsertest.cc +++ b/chrome/browser/ssl/typed_navigation_upgrade_throttle_browsertest.cc
@@ -48,13 +48,22 @@ const char* const kSiteWithNetError = "https://site-with-net-error.com"; const char* const kSiteWithNetErrorOverHttp = "http://site-with-net-error.com"; +// Site (likely on an intranet) that contains a non-registerable or +// non-assignable domain name (eg: a gTLD that has not been assigned by IANA) +// that therefore is unlikely to support HTTPS. +const char* const kNonUniqueHostname1 = "http://testpage"; +const char* const kNonUniqueHostname2 = "http://site.test"; + const char kNetErrorHistogram[] = "Net.ErrorPageCounts"; enum class NavigationExpectation { // Test should expect a successful navigation to HTTPS. kExpectHttps, // Test should expect a fallback navigation to HTTP. - kExpectHttp + kExpectHttp, + // Test should expect a search query navigation. This happens when the user + // enters a non-URL query such as "testpage". + kExpectSearch }; std::string GetURLWithoutScheme(const GURL& url) { @@ -142,7 +151,10 @@ params->url_request.url == GURL(kSiteWithGoodHttps) || params->url_request.url == GURL(kSiteWithBadHttpsOverHttp) || params->url_request.url == GURL(kSiteWithSlowHttpsOverHttp) || - params->url_request.url == GURL(kSiteWithNetErrorOverHttp)) { + params->url_request.url == GURL(kSiteWithNetErrorOverHttp) || + params->url_request.url == GURL(kNonUniqueHostname1) || + params->url_request.url == GURL(kNonUniqueHostname2) || + params->url_request.url == GURL("http://127.0.0.1")) { std::string headers = "HTTP/1.1 200 OK\nContent-Type: text/html; charset=utf-8\n"; std::string body = "<html><title>Success</title>Hello world</html>"; @@ -182,43 +194,78 @@ omnibox()->OnAfterPossibleChange(true); } + // Type |hostname| in the URL bar and hit enter. The navigation shouldn't be + // upgraded to HTTPS. Expect a search query to be issued if + // |expect_search_query| is true. Otherwise, the final URL will be an HTTP + // URL. + void TypeUrlAndExceptNoUpgrade(const std::string& hostname, + bool expect_search_query) { + base::HistogramTester histograms; + TypeUrlAndCheckNavigation(hostname, histograms, + expect_search_query + ? NavigationExpectation::kExpectSearch + : NavigationExpectation::kExpectHttp, + 1); + histograms.ExpectTotalCount(TypedNavigationUpgradeThrottle::kHistogramName, + 0); + } + + // Type |hostname| in the URL bar and hit enter. The navigation should + // initially be upgraded to HTTPS but then fall back to HTTP because the HTTPS + // URL wasn't available (e.g. had an SSL or net error). + void TypeUrlAndExpectHttpFallback(const std::string& hostname, + const base::HistogramTester& histograms) { + // There should be two navigations: One for the initial HTTPS + // navigation (which will be cancelled because of the timeout, or SSL or net + // errors) and one for the fallback HTTP navigation (which will succeed). + TypeUrlAndCheckNavigation(hostname, histograms, + NavigationExpectation::kExpectHttp, 2); + } + + // Type |hostname| in the URL bar and hit enter. The navigation should + // be upgraded to HTTPS and the HTTPS URL should successfully load. + void TypeUrlAndExpectHttps(const std::string& hostname, + const base::HistogramTester& histograms) { + TypeUrlAndCheckNavigation(hostname, histograms, + NavigationExpectation::kExpectHttps, 1); + } + void TypeUrlAndCheckNavigation(const std::string& hostname, const base::HistogramTester& histograms, - NavigationExpectation expectation) { + NavigationExpectation expectation, + size_t num_expected_navigations) { const GURL http_url(std::string("http://") + hostname); const GURL https_url(std::string("https://") + hostname); SetOmniboxText(hostname); + PressEnterAndWaitForNavigations(num_expected_navigations); - // Wait for navigations. - // - If the expectation is to successfully load the HTTPS URL, there should - // be a single navigation. - // - Otherwise, there should be two navigations: One for the initial HTTPS - // navigation (which will be cancelled because of the timeout, or SSL or net - // errors) and one for the fallback HTTP navigation (which will succeed). - PressEnterAndWaitForNavigations( - expectation == NavigationExpectation::kExpectHttps ? 1 : 2); - + ui_test_utils::HistoryEnumerator enumerator(browser()->profile()); content::WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents(); - const GURL expected_url = expectation == NavigationExpectation::kExpectHttps - ? https_url - : http_url; - EXPECT_EQ(expected_url, contents->GetLastCommittedURL()); + if (expectation != NavigationExpectation::kExpectSearch) { + const GURL expected_url = + expectation == NavigationExpectation::kExpectHttps ? https_url + : http_url; + EXPECT_EQ(expected_url, contents->GetLastCommittedURL()); + + // Should have either the HTTP or the HTTPS URL in history, but not both. + if (expectation == NavigationExpectation::kExpectHttp) { + EXPECT_TRUE(base::Contains(enumerator.urls(), http_url)); + EXPECT_FALSE(base::Contains(enumerator.urls(), https_url)); + } else { + EXPECT_TRUE(base::Contains(enumerator.urls(), https_url)); + EXPECT_FALSE(base::Contains(enumerator.urls(), http_url)); + } + } else { + // The user entered a search query. + EXPECT_EQ("www.google.com", contents->GetLastCommittedURL().host()); + EXPECT_FALSE(base::Contains(enumerator.urls(), https_url)); + } // Should never hit an error page. histograms.ExpectTotalCount(SSLErrorHandler::GetHistogramNameForTesting(), 0); histograms.ExpectTotalCount(kNetErrorHistogram, 0); - - // Should have either the HTTP or the HTTPS URL in history, but not both. - ui_test_utils::HistoryEnumerator enumerator(browser()->profile()); - if (expectation == NavigationExpectation::kExpectHttp) { - EXPECT_TRUE(base::Contains(enumerator.urls(), http_url)); - EXPECT_FALSE(base::Contains(enumerator.urls(), https_url)); - } else { - EXPECT_TRUE(base::Contains(enumerator.urls(), https_url)); - EXPECT_FALSE(base::Contains(enumerator.urls(), http_url)); - } } void PressEnterAndWaitForNavigations(size_t num_navigations) { @@ -328,21 +375,50 @@ return; } base::HistogramTester histograms; - const GURL url(kSiteWithHttp); + const GURL http_url(kSiteWithHttp); // Type "test-site.com". - SetOmniboxText(GetURLWithoutScheme(url)); + SetOmniboxText(GetURLWithoutScheme(http_url)); PressEnterAndWaitForNavigations(1); content::WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents(); - EXPECT_EQ(url, contents->GetLastCommittedURL()); + EXPECT_EQ(http_url, contents->GetLastCommittedURL()); EXPECT_FALSE(chrome_browser_interstitials::IsShowingInterstitial(contents)); histograms.ExpectTotalCount(TypedNavigationUpgradeThrottle::kHistogramName, 0); } +// Test the case when the user types a search keyword. The keyword may or may +// not be a non-unique hostname. The navigation should always result in a +// search and we should never upgrade it to https. +IN_PROC_BROWSER_TEST_P(TypedNavigationUpgradeThrottleBrowserTest, + SearchQuery_ShouldNotUpgrade) { + TypeUrlAndExceptNoUpgrade("testpage", /*expect_search_query=*/true); +} + +// Same as SearchQuery_ShouldNotUpgrade but with two words. This is a definite +// search query, and can never be a hostname. +IN_PROC_BROWSER_TEST_P(TypedNavigationUpgradeThrottleBrowserTest, + SearchQuery_TwoWords_ShouldNotUpgrade) { + TypeUrlAndExceptNoUpgrade("test page", /*expect_search_query=*/true); +} + +// Test the case when the user types a non-unique hostname. We shouldn't upgrade +// it to https. +IN_PROC_BROWSER_TEST_P(TypedNavigationUpgradeThrottleBrowserTest, + NonUniqueHostnameTypedWithoutScheme_ShouldNotUpgrade) { + TypeUrlAndExceptNoUpgrade("site.test", /*expect_search_query=*/false); +} + +// Test the case when the user types an IP address. We shouldn't upgrade it to +// https. +IN_PROC_BROWSER_TEST_P(TypedNavigationUpgradeThrottleBrowserTest, + IPAddressTypedWithoutScheme_ShouldNotUpgrade) { + TypeUrlAndExceptNoUpgrade("127.0.0.1", /*expect_search_query=*/false); +} + // If the feature is enabled, typing a URL in the omnibox without a scheme // should load the HTTPS version. IN_PROC_BROWSER_TEST_P(TypedNavigationUpgradeThrottleBrowserTest, @@ -356,8 +432,7 @@ // Type "site-with-good-https.com". const GURL url(kSiteWithGoodHttps); - TypeUrlAndCheckNavigation(url.host(), histograms, - NavigationExpectation::kExpectHttps); + TypeUrlAndExpectHttps(url.host(), histograms); histograms.ExpectTotalCount(TypedNavigationUpgradeThrottle::kHistogramName, 2); @@ -375,8 +450,7 @@ // without going through the upgrade. // Type "site-with-good-https.com". SetOmniboxText(url.host()); - TypeUrlAndCheckNavigation(url.host(), histograms, - NavigationExpectation::kExpectHttps); + TypeUrlAndExpectHttps(url.host(), histograms); // Since the throttle wasn't involved in the second navigation, histogram // values shouldn't change. @@ -407,8 +481,7 @@ // Type "site-with-bad-https.com". const GURL url(kSiteWithBadHttps); - TypeUrlAndCheckNavigation(url.host(), histograms, - NavigationExpectation::kExpectHttp); + TypeUrlAndExpectHttpFallback(url.host(), histograms); histograms.ExpectTotalCount(TypedNavigationUpgradeThrottle::kHistogramName, 2); @@ -436,10 +509,8 @@ } base::HistogramTester histograms; // Type "site-with-net-error.com". - const GURL https_url(kSiteWithNetError); const GURL http_url(kSiteWithNetErrorOverHttp); - TypeUrlAndCheckNavigation(http_url.host(), histograms, - NavigationExpectation::kExpectHttp); + TypeUrlAndExpectHttpFallback(http_url.host(), histograms); histograms.ExpectTotalCount(TypedNavigationUpgradeThrottle::kHistogramName, 2); @@ -453,10 +524,6 @@ TypedNavigationUpgradeThrottle::kHistogramName, TypedNavigationUpgradeThrottle::Event::kHttpsLoadTimedOut, 0); - ui_test_utils::HistoryEnumerator enumerator(browser()->profile()); - EXPECT_TRUE(base::Contains(enumerator.urls(), http_url)); - EXPECT_FALSE(base::Contains(enumerator.urls(), https_url)); - // TODO(meacer): Try again and check that the histogram counts doubled. Doing // that currently fails on lacros because this time the navigation never gets // upgraded (probably because of an issue in the autocomplete logic). @@ -488,8 +555,7 @@ // Type "site-with-slow-https.com". const GURL url(kSiteWithSlowHttps); - TypeUrlAndCheckNavigation(url.host(), histograms, - NavigationExpectation::kExpectHttp); + TypeUrlAndExpectHttpFallback(url.host(), histograms); histograms.ExpectTotalCount(TypedNavigationUpgradeThrottle::kHistogramName, 2);
diff --git a/chrome/browser/supervised_user/child_accounts/child_account_service.cc b/chrome/browser/supervised_user/child_accounts/child_account_service.cc index 38d4f1c9..09fdbdd 100644 --- a/chrome/browser/supervised_user/child_accounts/child_account_service.cc +++ b/chrome/browser/supervised_user/child_accounts/child_account_service.cc
@@ -161,7 +161,7 @@ SupervisedUserSettingsServiceFactory::GetForKey( profile_->GetProfileKey()); - // In contrast to legacy SUs, child account SUs must sign in. + // In contrast to deprecated legacy SUs, child account SUs must sign in. settings_service->SetLocalSetting(supervised_users::kSigninAllowed, std::make_unique<base::Value>(true)); @@ -341,9 +341,9 @@ user_manager::User* user = chromeos::ProfileHelper::Get()->GetUserByProfile(profile_); if (user) { - // Note that supervised user is allowed to change type due to legacy - // initialization. - if (user->GetType() != user_manager::USER_TYPE_SUPERVISED) { + // Note that deprecated legacy supervised users are allowed to change type + // due to legacy initialization. + if (user->GetType() != user_manager::USER_TYPE_SUPERVISED_DEPRECATED) { if (is_child != (user->GetType() == user_manager::USER_TYPE_CHILD)) LOG(FATAL) << "User child flag has changed: " << is_child; }
diff --git a/chrome/browser/tab_contents/navigation_metrics_recorder.cc b/chrome/browser/tab_contents/navigation_metrics_recorder.cc index 6817aa91..a7c4b05 100644 --- a/chrome/browser/tab_contents/navigation_metrics_recorder.cc +++ b/chrome/browser/tab_contents/navigation_metrics_recorder.cc
@@ -6,11 +6,11 @@ #include "base/metrics/histogram_macros.h" #include "build/build_config.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/metrics/chrome_metrics_service_accessor.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_metrics.h" #include "components/navigation_metrics/navigation_metrics.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/navigation_entry.h"
diff --git a/chrome/browser/tab_contents/navigation_metrics_recorder_browsertest.cc b/chrome/browser/tab_contents/navigation_metrics_recorder_browsertest.cc index 637561f..5f1e747 100644 --- a/chrome/browser/tab_contents/navigation_metrics_recorder_browsertest.cc +++ b/chrome/browser/tab_contents/navigation_metrics_recorder_browsertest.cc
@@ -3,7 +3,6 @@ // found in the LICENSE file. #include "base/test/metrics/histogram_tester.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/tab_contents/navigation_metrics_recorder.h" #include "chrome/browser/ui/browser.h" @@ -13,6 +12,7 @@ #include "chrome/test/base/ui_test_utils.h" #include "components/navigation_metrics/navigation_metrics.h" #include "components/site_engagement/content/site_engagement_score.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/render_widget_host.h" #include "content/public/browser/web_contents.h"
diff --git a/chrome/browser/tflite_experiment/tflite_experiment_keyed_service_browsertest.cc b/chrome/browser/tflite_experiment/tflite_experiment_keyed_service_browsertest.cc index 3e8461ba..d06f7d0 100644 --- a/chrome/browser/tflite_experiment/tflite_experiment_keyed_service_browsertest.cc +++ b/chrome/browser/tflite_experiment/tflite_experiment_keyed_service_browsertest.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/tflite_experiment/tflite_experiment_keyed_service.h" #include "base/command_line.h" +#include "base/files/file_util.h" #include "base/json/json_reader.h" #include "base/path_service.h" #include "base/task/thread_pool/thread_pool_instance.h" @@ -110,7 +111,8 @@ // Set TFLite model path. base::PathService::Get(chrome::DIR_TEST_DATA, &g_test_data_directory); - g_test_data_directory = g_test_data_directory.Append(kTFLiteModelName); + g_test_data_directory = + g_test_data_directory.Append(FILE_PATH_LITERAL(kTFLiteModelName)); cmd->AppendSwitchASCII(tflite_experiment::switches::kTFLiteModelPath, g_test_data_directory.value());
diff --git a/chrome/browser/tflite_experiment/tflite_experiment_observer.cc b/chrome/browser/tflite_experiment/tflite_experiment_observer.cc index 8aa7aef9..c556759 100644 --- a/chrome/browser/tflite_experiment/tflite_experiment_observer.cc +++ b/chrome/browser/tflite_experiment/tflite_experiment_observer.cc
@@ -4,12 +4,15 @@ #include "chrome/browser/tflite_experiment/tflite_experiment_observer.h" +#include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/json/json_writer.h" #include "base/metrics/histogram_macros_local.h" +#include "base/strings/utf_string_conversions.h" #include "base/task/task_traits.h" #include "base/time/time.h" #include "base/values.h" +#include "build/build_config.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/tflite_experiment/tflite_experiment_keyed_service.h" #include "chrome/browser/tflite_experiment/tflite_experiment_keyed_service_factory.h" @@ -124,7 +127,11 @@ const std::string& data) { if (!log_path) return; +#if defined(OS_WIN) + base::FilePath log_file = base::FilePath(base::UTF8ToWide(log_path.value())); +#else base::FilePath log_file = base::FilePath(log_path.value()); +#endif base::AppendToFile(log_file, data.c_str(), data.size()); } @@ -133,7 +140,11 @@ base::Optional<std::string> log_path) { if (!log_path) return; +#if defined(OS_WIN) + base::FilePath log_file = base::FilePath(base::UTF8ToWide(log_path.value())); +#else base::FilePath log_file = base::FilePath(log_path.value()); +#endif base::WriteFile(log_file, "", 0); }
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index b9be6cf..3607a31 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -2719,6 +2719,7 @@ "//components/services/app_service/public/cpp:instance_update", "//components/session_manager/core", "//components/user_manager", + "//extensions/browser/api/vpn_provider", "//google_apis/drive", "//media/capture:capture_lib", "//mojo/public/js:resources_grit",
diff --git a/chrome/browser/ui/ash/capture_mode_browsertest.cc b/chrome/browser/ui/ash/capture_mode_browsertest.cc new file mode 100644 index 0000000..78fcb9d --- /dev/null +++ b/chrome/browser/ui/ash/capture_mode_browsertest.cc
@@ -0,0 +1,36 @@ +// 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 "ash/public/cpp/ash_features.h" +#include "ash/public/cpp/capture_mode_test_api.h" +#include "ash/public/cpp/test/shell_test_api.h" +#include "base/test/scoped_feature_list.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "content/public/test/browser_test.h" + +class CaptureModeBrowserTest : public InProcessBrowserTest { + public: + CaptureModeBrowserTest() = default; + CaptureModeBrowserTest(const CaptureModeBrowserTest&) = delete; + CaptureModeBrowserTest& operator=(const CaptureModeBrowserTest&) = delete; + ~CaptureModeBrowserTest() override = default; + + // InProcessBrowserTest: + void SetUp() override { + scoped_feature_list_.InitAndEnableFeature(ash::features::kCaptureMode); + InProcessBrowserTest::SetUp(); + } + + private: + base::test::ScopedFeatureList scoped_feature_list_; +}; + +IN_PROC_BROWSER_TEST_F(CaptureModeBrowserTest, ContextMenuStaysOpen) { + ash::ShellTestApi shell_test_api; + shell_test_api.ShowContextMenu(); + ASSERT_TRUE(shell_test_api.IsContextMenuShown()); + + ash::CaptureModeTestApi().StartForWindow(/*for_video=*/false); + EXPECT_TRUE(shell_test_api.IsContextMenuShown()); +}
diff --git a/chrome/browser/ui/ash/chrome_capture_mode_delegate.cc b/chrome/browser/ui/ash/chrome_capture_mode_delegate.cc index 73d8d6a..1794734 100644 --- a/chrome/browser/ui/ash/chrome_capture_mode_delegate.cc +++ b/chrome/browser/ui/ash/chrome_capture_mode_delegate.cc
@@ -173,3 +173,7 @@ mojo::PendingReceiver<audio::mojom::StreamFactory> receiver) { content::GetAudioService().BindStreamFactory(std::move(receiver)); } + +void ChromeCaptureModeDelegate::OnSessionStateChanged(bool started) { + is_session_active_ = started; +}
diff --git a/chrome/browser/ui/ash/chrome_capture_mode_delegate.h b/chrome/browser/ui/ash/chrome_capture_mode_delegate.h index c550d6d..1be6af9 100644 --- a/chrome/browser/ui/ash/chrome_capture_mode_delegate.h +++ b/chrome/browser/ui/ash/chrome_capture_mode_delegate.h
@@ -20,6 +20,8 @@ static ChromeCaptureModeDelegate* Get(); + bool is_session_active() const { return is_session_active_; } + // Sets |is_screen_capture_locked_| to the given |locked|, and interrupts any // on going video capture. void SetIsScreenCaptureLocked(bool locked); @@ -47,6 +49,7 @@ override; void BindAudioStreamFactory( mojo::PendingReceiver<audio::mojom::StreamFactory> receiver) override; + void OnSessionStateChanged(bool started) override; private: // Used to temporarily disable capture mode in certain cases for which neither @@ -60,6 +63,9 @@ // locked. // This is only non-null during recording. base::OnceClosure interrupt_video_recording_callback_; + + // True when a capture mode session is currently active. + bool is_session_active_ = false; }; #endif // CHROME_BROWSER_UI_ASH_CHROME_CAPTURE_MODE_DELEGATE_H_
diff --git a/chrome/browser/ui/ash/chrome_launcher_prefs.cc b/chrome/browser/ui/ash/chrome_launcher_prefs.cc index b0848b3f..9eb27d15 100644 --- a/chrome/browser/ui/ash/chrome_launcher_prefs.cc +++ b/chrome/browser/ui/ash/chrome_launcher_prefs.cc
@@ -26,6 +26,7 @@ #include "chrome/browser/ui/ash/launcher/launcher_controller_helper.h" #include "chrome/browser/web_applications/components/app_registrar.h" #include "chrome/browser/web_applications/components/web_app_id.h" +#include "chrome/browser/web_applications/components/web_app_id_constants.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/common/extensions/extension_constants.h" #include "chrome/common/pref_names.h" @@ -49,24 +50,62 @@ // Chrome is pinned explicitly. const char* kDefaultPinnedApps[] = { - extension_misc::kFilesManagerAppId, extension_misc::kGmailAppId, - extension_misc::kGoogleDocAppId, extension_misc::kYoutubeAppId, - arc::kPlayStoreAppId}; + extension_misc::kFilesManagerAppId, + + extension_misc::kGmailAppId, + web_app::kGmailAppId, + + extension_misc::kGoogleDocAppId, + web_app::kGoogleDocsAppId, + + extension_misc::kYoutubeAppId, + web_app::kYoutubeAppId, + + arc::kPlayStoreAppId, +}; const char* kDefaultPinnedApps7Apps[] = { - extension_misc::kFilesManagerAppId, extension_misc::kGmailAppId, - extension_misc::kGoogleDocAppId, extension_misc::kGooglePhotosAppId, - extension_misc::kYoutubeAppId, arc::kPlayStoreAppId}; + extension_misc::kFilesManagerAppId, -const char* kDefaultPinnedApps10Apps[] = {extension_misc::kFilesManagerAppId, - extension_misc::kGmailAppId, - extension_misc::kCalendarAppId, - extension_misc::kGoogleDocAppId, - extension_misc::kGoogleSheetsAppId, - extension_misc::kGoogleSlidesAppId, - extension_misc::kCameraAppId, - extension_misc::kGooglePhotosAppId, - arc::kPlayStoreAppId}; + extension_misc::kGmailAppId, + web_app::kGmailAppId, + + extension_misc::kGoogleDocAppId, + web_app::kGoogleDocsAppId, + + extension_misc::kGooglePhotosAppId, + + extension_misc::kYoutubeAppId, + web_app::kYoutubeAppId, + + arc::kPlayStoreAppId, +}; + +const char* kDefaultPinnedApps10Apps[] = { + extension_misc::kFilesManagerAppId, + + extension_misc::kGmailAppId, + web_app::kGmailAppId, + + extension_misc::kCalendarAppId, + web_app::kGoogleCalendarAppId, + + extension_misc::kGoogleDocAppId, + web_app::kGoogleDocsAppId, + + extension_misc::kGoogleSheetsAppId, + web_app::kGoogleSheetsAppId, + + extension_misc::kGoogleSlidesAppId, + web_app::kGoogleSlidesAppId, + + extension_misc::kCameraAppId, + web_app::kCameraAppId, + + extension_misc::kGooglePhotosAppId, + + arc::kPlayStoreAppId, +}; const char* kTabletFormFactorDefaultPinnedApps[] = { extension_misc::kFilesManagerAppId, arc::kGmailAppId,
diff --git a/chrome/browser/ui/ash/clipboard_history_browsertest.cc b/chrome/browser/ui/ash/clipboard_history_browsertest.cc index a6bdf78..02385390 100644 --- a/chrome/browser/ui/ash/clipboard_history_browsertest.cc +++ b/chrome/browser/ui/ash/clipboard_history_browsertest.cc
@@ -158,8 +158,15 @@ run_loop.Run(); } - void ShowContextMenuViaAccelerator() { + void ShowContextMenuViaAccelerator(bool wait_for_selection) { PressAndRelease(ui::KeyboardCode::VKEY_V, ui::EF_COMMAND_DOWN); + if (!wait_for_selection) + return; + + base::RunLoop run_loop; + GetClipboardHistoryController() + ->set_initial_item_selected_callback_for_test(run_loop.QuitClosure()); + run_loop.Run(); } const views::MenuItemView* GetMenuItemViewForIndex(int index) const { @@ -268,7 +275,7 @@ SetClipboardText("B"); SetClipboardText("C"); - ShowContextMenuViaAccelerator(); + ShowContextMenuViaAccelerator(/*wait_for_selection=*/true); ASSERT_TRUE(GetClipboardHistoryController()->IsMenuShowing()); ASSERT_EQ(3, GetContextMenu()->GetMenuItemsCount()); @@ -319,7 +326,7 @@ SetClipboardText("A"); SetClipboardText("B"); - ShowContextMenuViaAccelerator(); + ShowContextMenuViaAccelerator(/*wait_for_selection=*/true); // Verify the default state right after the menu shows. ASSERT_TRUE(GetClipboardHistoryController()->IsMenuShowing()); @@ -393,7 +400,7 @@ LoginUser(account_id1_); SetClipboardText("A"); - ShowContextMenuViaAccelerator(); + ShowContextMenuViaAccelerator(/*wait_for_selection=*/true); // Verify the default state right after the menu shows. ASSERT_TRUE(GetClipboardHistoryController()->IsMenuShowing()); @@ -427,7 +434,7 @@ // No clipboard data. So the clipboard history menu should not show. ASSERT_TRUE(GetClipboardItems().empty()); - ShowContextMenuViaAccelerator(); + ShowContextMenuViaAccelerator(/*wait_for_selection=*/false); EXPECT_FALSE(GetClipboardHistoryController()->IsMenuShowing()); SetClipboardText("test"); @@ -435,7 +442,7 @@ const gfx::Point mouse_location = ash::Shell::Get()->GetPrimaryRootWindow()->bounds().CenterPoint(); GetEventGenerator()->MoveMouseTo(mouse_location); - ShowContextMenuViaAccelerator(); + ShowContextMenuViaAccelerator(/*wait_for_selection=*/true); // Verifies that the menu is anchored at the cursor's location. ASSERT_TRUE(GetClipboardHistoryController()->IsMenuShowing()); @@ -459,7 +466,7 @@ SetClipboardText("C"); // Show the menu. - ShowContextMenuViaAccelerator(); + ShowContextMenuViaAccelerator(/*wait_for_selection=*/true); ASSERT_TRUE(GetClipboardHistoryController()->IsMenuShowing()); ASSERT_EQ(3, GetContextMenu()->GetMenuItemsCount()); @@ -485,7 +492,7 @@ // Trigger the accelerator of opening the clipboard history menu. No menu // shows because of the empty history data. - ShowContextMenuViaAccelerator(); + ShowContextMenuViaAccelerator(/*wait_for_selection=*/false); EXPECT_FALSE(GetClipboardHistoryController()->IsMenuShowing()); } @@ -637,7 +644,7 @@ VerifyResponseToGestures) { SetClipboardText("A"); SetClipboardText("B"); - ShowContextMenuViaAccelerator(); + ShowContextMenuViaAccelerator(/*wait_for_selection=*/true); ASSERT_TRUE(GetClipboardHistoryController()->IsMenuShowing()); // Tap at the second menu item view. Verify that "A" is pasted. @@ -655,7 +662,7 @@ DeleteButtonShowAfterLongPress) { SetClipboardText("A"); SetClipboardText("B"); - ShowContextMenuViaAccelerator(); + ShowContextMenuViaAccelerator(/*wait_for_selection=*/true); ASSERT_TRUE(GetClipboardHistoryController()->IsMenuShowing()); ash::ClipboardHistoryItemView* second_item_view = @@ -690,9 +697,7 @@ SetClipboardText("B"); SetClipboardText("C"); - // Verify we can paste the first history item via the COMMAND+V shortcut. - PressAndRelease(ui::KeyboardCode::VKEY_V, ui::EF_COMMAND_DOWN); - + ShowContextMenuViaAccelerator(/*wait_for_selection=*/true); EXPECT_TRUE(GetClipboardHistoryController()->IsMenuShowing()); histogram_tester.ExpectTotalCount( "Ash.ClipboardHistory.ContextMenu.DisplayFormatShown", 3); @@ -707,10 +712,10 @@ textfield_->SetText(base::string16()); EXPECT_TRUE(textfield_->GetText().empty()); - // Verify we can paste the first history item via the COMMAND+V shortcut. - PressAndRelease(ui::KeyboardCode::VKEY_V, ui::EF_COMMAND_DOWN); - + ShowContextMenuViaAccelerator(/*wait_for_selection=*/true); EXPECT_TRUE(GetClipboardHistoryController()->IsMenuShowing()); + + // Verify we can paste the first history item via the COMMAND+V shortcut. PressAndRelease(ui::KeyboardCode::VKEY_V, ui::EF_COMMAND_DOWN); EXPECT_FALSE(GetClipboardHistoryController()->IsMenuShowing()); @@ -719,9 +724,7 @@ textfield_->SetText(base::string16()); EXPECT_TRUE(textfield_->GetText().empty()); - // Verify we can paste the first history item via the COMMAND+V shortcut. - PressAndRelease(ui::KeyboardCode::VKEY_V, ui::EF_COMMAND_DOWN); - + ShowContextMenuViaAccelerator(/*wait_for_selection=*/true); EXPECT_TRUE(GetClipboardHistoryController()->IsMenuShowing()); PressAndRelease(ui::KeyboardCode::VKEY_DOWN); @@ -735,9 +738,7 @@ EXPECT_TRUE(textfield_->GetText().empty()); - // Verify we can paste the last history item via the COMMAND+V shortcut. - PressAndRelease(ui::KeyboardCode::VKEY_V, ui::EF_COMMAND_DOWN); - + ShowContextMenuViaAccelerator(/*wait_for_selection=*/true); EXPECT_TRUE(GetClipboardHistoryController()->IsMenuShowing()); PressAndRelease(ui::KeyboardCode::VKEY_DOWN); @@ -757,8 +758,7 @@ // Verify we can traverse clipboard history and paste the first history item // while holding down the COMMAND key. - Press(ui::KeyboardCode::VKEY_COMMAND); - PressAndRelease(ui::KeyboardCode::VKEY_V, ui::EF_COMMAND_DOWN); + ShowContextMenuViaAccelerator(/*wait_for_selection=*/true); EXPECT_TRUE(GetClipboardHistoryController()->IsMenuShowing()); PressAndRelease(ui::KeyboardCode::VKEY_V, ui::EF_COMMAND_DOWN); EXPECT_FALSE(GetClipboardHistoryController()->IsMenuShowing()); @@ -770,8 +770,7 @@ // Verify we can traverse clipboard history and paste the last history item // while holding down the COMMAND key. - Press(ui::KeyboardCode::VKEY_COMMAND); - PressAndRelease(ui::KeyboardCode::VKEY_V, ui::EF_COMMAND_DOWN); + ShowContextMenuViaAccelerator(/*wait_for_selection=*/true); EXPECT_TRUE(GetClipboardHistoryController()->IsMenuShowing()); PressAndRelease(ui::KeyboardCode::VKEY_DOWN, ui::EF_COMMAND_DOWN); PressAndRelease(ui::KeyboardCode::VKEY_DOWN, ui::EF_COMMAND_DOWN); @@ -854,7 +853,7 @@ SetClipboardTextWithInaccessibleSrc("B"); EXPECT_TRUE(VerifyClipboardTextData({"B", "A"})); - ShowContextMenuViaAccelerator(); + ShowContextMenuViaAccelerator(/*wait_for_selection=*/true); EXPECT_TRUE(GetClipboardHistoryController()->IsMenuShowing()); // Verify that the text is pasted into `textfield_` after the mouse click at @@ -874,7 +873,7 @@ // Re-show the multipaste menu since the menu is closed after the previous // mouse click. ASSERT_FALSE(GetClipboardHistoryController()->IsMenuShowing()); - ShowContextMenuViaAccelerator(); + ShowContextMenuViaAccelerator(/*wait_for_selection=*/true); // Move mouse to `inaccessible_menu_item_view` then click the left button. const views::MenuItemView* inaccessible_menu_item_view =
diff --git a/chrome/browser/ui/ash/network/enrollment_dialog_view.cc b/chrome/browser/ui/ash/network/enrollment_dialog_view.cc index f1865675..1840990f 100644 --- a/chrome/browser/ui/ash/network/enrollment_dialog_view.cc +++ b/chrome/browser/ui/ash/network/enrollment_dialog_view.cc
@@ -262,7 +262,7 @@ case LoginState::LOGGED_IN_USER_PUBLIC_ACCOUNT: case LoginState::LOGGED_IN_USER_PUBLIC_ACCOUNT_MANAGED: return false; - case LoginState::LOGGED_IN_USER_SUPERVISED: + case LoginState::LOGGED_IN_USER_SUPERVISED_DEPRECATED: return true; case LoginState::LOGGED_IN_USER_KIOSK_APP: return false;
diff --git a/chrome/browser/ui/chrome_pages.cc b/chrome/browser/ui/chrome_pages.cc index 333bfb6c..5246dbb 100644 --- a/chrome/browser/ui/chrome_pages.cc +++ b/chrome/browser/ui/chrome_pages.cc
@@ -473,6 +473,14 @@ chromeos::scanning::RecordScanAppEntryPoint(entry_point); } +void ShowDiagnosticsApp(Profile* profile) { + // TODO(joonbug): Add entry point tracking + DCHECK(base::FeatureList::IsEnabled(chromeos::features::kDiagnosticsApp)); + + LaunchSystemWebApp(profile, web_app::SystemAppType::DIAGNOSTICS, + GURL(chrome::kChromeUIDiagnosticsAppURL)); +} + 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 61bc833..16d3f1d 100644 --- a/chrome/browser/ui/chrome_pages.h +++ b/chrome/browser/ui/chrome_pages.h
@@ -164,6 +164,8 @@ void ShowScanningApp(Profile* profile, chromeos::scanning::ScanAppEntryPoint entry_point); + +void ShowDiagnosticsApp(Profile* profile); #endif #if !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/chrome/browser/ui/tab_helpers.cc b/chrome/browser/ui/tab_helpers.cc index 6df56ea..1a711416 100644 --- a/chrome/browser/ui/tab_helpers.cc +++ b/chrome/browser/ui/tab_helpers.cc
@@ -25,7 +25,6 @@ #include "chrome/browser/content_settings/sound_content_setting_observer.h" #include "chrome/browser/data_reduction_proxy/data_reduction_proxy_tab_helper.h" #include "chrome/browser/engagement/site_engagement_helper.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/external_protocol/external_protocol_observer.h" #include "chrome/browser/favicon/favicon_utils.h" #include "chrome/browser/history/history_tab_helper.h" @@ -109,6 +108,7 @@ #include "components/performance_manager/public/performance_manager.h" #include "components/permissions/features.h" #include "components/permissions/permission_request_manager.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "components/sync/engine/sync_engine_switches.h" #include "components/tracing/common/tracing_switches.h" #include "components/ukm/content/source_url_recorder.h"
diff --git a/chrome/browser/ui/thumbnails/thumbnail_image.cc b/chrome/browser/ui/thumbnails/thumbnail_image.cc index 32730e140..171f1df 100644 --- a/chrome/browser/ui/thumbnails/thumbnail_image.cc +++ b/chrome/browser/ui/thumbnails/thumbnail_image.cc
@@ -4,8 +4,10 @@ #include "chrome/browser/ui/thumbnails/thumbnail_image.h" +#include <algorithm> #include <utility> +#include "base/memory/ptr_util.h" #include "base/metrics/histogram_macros.h" #include "base/task/post_task.h" #include "base/task/task_traits.h" @@ -15,15 +17,12 @@ #include "ui/gfx/codec/jpeg_codec.h" #include "ui/gfx/skia_util.h" -void ThumbnailImage::Observer::OnThumbnailImageAvailable( - gfx::ImageSkia thumbnail_image) {} +ThumbnailImage::Subscription::Subscription( + scoped_refptr<ThumbnailImage> thumbnail) + : thumbnail_(std::move(thumbnail)) {} -void ThumbnailImage::Observer::OnCompressedThumbnailDataAvailable( - CompressedThumbnailData thumbnail_data) {} - -base::Optional<gfx::Size> ThumbnailImage::Observer::GetThumbnailSizeHint() - const { - return base::nullopt; +ThumbnailImage::Subscription::~Subscription() { + thumbnail_->HandleSubscriptionDestroyed(this); } ThumbnailImage::Delegate::~Delegate() { @@ -46,29 +45,17 @@ delegate_->thumbnail_ = nullptr; } -void ThumbnailImage::AddObserver(Observer* observer) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK(observer); - if (!observers_.HasObserver(observer)) { - const bool is_first_observer = !observers_.might_have_observers(); - observers_.AddObserver(observer); - if (is_first_observer && delegate_) - delegate_->ThumbnailImageBeingObservedChanged(true); - } -} +std::unique_ptr<ThumbnailImage::Subscription> ThumbnailImage::Subscribe() { + // Use explicit new since Subscription constructor is private. + auto subscription = + base::WrapUnique(new Subscription(base::WrapRefCounted(this))); + subscribers_.insert(subscribers_.end(), subscription.get()); -void ThumbnailImage::RemoveObserver(Observer* observer) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK(observer); - if (observers_.HasObserver(observer)) { - observers_.RemoveObserver(observer); - if (delegate_ && !observers_.might_have_observers()) - delegate_->ThumbnailImageBeingObservedChanged(false); - } -} + // Notify |delegate_| if this is the first subscriber. + if (subscribers_.size() == 1) + delegate_->ThumbnailImageBeingObservedChanged(true); -bool ThumbnailImage::HasObserver(const Observer* observer) const { - return observers_.HasObserver(observer); + return subscription; } void ThumbnailImage::AssignSkBitmap(SkBitmap bitmap) { @@ -147,18 +134,22 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (async_operation_finished_callback_) async_operation_finished_callback_.Run(); - for (auto& observer : observers_) { - auto size_hint = observer.GetThumbnailSizeHint(); - observer.OnThumbnailImageAvailable( - size_hint ? CropPreviewImage(image, *size_hint) : image); + + for (Subscription* subscription : subscribers_) { + auto size_hint = subscription->size_hint_; + if (subscription->uncompressed_image_callback_) + subscription->uncompressed_image_callback_.Run( + size_hint ? CropPreviewImage(image, *size_hint) : image); } } void ThumbnailImage::NotifyCompressedDataObservers( CompressedThumbnailData data) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - for (auto& observer : observers_) - observer.OnCompressedThumbnailDataAvailable(data); + for (Subscription* subscription : subscribers_) { + if (subscription->compressed_image_callback_) + subscription->compressed_image_callback_.Run(data); + } } // static @@ -216,3 +207,17 @@ source_image.bitmap()->extractSubset(&cropped, gfx::RectToSkIRect(clip_rect)); return gfx::ImageSkia::CreateFrom1xBitmap(cropped); } + +void ThumbnailImage::HandleSubscriptionDestroyed(Subscription* subscription) { + // The order of |subscribers_| does not matter. We can simply swap + // |subscription| in |subscribers_| with the last element, then pop it + // off the back. + auto it = std::find(subscribers_.begin(), subscribers_.end(), subscription); + DCHECK(it != subscribers_.end()); + std::swap(*it, *(subscribers_.end() - 1)); + subscribers_.pop_back(); + + // If that was the last subscriber, tell |delegate_| (if it still exists). + if (delegate_ && subscribers_.empty()) + delegate_->ThumbnailImageBeingObservedChanged(false); +}
diff --git a/chrome/browser/ui/thumbnails/thumbnail_image.h b/chrome/browser/ui/thumbnails/thumbnail_image.h index dbad55c..20646d41 100644 --- a/chrome/browser/ui/thumbnails/thumbnail_image.h +++ b/chrome/browser/ui/thumbnails/thumbnail_image.h
@@ -5,10 +5,12 @@ #ifndef CHROME_BROWSER_UI_THUMBNAILS_THUMBNAIL_IMAGE_H_ #define CHROME_BROWSER_UI_THUMBNAILS_THUMBNAIL_IMAGE_H_ +#include <memory> #include <utility> #include <vector> #include "base/callback.h" +#include "base/containers/flat_set.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "base/observer_list.h" @@ -29,16 +31,27 @@ using CompressedThumbnailData = scoped_refptr<base::RefCountedData<std::vector<uint8_t>>>; - // Observes uncompressed and/or compressed versions of the thumbnail image as - // they are available. - class Observer : public base::CheckedObserver { + class Subscription { public: - // Receives uncompressed thumbnail image data. Default is no-op. - virtual void OnThumbnailImageAvailable(gfx::ImageSkia thumbnail_image); + Subscription() = delete; + ~Subscription(); - // Receives compressed thumbnail image data. Default is no-op. - virtual void OnCompressedThumbnailDataAvailable( - CompressedThumbnailData thumbnail_data); + using UncompressedImageCallback = + base::RepeatingCallback<void(gfx::ImageSkia)>; + using CompressedImageCallback = + base::RepeatingCallback<void(CompressedThumbnailData)>; + + // Set callbacks to receive image data. Subscribers are not allowed + // to unsubscribe (by destroying |this|) from the callback. If + // necessary, post a task to destroy it soon after. + + void SetUncompressedImageCallback(UncompressedImageCallback callback) { + uncompressed_image_callback_ = std::move(callback); + } + + void SetCompressedImageCallback(CompressedImageCallback callback) { + compressed_image_callback_ = std::move(callback); + } // Provides a desired aspect ratio and minimum size that the observer will // accept. If not specified, or if available thumbnail data is smaller in @@ -54,7 +67,20 @@ // image passed to OnThumbnailImageAvailable fits the needs of the observer // for display purposes, without the observer having to further crop the // image. The default is unspecified. - virtual base::Optional<gfx::Size> GetThumbnailSizeHint() const; + void SetSizeHint(const base::Optional<gfx::Size>& size_hint) { + size_hint_ = size_hint; + } + + private: + friend class ThumbnailImage; + + explicit Subscription(scoped_refptr<ThumbnailImage> thumbnail); + + scoped_refptr<ThumbnailImage> thumbnail_; + base::Optional<gfx::Size> size_hint_; + + UncompressedImageCallback uncompressed_image_callback_; + CompressedImageCallback compressed_image_callback_; }; // Represents the endpoint @@ -77,9 +103,14 @@ bool has_data() const { return data_.get(); } - void AddObserver(Observer* observer); - void RemoveObserver(Observer* observer); - bool HasObserver(const Observer* observer) const; + // Subscribe to thumbnail updates. See |Subscription| to set a + // callback and conigure additional options. + // + // Even if a callback is not set, the subscription influences + // thumbnail capture. It should be destroyed when updates are not + // needed. It is designed to be stored in base::Optional, created and + // destroyed as needed. + std::unique_ptr<Subscription> Subscribe(); // Sets the SkBitmap data and notifies observers with the resulting image. void AssignSkBitmap(SkBitmap bitmap); @@ -130,6 +161,8 @@ static gfx::ImageSkia CropPreviewImage(const gfx::ImageSkia& source_image, const gfx::Size& minimum_size); + void HandleSubscriptionDestroyed(Subscription* subscription); + Delegate* delegate_; // This is a scoped_refptr to immutable data. Once set, the wrapped @@ -138,7 +171,12 @@ // the old data. CompressedThumbnailData data_; - base::ObserverList<Observer> observers_; + // Subscriptions are inserted on |Subscribe()| calls and removed when + // they are destroyed via callback. The order of subscriber + // notification doesn't matter, so don't maintain any ordering. Since + // the number of subscribers for a given thumbnail is expected to be + // small, doing a linear search to remove a subscriber is fine. + std::vector<Subscription*> subscribers_; // Called when an asynchronous operation (such as encoding image data upon // assignment or decoding image data for observers) finishes or fails.
diff --git a/chrome/browser/ui/thumbnails/thumbnail_image_unittest.cc b/chrome/browser/ui/thumbnails/thumbnail_image_unittest.cc index 308715a..f97c137 100644 --- a/chrome/browser/ui/thumbnails/thumbnail_image_unittest.cc +++ b/chrome/browser/ui/thumbnails/thumbnail_image_unittest.cc
@@ -9,6 +9,7 @@ #include "base/bind.h" #include "base/macros.h" +#include "base/memory/weak_ptr.h" #include "base/run_loop.h" #include "base/scoped_observer.h" #include "base/test/task_environment.h" @@ -20,81 +21,56 @@ constexpr int kTestBitmapWidth = 200; constexpr int kTestBitmapHeight = 123; -// Waits for thumbnail images (or compressed data) and can report how many -// images it has received. -class TestThumbnailImageObserver : public ThumbnailImage::Observer { +template <typename... T> +base::RepeatingCallback<void(T...)> IgnoreArgs( + base::RepeatingCallback<void()> cb) { + auto helper = [](T...) {}; + return base::BindRepeating(helper).Then(std::move(cb)); +} + +class CallbackWaiter { public: - // Wait for the uncompressed thumbnail image. - void WaitForImage() { - if (new_image_count_ > last_image_count_) { - last_image_count_ = new_image_count_; + CallbackWaiter() { + callback_ = base::BindRepeating(&CallbackWaiter::HandleCallback, + weak_ptr_factory_.GetWeakPtr()); + } + + base::RepeatingClosure callback() { return callback_; } + + bool called() const { return called_; } + + void Reset() { called_ = false; } + + void Wait() { + if (called_) return; - } - // Need a fresh loop since we may have quit out of the last one. - run_loop_ = std::make_unique<base::RunLoop>(); - waiting_for_image_ = true; - run_loop_->Run(); - } - - // Wait for compressed thumbnail data. - void WaitForCompressedData() { - if (new_compressed_count_ > last_compressed_count_) { - last_compressed_count_ = new_compressed_count_; - return; - } - - // Need a fresh loop since we may have quit out of the last one. - run_loop_ = std::make_unique<base::RunLoop>(); - waiting_for_data_ = true; - run_loop_->Run(); - } - - int new_image_count() const { return new_image_count_; } - gfx::ImageSkia thumbnail_image() const { return thumbnail_image_; } - int new_compressed_count() const { return new_compressed_count_; } - ThumbnailImage::CompressedThumbnailData compressed_data() const { - return compressed_data_; - } - - ScopedObserver<ThumbnailImage, ThumbnailImage::Observer>* scoped_observer() { - return &scoped_observer_; + base::RunLoop run_loop; + quit_closure_ = run_loop.QuitClosure(); + run_loop.Run(); } private: - // ThumbnailImage::Observer: - void OnThumbnailImageAvailable(gfx::ImageSkia thumbnail_image) override { - ++new_image_count_; - thumbnail_image_ = thumbnail_image; - if (waiting_for_image_) { - last_image_count_ = new_image_count_; - run_loop_->Quit(); - waiting_for_image_ = false; - } + void HandleCallback() { + if (quit_closure_) + std::move(quit_closure_).Run(); + called_ = true; } - void OnCompressedThumbnailDataAvailable( - ThumbnailImage::CompressedThumbnailData thumbnail_data) override { - ++new_compressed_count_; - compressed_data_ = thumbnail_data; - if (waiting_for_data_) { - last_compressed_count_ = new_compressed_count_; - run_loop_->Quit(); - waiting_for_data_ = false; - } - } + base::RepeatingClosure callback_; + base::OnceClosure quit_closure_; + bool called_ = false; - ScopedObserver<ThumbnailImage, ThumbnailImage::Observer> scoped_observer_{ - this}; - int new_image_count_ = 0; - int last_image_count_ = 0; - gfx::ImageSkia thumbnail_image_; - int new_compressed_count_ = 0; - int last_compressed_count_ = 0; - ThumbnailImage::CompressedThumbnailData compressed_data_; - bool waiting_for_image_ = false; - bool waiting_for_data_ = false; - std::unique_ptr<base::RunLoop> run_loop_; + base::WeakPtrFactory<CallbackWaiter> weak_ptr_factory_{this}; +}; + +class StubDelegate : public ThumbnailImage::Delegate { + public: + StubDelegate() = default; + ~StubDelegate() override = default; + + // ThumbnailImage::Delegate: + void ThumbnailImageBeingObservedChanged(bool is_being_observed) override {} }; } // anonymous namespace @@ -128,169 +104,228 @@ DISALLOW_COPY_AND_ASSIGN(ThumbnailImageTest); }; -TEST_F(ThumbnailImageTest, Add_Remove_Observer) { +using Subscription = ThumbnailImage::Subscription; + +TEST_F(ThumbnailImageTest, AddRemoveSubscriber) { auto image = base::MakeRefCounted<ThumbnailImage>(this); EXPECT_FALSE(is_being_observed()); - TestThumbnailImageObserver observer; - image->AddObserver(&observer); - EXPECT_TRUE(image->HasObserver(&observer)); + + std::unique_ptr<Subscription> subscription = image->Subscribe(); EXPECT_TRUE(is_being_observed()); - image->RemoveObserver(&observer); - EXPECT_FALSE(image->HasObserver(&observer)); + + subscription.reset(); EXPECT_FALSE(is_being_observed()); } -TEST_F(ThumbnailImageTest, Add_Remove_MultipleObservers) { +TEST_F(ThumbnailImageTest, AddRemoveMultipleObservers) { auto image = base::MakeRefCounted<ThumbnailImage>(this); EXPECT_FALSE(is_being_observed()); - TestThumbnailImageObserver observer; - TestThumbnailImageObserver observer2; - image->AddObserver(&observer); - EXPECT_TRUE(image->HasObserver(&observer)); + + std::unique_ptr<Subscription> subscription1 = image->Subscribe(); EXPECT_TRUE(is_being_observed()); - image->AddObserver(&observer2); - EXPECT_TRUE(image->HasObserver(&observer2)); + + std::unique_ptr<Subscription> subscription2 = image->Subscribe(); EXPECT_TRUE(is_being_observed()); - image->RemoveObserver(&observer); - EXPECT_FALSE(image->HasObserver(&observer)); - EXPECT_TRUE(image->HasObserver(&observer2)); + + subscription1.reset(); EXPECT_TRUE(is_being_observed()); - image->RemoveObserver(&observer2); - EXPECT_FALSE(image->HasObserver(&observer2)); + + subscription2.reset(); EXPECT_FALSE(is_being_observed()); } -TEST_F(ThumbnailImageTest, AssignSkBitmap_NotifiesObservers) { +TEST_F(ThumbnailImageTest, AssignSkBitmapNotifiesObservers) { auto image = base::MakeRefCounted<ThumbnailImage>(this); - TestThumbnailImageObserver observer; - TestThumbnailImageObserver observer2; - observer.scoped_observer()->Add(image.get()); - observer2.scoped_observer()->Add(image.get()); + + std::unique_ptr<Subscription> subscription1 = image->Subscribe(); + std::unique_ptr<Subscription> subscription2 = image->Subscribe(); + + CallbackWaiter waiter1; + subscription1->SetUncompressedImageCallback( + IgnoreArgs<gfx::ImageSkia>(waiter1.callback())); + + CallbackWaiter waiter2; + subscription2->SetUncompressedImageCallback( + IgnoreArgs<gfx::ImageSkia>(waiter2.callback())); SkBitmap bitmap = CreateBitmap(kTestBitmapWidth, kTestBitmapHeight); image->AssignSkBitmap(bitmap); - observer.WaitForImage(); - observer2.WaitForImage(); - EXPECT_EQ(1, observer.new_image_count()); - EXPECT_EQ(1, observer2.new_image_count()); - EXPECT_FALSE(observer.thumbnail_image().isNull()); - EXPECT_FALSE(observer2.thumbnail_image().isNull()); - EXPECT_EQ(gfx::Size(kTestBitmapWidth, kTestBitmapHeight), - observer.thumbnail_image().size()); + + waiter1.Wait(); + waiter2.Wait(); + EXPECT_TRUE(waiter1.called()); + EXPECT_TRUE(waiter2.called()); } TEST_F(ThumbnailImageTest, AssignSkBitmap_NotifiesObserversAgain) { auto image = base::MakeRefCounted<ThumbnailImage>(this); - TestThumbnailImageObserver observer; - TestThumbnailImageObserver observer2; - observer.scoped_observer()->Add(image.get()); - observer2.scoped_observer()->Add(image.get()); + + std::unique_ptr<Subscription> subscription1 = image->Subscribe(); + std::unique_ptr<Subscription> subscription2 = image->Subscribe(); + + CallbackWaiter waiter1; + subscription1->SetUncompressedImageCallback( + IgnoreArgs<gfx::ImageSkia>(waiter1.callback())); + + CallbackWaiter waiter2; + subscription2->SetUncompressedImageCallback( + IgnoreArgs<gfx::ImageSkia>(waiter2.callback())); SkBitmap bitmap = CreateBitmap(kTestBitmapWidth, kTestBitmapHeight); image->AssignSkBitmap(bitmap); - observer.WaitForImage(); - observer2.WaitForImage(); + + waiter1.Wait(); + waiter2.Wait(); + EXPECT_TRUE(waiter1.called()); + EXPECT_TRUE(waiter2.called()); + + waiter1.Reset(); + waiter2.Reset(); + image->AssignSkBitmap(bitmap); - observer.WaitForImage(); - observer2.WaitForImage(); - EXPECT_EQ(2, observer.new_image_count()); - EXPECT_EQ(2, observer2.new_image_count()); - EXPECT_FALSE(observer.thumbnail_image().isNull()); - EXPECT_FALSE(observer2.thumbnail_image().isNull()); - EXPECT_EQ(gfx::Size(kTestBitmapWidth, kTestBitmapHeight), - observer.thumbnail_image().size()); + + waiter1.Wait(); + waiter2.Wait(); + EXPECT_TRUE(waiter1.called()); + EXPECT_TRUE(waiter2.called()); } TEST_F(ThumbnailImageTest, AssignSkBitmap_NotifiesCompressedObservers) { auto image = base::MakeRefCounted<ThumbnailImage>(this); - TestThumbnailImageObserver observer; - TestThumbnailImageObserver observer2; - observer.scoped_observer()->Add(image.get()); - observer2.scoped_observer()->Add(image.get()); + + std::unique_ptr<Subscription> subscription1 = image->Subscribe(); + std::unique_ptr<Subscription> subscription2 = image->Subscribe(); + + CallbackWaiter waiter1; + subscription1->SetCompressedImageCallback( + IgnoreArgs<ThumbnailImage::CompressedThumbnailData>(waiter1.callback())); + + CallbackWaiter waiter2; + subscription2->SetCompressedImageCallback( + IgnoreArgs<ThumbnailImage::CompressedThumbnailData>(waiter2.callback())); SkBitmap bitmap = CreateBitmap(kTestBitmapWidth, kTestBitmapHeight); - auto compressed = Compress(bitmap); - image->AssignSkBitmap(bitmap); - observer.WaitForCompressedData(); - observer2.WaitForCompressedData(); - EXPECT_EQ(1, observer.new_compressed_count()); - EXPECT_EQ(1, observer2.new_compressed_count()); - EXPECT_TRUE(observer.compressed_data()); - EXPECT_TRUE(observer2.compressed_data()); - EXPECT_EQ(compressed, observer.compressed_data()->data); - EXPECT_EQ(compressed, observer2.compressed_data()->data); + + waiter1.Wait(); + waiter2.Wait(); + EXPECT_TRUE(waiter1.called()); + EXPECT_TRUE(waiter2.called()); } TEST_F(ThumbnailImageTest, AssignSkBitmap_NotifiesCompressedObserversAgain) { auto image = base::MakeRefCounted<ThumbnailImage>(this); - TestThumbnailImageObserver observer; - TestThumbnailImageObserver observer2; - observer.scoped_observer()->Add(image.get()); - observer2.scoped_observer()->Add(image.get()); + + std::unique_ptr<Subscription> subscription1 = image->Subscribe(); + std::unique_ptr<Subscription> subscription2 = image->Subscribe(); + + CallbackWaiter waiter1; + subscription1->SetCompressedImageCallback( + IgnoreArgs<ThumbnailImage::CompressedThumbnailData>(waiter1.callback())); + + CallbackWaiter waiter2; + subscription2->SetCompressedImageCallback( + IgnoreArgs<ThumbnailImage::CompressedThumbnailData>(waiter2.callback())); SkBitmap bitmap = CreateBitmap(kTestBitmapWidth, kTestBitmapHeight); - auto compressed = Compress(bitmap); + image->AssignSkBitmap(bitmap); + + waiter1.Wait(); + waiter2.Wait(); + EXPECT_TRUE(waiter1.called()); + EXPECT_TRUE(waiter2.called()); + + waiter1.Reset(); + waiter2.Reset(); image->AssignSkBitmap(bitmap); - observer.WaitForCompressedData(); - observer2.WaitForCompressedData(); - image->AssignSkBitmap(bitmap); - observer.WaitForCompressedData(); - observer2.WaitForCompressedData(); - EXPECT_EQ(2, observer.new_compressed_count()); - EXPECT_EQ(2, observer2.new_compressed_count()); - EXPECT_TRUE(observer.compressed_data()); - EXPECT_TRUE(observer2.compressed_data()); - EXPECT_EQ(compressed, observer.compressed_data()->data); - EXPECT_EQ(compressed, observer2.compressed_data()->data); + + waiter1.Wait(); + waiter2.Wait(); + EXPECT_TRUE(waiter1.called()); + EXPECT_TRUE(waiter2.called()); } TEST_F(ThumbnailImageTest, RequestThumbnailImage) { auto image = base::MakeRefCounted<ThumbnailImage>(this); - TestThumbnailImageObserver observer; - observer.scoped_observer()->Add(image.get()); + + std::unique_ptr<Subscription> subscription1 = image->Subscribe(); + + CallbackWaiter waiter1; + subscription1->SetUncompressedImageCallback( + IgnoreArgs<gfx::ImageSkia>(waiter1.callback())); SkBitmap bitmap = CreateBitmap(kTestBitmapWidth, kTestBitmapHeight); image->AssignSkBitmap(bitmap); - observer.WaitForImage(); + waiter1.Wait(); + EXPECT_TRUE(waiter1.called()); + waiter1.Reset(); - TestThumbnailImageObserver observer2; - observer2.scoped_observer()->Add(image.get()); + std::unique_ptr<Subscription> subscription2 = image->Subscribe(); + + CallbackWaiter waiter2; + subscription2->SetUncompressedImageCallback( + IgnoreArgs<gfx::ImageSkia>(waiter2.callback())); + image->RequestThumbnailImage(); - observer.WaitForImage(); - observer2.WaitForImage(); - EXPECT_EQ(2, observer.new_image_count()); - EXPECT_EQ(1, observer2.new_image_count()); - EXPECT_FALSE(observer2.thumbnail_image().isNull()); - EXPECT_EQ(gfx::Size(kTestBitmapWidth, kTestBitmapHeight), - observer2.thumbnail_image().size()); + waiter1.Wait(); + waiter2.Wait(); + EXPECT_TRUE(waiter1.called()); + EXPECT_TRUE(waiter2.called()); } TEST_F(ThumbnailImageTest, RequestCompressedThumbnailData) { auto image = base::MakeRefCounted<ThumbnailImage>(this); - TestThumbnailImageObserver observer; - observer.scoped_observer()->Add(image.get()); - SkBitmap bitmap = CreateBitmap(kTestBitmapHeight, kTestBitmapHeight); + std::unique_ptr<Subscription> subscription = image->Subscribe(); + + CallbackWaiter waiter; + subscription->SetCompressedImageCallback( + IgnoreArgs<ThumbnailImage::CompressedThumbnailData>(waiter.callback())); + + SkBitmap bitmap = CreateBitmap(kTestBitmapWidth, kTestBitmapHeight); image->AssignSkBitmap(bitmap); - observer.WaitForImage(); + waiter.Wait(); + EXPECT_TRUE(waiter.called()); + waiter.Reset(); - const int count_before_request = observer.new_compressed_count(); image->RequestCompressedThumbnailData(); - EXPECT_EQ(count_before_request + 1, observer.new_compressed_count()); + waiter.Wait(); + EXPECT_TRUE(waiter.called()); } TEST_F(ThumbnailImageTest, ClearThumbnailWhileNotifyingObservers) { auto image = base::MakeRefCounted<ThumbnailImage>(this); - TestThumbnailImageObserver observer; - observer.scoped_observer()->Add(image.get()); + + std::unique_ptr<Subscription> subscription = image->Subscribe(); + + CallbackWaiter waiter; + subscription->SetUncompressedImageCallback( + IgnoreArgs<gfx::ImageSkia>(waiter.callback())); SkBitmap bitmap = CreateBitmap(kTestBitmapWidth, kTestBitmapHeight); image->AssignSkBitmap(bitmap); - observer.WaitForImage(); + waiter.Wait(); + EXPECT_TRUE(waiter.called()); + waiter.Reset(); image->RequestThumbnailImage(); image->ClearData(); - observer.WaitForImage(); + waiter.Wait(); + EXPECT_TRUE(waiter.called()); +} + +// Makes sure a null dereference does not happen. Regression test for +// crbug.com/1159701. +TEST_F(ThumbnailImageTest, UnsubscribeAfterDelegateDestroyed) { + auto delegate = std::make_unique<StubDelegate>(); + auto image = base::MakeRefCounted<ThumbnailImage>(delegate.get()); + + std::unique_ptr<Subscription> subscription = image->Subscribe(); + + // Normally |image| will notify its delegate when the last + // subscription is destroyed. When there is no delegate it shouldn't + // do anything. + delegate.reset(); + subscription.reset(); }
diff --git a/chrome/browser/ui/thumbnails/thumbnail_tab_helper_browsertest.cc b/chrome/browser/ui/thumbnails/thumbnail_tab_helper_browsertest.cc index 3e1ce62..6ecc30d0 100644 --- a/chrome/browser/ui/thumbnails/thumbnail_tab_helper_browsertest.cc +++ b/chrome/browser/ui/thumbnails/thumbnail_tab_helper_browsertest.cc
@@ -29,37 +29,30 @@ namespace { -class ThumbnailWaiter : public ThumbnailImage::Observer { +class ThumbnailWaiter { public: ThumbnailWaiter() = default; - ~ThumbnailWaiter() override = default; + ~ThumbnailWaiter() = default; base::Optional<gfx::ImageSkia> WaitForThumbnail(ThumbnailImage* thumbnail) { - DCHECK(!thumbnail_); - thumbnail_ = thumbnail; - scoped_observer_.Add(thumbnail); - thumbnail_->RequestThumbnailImage(); + std::unique_ptr<ThumbnailImage::Subscription> subscription = + thumbnail->Subscribe(); + subscription->SetUncompressedImageCallback(base::BindRepeating( + &ThumbnailWaiter::ThumbnailImageCallback, base::Unretained(this))); + thumbnail->RequestThumbnailImage(); run_loop_.Run(); return image_; } protected: - // ThumbnailImage::Observer: - void OnThumbnailImageAvailable(gfx::ImageSkia thumbnail_image) override { - if (thumbnail_) { - scoped_observer_.Remove(thumbnail_); - thumbnail_ = nullptr; - image_ = thumbnail_image; - run_loop_.Quit(); - } + void ThumbnailImageCallback(gfx::ImageSkia thumbnail_image) { + image_ = std::move(thumbnail_image); + run_loop_.Quit(); } private: base::RunLoop run_loop_; - ThumbnailImage* thumbnail_ = nullptr; base::Optional<gfx::ImageSkia> image_; - ScopedObserver<ThumbnailImage, ThumbnailImage::Observer> scoped_observer_{ - this}; }; } // anonymous namespace
diff --git a/chrome/browser/ui/views/DEPS b/chrome/browser/ui/views/DEPS index 7200cc38..35bccc4 100644 --- a/chrome/browser/ui/views/DEPS +++ b/chrome/browser/ui/views/DEPS
@@ -7,8 +7,8 @@ specific_include_rules = { "chrome_views_delegate_chromeos\.cc": [ + "+ash/public/cpp/ash_features.h", "+ash/shell.h", - "+ash/wm/window_state.h", ], "qrcode_generator\.*": [ "+chrome/services/qrcode_generator/public/cpp/qrcode_generator_service.h"
diff --git a/chrome/browser/ui/views/chrome_views_delegate.h b/chrome/browser/ui/views/chrome_views_delegate.h index 7ea8195..c8f7f20e 100644 --- a/chrome/browser/ui/views/chrome_views_delegate.h +++ b/chrome/browser/ui/views/chrome_views_delegate.h
@@ -36,6 +36,7 @@ #if BUILDFLAG(IS_CHROMEOS_ASH) ProcessMenuAcceleratorResult ProcessAcceleratorWhileMenuShowing( const ui::Accelerator& accelerator) override; + bool ShouldCloseMenuIfMouseCaptureLost() const override; std::unique_ptr<views::NonClientFrameView> CreateDefaultNonClientFrameView( views::Widget* widget) override; #endif
diff --git a/chrome/browser/ui/views/chrome_views_delegate_chromeos.cc b/chrome/browser/ui/views/chrome_views_delegate_chromeos.cc index 3a88c87..ffdc7de 100644 --- a/chrome/browser/ui/views/chrome_views_delegate_chromeos.cc +++ b/chrome/browser/ui/views/chrome_views_delegate_chromeos.cc
@@ -5,10 +5,12 @@ #include "chrome/browser/ui/views/chrome_views_delegate.h" #include "ash/public/cpp/accelerators.h" +#include "ash/public/cpp/ash_features.h" #include "ash/shell.h" #include "base/bind.h" #include "base/task/current_thread.h" #include "base/threading/thread_task_runner_handle.h" +#include "chrome/browser/ui/ash/chrome_capture_mode_delegate.h" #include "ui/display/display.h" #include "ui/display/screen.h" @@ -37,6 +39,12 @@ return views::ViewsDelegate::ProcessMenuAcceleratorResult::LEAVE_MENU_OPEN; } +bool ChromeViewsDelegate::ShouldCloseMenuIfMouseCaptureLost() const { + // Menu closes unless an ongoing screen capture session is underway. + return !(ash::features::IsCaptureModeEnabled() && + ChromeCaptureModeDelegate::Get()->is_session_active()); +} + std::unique_ptr<views::NonClientFrameView> ChromeViewsDelegate::CreateDefaultNonClientFrameView(views::Widget* widget) { return ash::Shell::Get()->CreateDefaultNonClientFrameView(widget);
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_view_unittest.cc b/chrome/browser/ui/views/extensions/extensions_menu_view_unittest.cc index 75502bb..0bdaee81 100644 --- a/chrome/browser/ui/views/extensions/extensions_menu_view_unittest.cc +++ b/chrome/browser/ui/views/extensions/extensions_menu_view_unittest.cc
@@ -43,6 +43,7 @@ #include "ui/gfx/geometry/point.h" #include "ui/views/controls/button/image_button.h" #include "ui/views/layout/animating_layout_manager_test_util.h" +#include "ui/views/view_utils.h" #include "ui/views/widget/widget.h" namespace { @@ -196,7 +197,7 @@ std::vector<ToolbarActionView*> result; for (views::View* child : extensions_container()->children()) { // Ensure we don't downcast the ExtensionsToolbarButton. - if (child->GetClassName() == ToolbarActionView::kClassName) { + if (views::IsViewClass<ToolbarActionView>(child)) { ToolbarActionView* const action = static_cast<ToolbarActionView*>(child); #if defined(OS_MAC) // TODO(crbug.com/1045212): Use IsActionVisibleOnToolbar() because it @@ -533,7 +534,7 @@ // Since the extension is removed it's no longer visible on the toolbar or in // the menu. for (views::View* child : extensions_container()->children()) - EXPECT_NE(ToolbarActionView::kClassName, child->GetClassName()); + EXPECT_FALSE(views::IsViewClass<ToolbarActionView>(child)); EXPECT_EQ(0u, extensions_menu()->extensions_menu_items_for_testing().size()); }
diff --git a/chrome/browser/ui/views/extensions/extensions_toolbar_browsertest.cc b/chrome/browser/ui/views/extensions/extensions_toolbar_browsertest.cc index c96cbb8..e378ea09 100644 --- a/chrome/browser/ui/views/extensions/extensions_toolbar_browsertest.cc +++ b/chrome/browser/ui/views/extensions/extensions_toolbar_browsertest.cc
@@ -16,6 +16,7 @@ #include "chrome/common/chrome_paths.h" #include "net/dns/mock_host_resolver.h" #include "ui/views/layout/animating_layout_manager_test_util.h" +#include "ui/views/view_utils.h" ExtensionsToolbarBrowserTest::ExtensionsToolbarBrowserTest(bool enable_flag) { if (enable_flag) { @@ -80,7 +81,7 @@ ExtensionsToolbarBrowserTest::GetToolbarActionViews() const { std::vector<ToolbarActionView*> views; for (auto* view : GetExtensionsToolbarContainer()->children()) { - if (view->GetClassName() == ToolbarActionView::kClassName) + if (views::IsViewClass<ToolbarActionView>(view)) views.push_back(static_cast<ToolbarActionView*>(view)); } return views;
diff --git a/chrome/browser/ui/views/extensions/extensions_toolbar_container.cc b/chrome/browser/ui/views/extensions/extensions_toolbar_container.cc index 9826b68..84d6c8b 100644 --- a/chrome/browser/ui/views/extensions/extensions_toolbar_container.cc +++ b/chrome/browser/ui/views/extensions/extensions_toolbar_container.cc
@@ -87,7 +87,7 @@ } extensions_button_->SetID(VIEW_ID_EXTENSIONS_MENU_BUTTON); AddMainButton(extensions_button_); - target_layout_manager() + GetTargetLayoutManager() ->SetFlexAllocationOrder(views::FlexAllocationOrder::kReverse) .SetDefault(views::kFlexBehaviorKey, hide_icon_flex_specification.WithOrder(3)); @@ -136,7 +136,7 @@ anchored_widgets_.push_back({widget, extension_id}); widget->AddObserver(this); UpdateIconVisibility(extension_id); - animating_layout_manager()->PostOrQueueAction(base::BindOnce( + GetAnimatingLayoutManager()->PostOrQueueAction(base::BindOnce( &ExtensionsToolbarContainer::AnchorAndShowWidgetImmediately, weak_ptr_factory_.GetWeakPtr(), widget)); } @@ -207,9 +207,9 @@ if (must_show || (CanShowIconInToolbar() && model_->IsActionPinned(extension_id))) - animating_layout_manager()->FadeIn(action_view); + GetAnimatingLayoutManager()->FadeIn(action_view); else - animating_layout_manager()->FadeOut(action_view); + GetAnimatingLayoutManager()->FadeOut(action_view); } void ExtensionsToolbarContainer::AnchorAndShowWidgetImmediately( @@ -349,7 +349,7 @@ DCHECK(!popped_out_action_); popped_out_action_ = action; UpdateIconVisibility(action->GetId()); - animating_layout_manager()->PostOrQueueAction(std::move(closure)); + GetAnimatingLayoutManager()->PostOrQueueAction(std::move(closure)); UpdateContainerVisibility(); } @@ -629,7 +629,7 @@ drop_info_->action_id; drop_info_.reset(); ReorderViews(); - animating_layout_manager()->PostOrQueueAction(base::BindOnce( + GetAnimatingLayoutManager()->PostOrQueueAction(base::BindOnce( &ExtensionsToolbarContainer::SetExtensionIconVisibility, weak_ptr_factory_.GetWeakPtr(), dragged_extension_id, true)); } @@ -703,7 +703,7 @@ // Layout animation does not handle host view visibility changing; requires // resetting. if (was_visible != GetVisible()) - animating_layout_manager()->ResetLayout(); + GetAnimatingLayoutManager()->ResetLayout(); if (!was_visible && GetVisible() && GetOnVisibleCallbackForTesting()) std::move(GetOnVisibleCallbackForTesting()).Run(); @@ -719,7 +719,7 @@ if (display_mode_ != DisplayMode::kAutoHide) return true; - if (animating_layout_manager()->is_animating()) + if (GetAnimatingLayoutManager()->is_animating()) return true; // Is menu showing. @@ -738,7 +738,7 @@ } void ExtensionsToolbarContainer::UpdateContainerVisibilityAfterAnimation() { - animating_layout_manager()->PostOrQueueAction( + GetAnimatingLayoutManager()->PostOrQueueAction( base::BindOnce(&ExtensionsToolbarContainer::UpdateContainerVisibility, weak_ptr_factory_.GetWeakPtr())); }
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index faaa693..27b5324 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -1549,7 +1549,7 @@ // location. // // Not used on the Mac, which has a normal menu bar. - if (toolbar_->IsAppMenuFocused()) { + if (toolbar_->GetAppMenuFocused()) { RestoreFocus(); } else { DCHECK(!immersive_mode_controller_->IsEnabled());
diff --git a/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc b/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc index f9b51dc..103b692 100644 --- a/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc +++ b/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc
@@ -492,7 +492,6 @@ frame_background_->set_frame_color(frame_color); frame_background_->set_use_custom_frame(frame()->UseCustomFrame()); frame_background_->set_is_active(active); - frame_background_->set_incognito(browser_view()->IsIncognito()); frame_background_->set_theme_image(GetFrameImage()); const int y_inset = browser_view()->IsTabStripVisible()
diff --git a/chrome/browser/ui/views/global_media_controls/media_dialog_view_interactive_browsertest.cc b/chrome/browser/ui/views/global_media_controls/media_dialog_view_interactive_browsertest.cc index 168b3e03..e9c78c8e 100644 --- a/chrome/browser/ui/views/global_media_controls/media_dialog_view_interactive_browsertest.cc +++ b/chrome/browser/ui/views/global_media_controls/media_dialog_view_interactive_browsertest.cc
@@ -882,7 +882,13 @@ EXPECT_TRUE(IsPlayingSessionDisplayedFirst()); } -IN_PROC_BROWSER_TEST_F(MediaDialogViewBrowserTest, LiveCaption) { +// Flaky on Mac: crbug.com/1163666 +#if defined(OS_MAC) +#define MAYBE_LiveCaption DISABLED_LiveCaption +#else +#define MAYBE_LiveCaption LiveCaption +#endif // defined(OS_MAC) +IN_PROC_BROWSER_TEST_F(MediaDialogViewBrowserTest, MAYBE_LiveCaption) { // Open a tab and play media. OpenTestURL(); StartPlayback();
diff --git a/chrome/browser/ui/views/hover_button_controller.cc b/chrome/browser/ui/views/hover_button_controller.cc index aaa3335..5d6cfa1 100644 --- a/chrome/browser/ui/views/hover_button_controller.cc +++ b/chrome/browser/ui/views/hover_button_controller.cc
@@ -58,9 +58,9 @@ void HoverButtonController::OnGestureEvent(ui::GestureEvent* event) { if (event->type() == ui::ET_GESTURE_TAP) { + button()->SetState(views::Button::STATE_NORMAL); if (callback_) callback_.Run(*event); - button()->SetState(views::Button::STATE_NORMAL); } else { ButtonController::OnGestureEvent(event); }
diff --git a/chrome/browser/ui/views/hover_button_unittest.cc b/chrome/browser/ui/views/hover_button_unittest.cc index c212ab0..4d79e60 100644 --- a/chrome/browser/ui/views/hover_button_unittest.cc +++ b/chrome/browser/ui/views/hover_button_unittest.cc
@@ -8,6 +8,7 @@ #include "base/stl_util.h" #include "base/strings/utf_string_conversions.h" +#include "build/build_config.h" #include "chrome/test/views/chrome_views_test_base.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/accessibility/ax_enums.mojom.h" @@ -159,4 +160,31 @@ widget()->Close(); } +// No touch on desktop Mac. +#if !defined(OS_MAC) || defined(USE_AURA) + +// Tests that tapping hover button does not crash if the tap handler removes the +// button from views hierarchy. +TEST_F(HoverButtonTest, TapGestureThatDeletesTheButton) { + bool clicked = false; + HoverButton* button = widget()->SetContentsView(std::make_unique<HoverButton>( + base::BindRepeating( + [](bool* clicked, views::Widget* widget) { + *clicked = true; + // Update the widget contents view, which deletes the hover button. + widget->SetContentsView(std::make_unique<views::View>()); + }, + &clicked, widget()), + CreateIcon(), base::ASCIIToUTF16("Title"), base::string16())); + button->SetBoundsRect(gfx::Rect(100, 100, 200, 200)); + widget()->Show(); + + generator()->GestureTapAt(gfx::Point(150, 150)); + EXPECT_TRUE(clicked); + + widget()->Close(); +} + +#endif // !defined(OS_MAC) || defined(USE_AURA) + } // namespace
diff --git a/chrome/browser/ui/views/location_bar/icon_label_bubble_view.cc b/chrome/browser/ui/views/location_bar/icon_label_bubble_view.cc index 8cbbac9f..9841681 100644 --- a/chrome/browser/ui/views/location_bar/icon_label_bubble_view.cc +++ b/chrome/browser/ui/views/location_bar/icon_label_bubble_view.cc
@@ -30,6 +30,7 @@ #include "ui/views/border.h" #include "ui/views/controls/highlight_path_generator.h" #include "ui/views/controls/image_view.h" +#include "ui/views/metadata/metadata_impl_macros.h" #include "ui/views/widget/widget.h" namespace { @@ -439,10 +440,6 @@ return end_padding; } -const char* IconLabelBubbleView::GetClassName() const { - return "IconLabelBubbleView"; -} - void IconLabelBubbleView::SetUpForAnimation() { SetInkDropMode(InkDropMode::ON); SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY); @@ -566,3 +563,12 @@ gfx::Insets(GetLayoutConstant(LOCATION_BAR_CHILD_INTERIOR_PADDING), GetLayoutInsets(LOCATION_BAR_ICON_INTERIOR_PADDING).left()))); } + +BEGIN_METADATA(IconLabelBubbleView, views::LabelButton) +ADD_READONLY_PROPERTY_METADATA(SkColor, ForegroundColor) +ADD_READONLY_PROPERTY_METADATA(double, AnimationValue) +ADD_READONLY_PROPERTY_METADATA(int, InternalSpacing) +ADD_READONLY_PROPERTY_METADATA(int, ExtraInternalSpacing) +ADD_READONLY_PROPERTY_METADATA(int, WidthBetweenIconAndSeparator) +ADD_READONLY_PROPERTY_METADATA(int, EndPaddingWithSeparator) +END_METADATA
diff --git a/chrome/browser/ui/views/location_bar/icon_label_bubble_view.h b/chrome/browser/ui/views/location_bar/icon_label_bubble_view.h index 02a3dd2c..f5d9df0 100644 --- a/chrome/browser/ui/views/location_bar/icon_label_bubble_view.h +++ b/chrome/browser/ui/views/location_bar/icon_label_bubble_view.h
@@ -20,6 +20,7 @@ #include "ui/views/animation/ink_drop_observer.h" #include "ui/views/controls/button/label_button.h" #include "ui/views/controls/label.h" +#include "ui/views/metadata/metadata_header_macros.h" #include "ui/views/widget/widget_observer.h" namespace gfx { @@ -41,6 +42,8 @@ class IconLabelBubbleView : public views::InkDropObserver, public views::LabelButton { public: + METADATA_HEADER(IconLabelBubbleView); + static constexpr int kTrailingPaddingPreMd = 2; class Delegate { @@ -172,10 +175,6 @@ // the animation is set to fully shown or fully hidden. void ResetSlideAnimation(bool show); - // Returns true iff the slide animation has started, has not ended and is - // currently paused. - bool is_animation_paused() const { return is_animation_paused_; } - // Slide animation for label. gfx::SlideAnimation slide_animation_{this}; @@ -218,9 +217,6 @@ // separator width. int GetEndPaddingWithSeparator() const; - // views::View: - const char* GetClassName() const override; - // Disables highlights and calls Show on the slide animation, should not be // called directly, use AnimateIn() instead, which handles label visibility. void ShowAnimation();
diff --git a/chrome/browser/ui/views/location_bar/star_view.cc b/chrome/browser/ui/views/location_bar/star_view.cc index 9edaafeb..b725178 100644 --- a/chrome/browser/ui/views/location_bar/star_view.cc +++ b/chrome/browser/ui/views/location_bar/star_view.cc
@@ -77,7 +77,7 @@ OnExecuting(source); if (base::FeatureList::IsEnabled(reading_list::switches::kReadLater)) { menu_model_ = std::make_unique<StarMenuModel>( - this, active(), chrome::CanMoveActiveTabToReadLater(browser_), + this, GetActive(), chrome::CanMoveActiveTabToReadLater(browser_), chrome::IsCurrentTabUnreadInReadLater(browser_)); menu_runner_ = std::make_unique<views::MenuRunner>( menu_model_.get(), @@ -95,12 +95,12 @@ } const gfx::VectorIcon& StarView::GetVectorIcon() const { - return active() ? omnibox::kStarActiveIcon : omnibox::kStarIcon; + return GetActive() ? omnibox::kStarActiveIcon : omnibox::kStarIcon; } base::string16 StarView::GetTextForTooltipAndAccessibleName() const { - return l10n_util::GetStringUTF16(active() ? IDS_TOOLTIP_STARRED - : IDS_TOOLTIP_STAR); + return l10n_util::GetStringUTF16(GetActive() ? IDS_TOOLTIP_STARRED + : IDS_TOOLTIP_STAR); } const char* StarView::GetClassName() const {
diff --git a/chrome/browser/ui/views/location_bar/star_view_interactive_uitest.cc b/chrome/browser/ui/views/location_bar/star_view_interactive_uitest.cc index 2ffd82d..dd5f664 100644 --- a/chrome/browser/ui/views/location_bar/star_view_interactive_uitest.cc +++ b/chrome/browser/ui/views/location_bar/star_view_interactive_uitest.cc
@@ -66,7 +66,7 @@ // The page should not initiall be bookmarked. EXPECT_FALSE(bookmark_model->IsBookmarked(current_url)); - EXPECT_FALSE(star_icon->active()); + EXPECT_FALSE(star_icon->GetActive()); ui::MouseEvent pressed_event(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(), ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, @@ -79,7 +79,7 @@ static_cast<views::View*>(star_icon)->OnMouseReleased(released_event); EXPECT_TRUE(bookmark_model->IsBookmarked(current_url)); - EXPECT_TRUE(star_icon->active()); + EXPECT_TRUE(star_icon->GetActive()); } // Verify that clicking the bookmark star a second time hides the bookmark @@ -176,13 +176,13 @@ // The page should not initially be bookmarked. EXPECT_FALSE(bookmark_model->IsBookmarked(current_url)); - EXPECT_FALSE(star_icon->active()); + EXPECT_FALSE(star_icon->GetActive()); OpenStarViewMenu(star_icon); // The page should not be bookmarked when the menu is opened. EXPECT_FALSE(bookmark_model->IsBookmarked(current_url)); - EXPECT_FALSE(star_icon->active()); + EXPECT_FALSE(star_icon->GetActive()); StarMenuModel* menu_model = star_icon->menu_model_for_test(); @@ -193,7 +193,7 @@ menu_model->ActivatedAt(bookmark_command_index); EXPECT_TRUE(bookmark_model->IsBookmarked(current_url)); - EXPECT_TRUE(star_icon->active()); + EXPECT_TRUE(star_icon->GetActive()); } // Verifies clicking the Read Later button in the StarView's menu saves the page @@ -212,13 +212,13 @@ // The page should not initially be in model. EXPECT_EQ(reading_list_model->GetEntryByURL(current_url), nullptr); - EXPECT_FALSE(star_icon->active()); + EXPECT_FALSE(star_icon->GetActive()); OpenStarViewMenu(star_icon); // The page should not be bookmarked when the menu is opened. EXPECT_EQ(reading_list_model->GetEntryByURL(current_url), nullptr); - EXPECT_FALSE(star_icon->active()); + EXPECT_FALSE(star_icon->GetActive()); StarMenuModel* menu_model = star_icon->menu_model_for_test(); @@ -229,7 +229,7 @@ menu_model->ActivatedAt(read_later_command_index); EXPECT_NE(reading_list_model->GetEntryByURL(current_url), nullptr); - EXPECT_FALSE(star_icon->active()); + EXPECT_FALSE(star_icon->GetActive()); } } // namespace
diff --git a/chrome/browser/ui/views/page_action/page_action_icon_container.cc b/chrome/browser/ui/views/page_action/page_action_icon_container.cc index 9ef2b28c..8da1bcf9 100644 --- a/chrome/browser/ui/views/page_action/page_action_icon_container.cc +++ b/chrome/browser/ui/views/page_action/page_action_icon_container.cc
@@ -7,11 +7,7 @@ #include "chrome/browser/ui/views/page_action/page_action_icon_controller.h" #include "chrome/browser/ui/views/page_action/page_action_icon_params.h" #include "ui/views/layout/box_layout.h" - -// static -const char - PageActionIconContainerView::kPageActionIconContainerViewClassName[] = - "PageActionIconContainerView"; +#include "ui/views/metadata/metadata_impl_macros.h" PageActionIconContainerView::PageActionIconContainerView( const PageActionIconParams& params) @@ -28,10 +24,6 @@ PageActionIconContainerView::~PageActionIconContainerView() = default; -const char* PageActionIconContainerView::GetClassName() const { - return kPageActionIconContainerViewClassName; -} - void PageActionIconContainerView::ChildPreferredSizeChanged( views::View* child) { PreferredSizeChanged(); @@ -40,3 +32,6 @@ void PageActionIconContainerView::AddPageActionIcon(views::View* icon) { AddChildView(icon); } + +BEGIN_METADATA(PageActionIconContainerView, views::View) +END_METADATA
diff --git a/chrome/browser/ui/views/page_action/page_action_icon_container.h b/chrome/browser/ui/views/page_action/page_action_icon_container.h index 85447e4..002dfab8 100644 --- a/chrome/browser/ui/views/page_action/page_action_icon_container.h +++ b/chrome/browser/ui/views/page_action/page_action_icon_container.h
@@ -5,6 +5,7 @@ #ifndef CHROME_BROWSER_UI_VIEWS_PAGE_ACTION_PAGE_ACTION_ICON_CONTAINER_H_ #define CHROME_BROWSER_UI_VIEWS_PAGE_ACTION_PAGE_ACTION_ICON_CONTAINER_H_ +#include "ui/views/metadata/metadata_header_macros.h" #include "ui/views/view.h" class PageActionIconController; @@ -22,16 +23,15 @@ class PageActionIconContainerView : public views::View, public PageActionIconContainer { public: + METADATA_HEADER(PageActionIconContainerView); explicit PageActionIconContainerView(const PageActionIconParams& params); + PageActionIconContainerView(const PageActionIconContainerView&) = delete; + PageActionIconContainerView& operator=(const PageActionIconContainerView&) = + delete; ~PageActionIconContainerView() override; PageActionIconController* controller() { return controller_.get(); } - // views::View: - const char* GetClassName() const override; - - static const char kPageActionIconContainerViewClassName[]; - private: // views::View: void ChildPreferredSizeChanged(views::View* child) override; @@ -40,8 +40,6 @@ void AddPageActionIcon(views::View* icon) override; std::unique_ptr<PageActionIconController> controller_; - - DISALLOW_COPY_AND_ASSIGN(PageActionIconContainerView); }; #endif // CHROME_BROWSER_UI_VIEWS_PAGE_ACTION_PAGE_ACTION_ICON_CONTAINER_H_
diff --git a/chrome/browser/ui/views/page_action/page_action_icon_view.cc b/chrome/browser/ui/views/page_action/page_action_icon_view.cc index 7b363dc6..9aa36d6c 100644 --- a/chrome/browser/ui/views/page_action/page_action_icon_view.cc +++ b/chrome/browser/ui/views/page_action/page_action_icon_view.cc
@@ -24,6 +24,7 @@ #include "ui/views/bubble/bubble_dialog_delegate_view.h" #include "ui/views/controls/button/button_controller.h" #include "ui/views/controls/focus_ring.h" +#include "ui/views/metadata/metadata_impl_macros.h" #include "ui/views/style/platform_style.h" float PageActionIconView::Delegate::GetPageActionInkDropVisibleOpacity() const { @@ -181,13 +182,16 @@ IconLabelBubbleView::OnTouchUiChanged(); } -const char* PageActionIconView::GetClassName() const { - return "PageActionIconView"; -} - void PageActionIconView::SetIconColor(SkColor icon_color) { + if (icon_color_ == icon_color) + return; icon_color_ = icon_color; UpdateIconImage(); + OnPropertyChanged(&icon_color_, views::kPropertyEffectsNone); +} + +SkColor PageActionIconView::GetIconColor() const { + return icon_color_; } void PageActionIconView::SetActive(bool active) { @@ -195,6 +199,11 @@ return; active_ = active; UpdateIconImage(); + OnPropertyChanged(&active_, views::kPropertyEffectsNone); +} + +bool PageActionIconView::GetActive() const { + return active_; } void PageActionIconView::Update() { @@ -247,3 +256,8 @@ if (new_insets != GetInsets()) SetBorder(views::CreateEmptyBorder(new_insets)); } + +BEGIN_METADATA(PageActionIconView, IconLabelBubbleView) +ADD_PROPERTY_METADATA(SkColor, IconColor) +ADD_PROPERTY_METADATA(bool, Active) +END_METADATA
diff --git a/chrome/browser/ui/views/page_action/page_action_icon_view.h b/chrome/browser/ui/views/page_action/page_action_icon_view.h index b2c3c05..02f108c 100644 --- a/chrome/browser/ui/views/page_action/page_action_icon_view.h +++ b/chrome/browser/ui/views/page_action/page_action_icon_view.h
@@ -7,7 +7,6 @@ #include <memory> -#include "base/macros.h" #include "chrome/browser/ui/layout_constants.h" #include "chrome/browser/ui/omnibox/omnibox_theme.h" #include "chrome/browser/ui/views/location_bar/icon_label_bubble_view.h" @@ -16,6 +15,7 @@ #include "ui/gfx/image/image_skia.h" #include "ui/views/animation/ink_drop_host_view.h" #include "ui/views/controls/image_view.h" +#include "ui/views/metadata/metadata_header_macros.h" class CommandUpdater; class OmniboxView; @@ -37,6 +37,8 @@ // shows a bubble when clicked. class PageActionIconView : public IconLabelBubbleView { public: + METADATA_HEADER(PageActionIconView); + class Delegate { public: // Gets the opacity to use for the ink highlight. @@ -56,15 +58,18 @@ virtual const OmniboxView* GetOmniboxView() const; }; + PageActionIconView(const PageActionIconView&) = delete; + PageActionIconView& operator=(const PageActionIconView&) = delete; ~PageActionIconView() override; // Updates the color of the icon, this must be set before the icon is drawn. void SetIconColor(SkColor icon_color); + SkColor GetIconColor() const; // Sets the active state of the icon. An active icon will be displayed in a // "call to action" color. void SetActive(bool active); - bool active() const { return active_; } + bool GetActive() const; // Hide the icon on user input in progress and invokes UpdateImpl(). void Update(); @@ -135,7 +140,6 @@ // IconLabelBubbleView: void OnTouchUiChanged() override; - const char* GetClassName() const override; // Updates the icon image after some state has changed. virtual void UpdateIconImage(); @@ -181,8 +185,6 @@ // The loading indicator, showing a throbber animation on top of the icon. PageActionIconLoadingIndicatorView* loading_indicator_ = nullptr; - - DISALLOW_COPY_AND_ASSIGN(PageActionIconView); }; #endif // CHROME_BROWSER_UI_VIEWS_PAGE_ACTION_PAGE_ACTION_ICON_VIEW_H_
diff --git a/chrome/browser/ui/views/page_action/pwa_install_view.cc b/chrome/browser/ui/views/page_action/pwa_install_view.cc index 07f5f0f..8cd6e0f 100644 --- a/chrome/browser/ui/views/page_action/pwa_install_view.cc +++ b/chrome/browser/ui/views/page_action/pwa_install_view.cc
@@ -14,7 +14,6 @@ #include "base/time/time.h" #include "chrome/app/chrome_command_ids.h" #include "chrome/browser/banners/app_banner_manager.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/user_education/feature_promo_controller.h" #include "chrome/browser/ui/user_education/feature_promo_text_replacements.h" @@ -28,8 +27,10 @@ #include "chrome/grit/generated_resources.h" #include "components/feature_engagement/public/feature_constants.h" #include "components/omnibox/browser/vector_icons.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "components/webapps/installable/installable_metrics.h" #include "ui/base/l10n/l10n_util.h" +#include "ui/views/metadata/metadata_impl_macros.h" namespace { @@ -188,10 +189,6 @@ webapps::AppBannerManager::GetInstallableWebAppName(web_contents)); } -const char* PwaInstallView::GetClassName() const { - return "PwaInstallView"; -} - bool PwaInstallView::ShouldShowIph(content::WebContents* web_contents, webapps::AppBannerManager* manager) { auto start_url = manager->GetManifestStartUrl(); @@ -207,3 +204,6 @@ return score > kIphSiteEngagementThresholdParam.Get() && web_app::ShouldShowIph(profile->GetPrefs(), app_id); } + +BEGIN_METADATA(PwaInstallView, PageActionIconView) +END_METADATA
diff --git a/chrome/browser/ui/views/page_action/pwa_install_view.h b/chrome/browser/ui/views/page_action/pwa_install_view.h index 3a07455..8e59282 100644 --- a/chrome/browser/ui/views/page_action/pwa_install_view.h +++ b/chrome/browser/ui/views/page_action/pwa_install_view.h
@@ -5,8 +5,8 @@ #ifndef CHROME_BROWSER_UI_VIEWS_PAGE_ACTION_PWA_INSTALL_VIEW_H_ #define CHROME_BROWSER_UI_VIEWS_PAGE_ACTION_PWA_INSTALL_VIEW_H_ -#include "base/macros.h" #include "chrome/browser/ui/views/page_action/page_action_icon_view.h" +#include "ui/views/metadata/metadata_header_macros.h" namespace webapps { class AppBannerManager; @@ -16,10 +16,13 @@ // installability checks and can be installed. class PwaInstallView : public PageActionIconView { public: + METADATA_HEADER(PwaInstallView); explicit PwaInstallView( CommandUpdater* command_updater, IconLabelBubbleView::Delegate* icon_label_bubble_delegate, PageActionIconView::Delegate* page_action_icon_delegate); + PwaInstallView(const PwaInstallView&) = delete; + PwaInstallView& operator=(const PwaInstallView&) = delete; ~PwaInstallView() override; protected: @@ -29,7 +32,6 @@ views::BubbleDialogDelegate* GetBubble() const override; const gfx::VectorIcon& GetVectorIcon() const override; base::string16 GetTextForTooltipAndAccessibleName() const override; - const char* GetClassName() const override; private: // Called when IPH is closed. @@ -43,8 +45,6 @@ webapps::AppBannerManager* manager); base::WeakPtrFactory<PwaInstallView> weak_ptr_factory_{this}; - - DISALLOW_COPY_AND_ASSIGN(PwaInstallView); }; #endif // CHROME_BROWSER_UI_VIEWS_PAGE_ACTION_PWA_INSTALL_VIEW_H_
diff --git a/chrome/browser/ui/views/page_action/pwa_install_view_browsertest.cc b/chrome/browser/ui/views/page_action/pwa_install_view_browsertest.cc index c876d10..8e6d6e3 100644 --- a/chrome/browser/ui/views/page_action/pwa_install_view_browsertest.cc +++ b/chrome/browser/ui/views/page_action/pwa_install_view_browsertest.cc
@@ -11,7 +11,6 @@ #include "base/test/scoped_feature_list.h" #include "build/chromeos_buildflags.h" #include "chrome/browser/banners/test_app_banner_manager_desktop.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/extensions/extension_browsertest.h" #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/browser_dialogs.h" @@ -36,6 +35,7 @@ #include "components/feature_engagement/public/feature_list.h" #include "components/omnibox/browser/omnibox_popup_model.h" #include "components/omnibox/browser/omnibox_view.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "components/webapps/installable/installable_metrics.h" #include "content/public/common/referrer.h" #include "content/public/test/browser_test.h"
diff --git a/chrome/browser/ui/views/page_action/zoom_view.cc b/chrome/browser/ui/views/page_action/zoom_view.cc index 07ef9946..481e3fa 100644 --- a/chrome/browser/ui/views/page_action/zoom_view.cc +++ b/chrome/browser/ui/views/page_action/zoom_view.cc
@@ -15,6 +15,7 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/events/event.h" #include "ui/gfx/geometry/size.h" +#include "ui/views/metadata/metadata_impl_macros.h" ZoomView::ZoomView(IconLabelBubbleView::Delegate* icon_label_bubble_delegate, PageActionIconView::Delegate* page_action_icon_delegate) @@ -113,6 +114,5 @@ base::FormatPercent(current_zoom_percent_)); } -const char* ZoomView::GetClassName() const { - return "ZoomView"; -} +BEGIN_METADATA(ZoomView, PageActionIconView) +END_METADATA
diff --git a/chrome/browser/ui/views/page_action/zoom_view.h b/chrome/browser/ui/views/page_action/zoom_view.h index d7bc4f3c..5489307 100644 --- a/chrome/browser/ui/views/page_action/zoom_view.h +++ b/chrome/browser/ui/views/page_action/zoom_view.h
@@ -5,18 +5,21 @@ #ifndef CHROME_BROWSER_UI_VIEWS_PAGE_ACTION_ZOOM_VIEW_H_ #define CHROME_BROWSER_UI_VIEWS_PAGE_ACTION_ZOOM_VIEW_H_ -#include "base/macros.h" #include "chrome/browser/ui/views/page_action/page_action_icon_view.h" +#include "ui/views/metadata/metadata_header_macros.h" // View for the zoom icon in the Omnibox. class ZoomView : public PageActionIconView { public: + METADATA_HEADER(ZoomView); // Clicking on the ZoomView shows a ZoomBubbleView, which requires the current // WebContents. Because the current WebContents changes as the user switches // tabs, a LocationBarView::Delegate is supplied to queried for the current // WebContents when needed. ZoomView(IconLabelBubbleView::Delegate* icon_label_bubble_delegate, PageActionIconView::Delegate* page_action_icon_delegate); + ZoomView(const ZoomView&) = delete; + ZoomView& operator=(const ZoomView&) = delete; ~ZoomView() override; // Updates the image and its tooltip appropriately, hiding or showing the icon @@ -30,7 +33,6 @@ views::BubbleDialogDelegate* GetBubble() const override; const gfx::VectorIcon& GetVectorIcon() const override; base::string16 GetTextForTooltipAndAccessibleName() const override; - const char* GetClassName() const override; private: bool ShouldBeVisible(bool can_show_bubble) const; @@ -39,8 +41,6 @@ const gfx::VectorIcon* icon_ = nullptr; int current_zoom_percent_ = 100; - - DISALLOW_COPY_AND_ASSIGN(ZoomView); }; #endif // CHROME_BROWSER_UI_VIEWS_PAGE_ACTION_ZOOM_VIEW_H_
diff --git a/chrome/browser/ui/views/page_info/safety_tip_page_info_bubble_view_browsertest.cc b/chrome/browser/ui/views/page_info/safety_tip_page_info_bubble_view_browsertest.cc index ecf5e225..94e32b4 100644 --- a/chrome/browser/ui/views/page_info/safety_tip_page_info_bubble_view_browsertest.cc +++ b/chrome/browser/ui/views/page_info/safety_tip_page_info_bubble_view_browsertest.cc
@@ -13,7 +13,6 @@ #include "base/test/scoped_feature_list.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/history/history_service_factory.h" #include "chrome/browser/history/history_test_utils.h" #include "chrome/browser/reputation/reputation_service.h" @@ -39,6 +38,7 @@ #include "components/security_state/core/features.h" #include "components/security_state/core/security_state.h" #include "components/site_engagement/content/site_engagement_score.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "components/strings/grit/components_chromium_strings.h" #include "components/strings/grit/components_strings.h" #include "components/ukm/test_ukm_recorder.h"
diff --git a/chrome/browser/ui/views/profiles/avatar_toolbar_button.cc b/chrome/browser/ui/views/profiles/avatar_toolbar_button.cc index d16b5e3c..bd5b9f28 100644 --- a/chrome/browser/ui/views/profiles/avatar_toolbar_button.cc +++ b/chrome/browser/ui/views/profiles/avatar_toolbar_button.cc
@@ -193,7 +193,7 @@ } bool AvatarToolbarButton::IsParentHighlighted() const { - return parent_ && parent_->IsHighlighted(); + return parent_ && parent_->GetHighlighted(); } void AvatarToolbarButton::AddObserver(Observer* observer) {
diff --git a/chrome/browser/ui/views/profiles/profile_picker_view.cc b/chrome/browser/ui/views/profiles/profile_picker_view.cc index a1fe350..8aa69b0c 100644 --- a/chrome/browser/ui/views/profiles/profile_picker_view.cc +++ b/chrome/browser/ui/views/profiles/profile_picker_view.cc
@@ -464,11 +464,6 @@ // browser crashes before finishing the flow. entry->SetIsEphemeral(true); - // TODO(crbug.com/1126913): Record also that we show the sign-in promo - // (it has to be plumbed from js to profile_picker_handler.cc): - // signin_metrics::RecordSigninImpressionUserActionForAccessPoint( - // signin_metrics::AccessPoint::ACCESS_POINT_USER_MANAGER); - // Record that the sign in process starts (its end is recorded automatically // by the instance of DiceTurnSyncOnHelper constructed later on). signin_metrics::RecordSigninUserActionForAccessPoint(
diff --git a/chrome/browser/ui/views/reader_mode/reader_mode_icon_view.cc b/chrome/browser/ui/views/reader_mode/reader_mode_icon_view.cc index 01fb8b9..5c4d8ce 100644 --- a/chrome/browser/ui/views/reader_mode/reader_mode_icon_view.cc +++ b/chrome/browser/ui/views/reader_mode/reader_mode_icon_view.cc
@@ -126,12 +126,12 @@ } const gfx::VectorIcon& ReaderModeIconView::GetVectorIcon() const { - return active() ? kReaderModeIcon : kReaderModeDisabledIcon; + return GetActive() ? kReaderModeIcon : kReaderModeDisabledIcon; } base::string16 ReaderModeIconView::GetTextForTooltipAndAccessibleName() const { - return l10n_util::GetStringUTF16(active() ? IDS_EXIT_DISTILLED_PAGE - : IDS_DISTILL_PAGE); + return l10n_util::GetStringUTF16(GetActive() ? IDS_EXIT_DISTILLED_PAGE + : IDS_DISTILL_PAGE); } const char* ReaderModeIconView::GetClassName() const { @@ -146,7 +146,7 @@ void ReaderModeIconView::OnExecuting( PageActionIconView::ExecuteSource execute_source) { - if (active()) { + if (GetActive()) { dom_distiller::UMAHelper::RecordReaderModeExit( dom_distiller::UMAHelper::ReaderModeEntryPoint::kOmniboxIcon); } else {
diff --git a/chrome/browser/ui/views/sad_tab_view_interactive_uitest.cc b/chrome/browser/ui/views/sad_tab_view_interactive_uitest.cc index ddef173..903cb26 100644 --- a/chrome/browser/ui/views/sad_tab_view_interactive_uitest.cc +++ b/chrome/browser/ui/views/sad_tab_view_interactive_uitest.cc
@@ -98,7 +98,10 @@ } bool IsFocusedViewInsideBrowserToolbar() { - return IsFocusedViewInsideViewClass(ToolbarView::kViewClassName); + return IsFocusedViewInsideViewClass( + BrowserView::GetBrowserViewForBrowser(browser()) + ->toolbar() + ->GetClassName()); } bool IsFocusedViewOnActionButtonInSadTab() {
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc index 7c623cc..6105ff8 100644 --- a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc +++ b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
@@ -951,8 +951,15 @@ // tabs joining the same group as the tab in the second position. Then dragging // the tabs over two to the right will result in the tabs joining the same group // as the last tab. +// Flaky on windows. http://crbug.com/1164561 +#if defined(OS_WIN) +#define MAYBE_DragMultipleTabsRightIntoGroup \ + DISABLED_DragMultipleTabsRightIntoGroup +#else +#define MAYBE_DragMultipleTabsRightIntoGroup DragMultipleTabsRightIntoGroup +#endif IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest, - DragMultipleTabsRightIntoGroup) { + MAYBE_DragMultipleTabsRightIntoGroup) { TabStrip* tab_strip = GetTabStripForBrowser(browser()); TabStripModel* model = browser()->tab_strip_model(); TabGroupModel* group_model = model->group_model(); @@ -2052,7 +2059,8 @@ } // namespace -#if defined(OS_MAC) /* && defined(ARCH_CPU_ARM64) */ +// Flaky. http://crbug.com/1128774 +#if defined(OS_MAC) || defined(OS_WIN) // Bulk-disabled for arm64 bot stabilization: https://crbug.com/1154345 // These were flaking on all macs, so commented out ARCH_ above for // crbug.com/1160917 too.
diff --git a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc index 5f68959..312b2f9a 100644 --- a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc +++ b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc
@@ -396,12 +396,11 @@ // Maintains a set of thumbnails to watch, ensuring the capture count on the // associated WebContents stays nonzero until a valid thumbnail has been // captured. -class TabHoverCardBubbleView::ThumbnailObserver - : public ThumbnailImage::Observer { +class TabHoverCardBubbleView::ThumbnailObserver { public: explicit ThumbnailObserver(TabHoverCardBubbleView* hover_card) : hover_card_(hover_card) {} - ~ThumbnailObserver() override = default; + ~ThumbnailObserver() = default; // Begin watching the specified thumbnail image for updates. Ideally, should // trigger the associated WebContents to load (if not loaded already) and @@ -411,13 +410,17 @@ if (current_image_ == thumbnail_image) return; - scoped_observation_.Reset(); + subscription_.reset(); current_image_ = std::move(thumbnail_image); + if (!current_image_) + return; - if (current_image_) { - scoped_observation_.Observe(current_image_.get()); - current_image_->RequestThumbnailImage(); - } + subscription_ = current_image_->Subscribe(); + subscription_->SetSizeHint(TabStyle::GetPreviewImageSize()); + subscription_->SetUncompressedImageCallback(base::BindRepeating( + &ThumbnailObserver::ThumbnailImageCallback, base::Unretained(this))); + + current_image_->RequestThumbnailImage(); } // Returns the current (most recent) thumbnail being watched. @@ -425,18 +428,13 @@ return current_image_; } - base::Optional<gfx::Size> GetThumbnailSizeHint() const override { - return TabStyle::GetPreviewImageSize(); - } - - void OnThumbnailImageAvailable(gfx::ImageSkia preview_image) override { + void ThumbnailImageCallback(gfx::ImageSkia preview_image) { hover_card_->OnThumbnailImageAvailable(std::move(preview_image)); } scoped_refptr<ThumbnailImage> current_image_; + std::unique_ptr<ThumbnailImage::Subscription> subscription_; TabHoverCardBubbleView* const hover_card_; - base::ScopedObservation<ThumbnailImage, ThumbnailImage::Observer> - scoped_observation_{this}; }; TabHoverCardBubbleView::TabHoverCardBubbleView(Tab* tab)
diff --git a/chrome/browser/ui/views/toolbar/browser_app_menu_button.cc b/chrome/browser/ui/views/toolbar/browser_app_menu_button.cc index 711a9e1..07cad2c9 100644 --- a/chrome/browser/ui/views/toolbar/browser_app_menu_button.cc +++ b/chrome/browser/ui/views/toolbar/browser_app_menu_button.cc
@@ -41,6 +41,7 @@ #include "ui/views/animation/ink_drop_highlight.h" #include "ui/views/animation/ink_drop_state.h" #include "ui/views/controls/button/label_button_border.h" +#include "ui/views/metadata/metadata_impl_macros.h" #include "ui/views/metrics.h" #include "ui/views/view.h" #include "ui/views/view_class_properties.h" @@ -172,10 +173,6 @@ SetHighlight(text, color); } -const char* BrowserAppMenuButton::GetClassName() const { - return "BrowserAppMenuButton"; -} - bool BrowserAppMenuButton::GetDropFormats( int* formats, std::set<ui::ClipboardFormatType>* format_types) { @@ -231,3 +228,6 @@ UpdateColorsAndInsets(); PreferredSizeChanged(); } + +BEGIN_METADATA(BrowserAppMenuButton, AppMenuButton) +END_METADATA
diff --git a/chrome/browser/ui/views/toolbar/browser_app_menu_button.h b/chrome/browser/ui/views/toolbar/browser_app_menu_button.h index 7dcc240..32add0f9 100644 --- a/chrome/browser/ui/views/toolbar/browser_app_menu_button.h +++ b/chrome/browser/ui/views/toolbar/browser_app_menu_button.h
@@ -14,6 +14,7 @@ #include "chrome/browser/ui/toolbar/app_menu_icon_controller.h" #include "chrome/browser/ui/user_education/feature_promo_controller.h" #include "chrome/browser/ui/views/frame/app_menu_button.h" +#include "ui/views/metadata/metadata_header_macros.h" #include "ui/views/view.h" class ToolbarView; @@ -23,6 +24,7 @@ // windows, which is implemented in WebAppMenuButton). class BrowserAppMenuButton : public AppMenuButton { public: + METADATA_HEADER(BrowserAppMenuButton); BrowserAppMenuButton(PressedCallback callback, ToolbarView* toolbar_view); BrowserAppMenuButton(const BrowserAppMenuButton&) = delete; BrowserAppMenuButton& operator=(const BrowserAppMenuButton&) = delete; @@ -31,10 +33,6 @@ void SetTypeAndSeverity( AppMenuIconController::TypeAndSeverity type_and_severity); - AppMenuIconController::Severity severity() { - return type_and_severity_.severity; - } - // Shows the app menu. |run_types| denotes the MenuRunner::RunTypes associated // with the menu. void ShowMenu(int run_types); @@ -44,7 +42,6 @@ static bool g_open_app_immediately_for_testing; // AppMenuButton: - const char* GetClassName() const override; bool GetDropFormats(int* formats, std::set<ui::ClipboardFormatType>* format_types) override; bool AreDropTypesRequired() override;
diff --git a/chrome/browser/ui/views/toolbar/chrome_labs_bubble_view.cc b/chrome/browser/ui/views/toolbar/chrome_labs_bubble_view.cc index b3d6561..28ab871 100644 --- a/chrome/browser/ui/views/toolbar/chrome_labs_bubble_view.cc +++ b/chrome/browser/ui/views/toolbar/chrome_labs_bubble_view.cc
@@ -10,9 +10,11 @@ #include "chrome/browser/flag_descriptions.h" #include "chrome/browser/lifetime/application_lifetime.h" #include "chrome/browser/ui/webui/flags/flags_ui.h" +#include "chrome/common/channel_info.h" #include "chrome/grit/generated_resources.h" #include "chrome/grit/google_chrome_strings.h" #include "components/flags_ui/pref_service_flags_storage.h" +#include "components/version_info/channel.h" #include "ui/base/l10n/l10n_util.h" #include "ui/gfx/color_palette.h" #include "ui/views/background.h" @@ -179,7 +181,8 @@ for (const auto& lab : all_labs) { const flags_ui::FeatureEntry* entry = flags_state_->FindFeatureEntryByName(lab.internal_name); - if (IsFeatureSupportedOnPlatform(entry)) { + if (IsFeatureSupportedOnChannel(lab) && + IsFeatureSupportedOnPlatform(entry)) { DCHECK_EQ(entry->type, flags_ui::FeatureEntry::FEATURE_VALUE); int default_index = GetIndexOfEnabledLabState(entry); menu_item_container_->AddChildView( @@ -235,6 +238,10 @@ return 0; } +bool ChromeLabsBubbleView::IsFeatureSupportedOnChannel(const LabInfo& lab) { + return chrome::GetChannel() <= lab.allowed_channel; +} + // TODO(elainechien): ChromeOS specific logic for owner access only flags. bool ChromeLabsBubbleView::IsFeatureSupportedOnPlatform( const flags_ui::FeatureEntry* entry) {
diff --git a/chrome/browser/ui/views/toolbar/chrome_labs_bubble_view.h b/chrome/browser/ui/views/toolbar/chrome_labs_bubble_view.h index eb37d5b..eca81ab 100644 --- a/chrome/browser/ui/views/toolbar/chrome_labs_bubble_view.h +++ b/chrome/browser/ui/views/toolbar/chrome_labs_bubble_view.h
@@ -43,6 +43,8 @@ int GetIndexOfEnabledLabState(const flags_ui::FeatureEntry* entry); + bool IsFeatureSupportedOnChannel(const LabInfo& lab); + bool IsFeatureSupportedOnPlatform(const flags_ui::FeatureEntry* entry); void ShowRelaunchPrompt();
diff --git a/chrome/browser/ui/views/toolbar/chrome_labs_bubble_view_model.cc b/chrome/browser/ui/views/toolbar/chrome_labs_bubble_view_model.cc index 163c4d6..b760a002 100644 --- a/chrome/browser/ui/views/toolbar/chrome_labs_bubble_view_model.cc +++ b/chrome/browser/ui/views/toolbar/chrome_labs_bubble_view_model.cc
@@ -6,6 +6,19 @@ #include "base/strings/utf_string_conversions.h" #include "chrome/browser/flag_descriptions.h" +LabInfo::LabInfo(const std::string& internal_name, + const base::string16& visible_name, + const base::string16& visible_description, + version_info::Channel allowed_channel) + : internal_name(internal_name), + visible_name(visible_name), + visible_description(visible_description), + allowed_channel(allowed_channel) {} + +LabInfo::LabInfo(const LabInfo& other) = default; + +LabInfo::~LabInfo() = default; + ChromeLabsBubbleViewModel::ChromeLabsBubbleViewModel() { SetUpLabs(); } @@ -25,16 +38,18 @@ // Read Later. lab_info_.emplace_back(LabInfo( flag_descriptions::kReadLaterFlagId, base::ASCIIToUTF16("Reading List"), - base::ASCIIToUTF16( - "Right click on a tab or click the star to add tabs to a reading " - "list. Access from the Bookmarks bar."))); + base::ASCIIToUTF16("Right click on a tab or click the Bookmark icon to " + "add tabs to a reading " + "list. Access from the Bookmarks bar."), + version_info::Channel::BETA)); // Tab Search. lab_info_.emplace_back( LabInfo(flag_descriptions::kEnableTabSearchFlagId, base::ASCIIToUTF16("Tab Search"), base::ASCIIToUTF16("Enable a popup bubble in Top Chrome UI to " - "search over currently open tabs."))); + "search over currently open tabs."), + version_info::Channel::BETA)); } void ChromeLabsBubbleViewModel::SetLabInfoForTesting(
diff --git a/chrome/browser/ui/views/toolbar/chrome_labs_bubble_view_model.h b/chrome/browser/ui/views/toolbar/chrome_labs_bubble_view_model.h index 62056cdc..fa5f953 100644 --- a/chrome/browser/ui/views/toolbar/chrome_labs_bubble_view_model.h +++ b/chrome/browser/ui/views/toolbar/chrome_labs_bubble_view_model.h
@@ -7,21 +7,26 @@ #include <vector> #include "base/strings/string16.h" +#include "components/version_info/channel.h" // Currently there are differences in both visible name and visible description // between about_flags and what we want for Chrome Labs. We are coordinating to -// match these. LabInfo struct can be removed after that. +// match these. Visible name and visible description can be removed from this +// struct after that. struct LabInfo { LabInfo(const std::string& internal_name, const base::string16& visible_name, - const base::string16& visible_description) - : internal_name(internal_name), - visible_name(visible_name), - visible_description(visible_description) {} - + const base::string16& visible_description, + version_info::Channel allowed_channel); + LabInfo(const LabInfo& other); + ~LabInfo(); std::string internal_name; base::string16 visible_name; base::string16 visible_description; + // Channels that are less stable than allowed_channel will also be + // considered allowed. ex) if BETA is specified, this feature will also be + // shown on CANARY and DEV. + version_info::Channel allowed_channel; }; class ChromeLabsBubbleViewModel {
diff --git a/chrome/browser/ui/views/toolbar/chrome_labs_bubble_view_unittest.cc b/chrome/browser/ui/views/toolbar/chrome_labs_bubble_view_unittest.cc index 99a9c30c..02d8a152 100644 --- a/chrome/browser/ui/views/toolbar/chrome_labs_bubble_view_unittest.cc +++ b/chrome/browser/ui/views/toolbar/chrome_labs_bubble_view_unittest.cc
@@ -13,6 +13,7 @@ #include "chrome/browser/ui/views/toolbar/toolbar_view.h" #include "components/flags_ui/feature_entry_macros.h" #include "components/flags_ui/flags_state.h" +#include "components/version_info/channel.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/views/test/combobox_test_api.h" #include "ui/views/test/widget_test.h" @@ -67,14 +68,17 @@ } void CreateTestLabInfo() { - test_feature_info_.emplace_back(LabInfo( - kFirstTestFeatureId, base::ASCIIToUTF16(""), base::ASCIIToUTF16(""))); + test_feature_info_.emplace_back( + LabInfo(kFirstTestFeatureId, base::ASCIIToUTF16(""), + base::ASCIIToUTF16(""), version_info::Channel::UNKNOWN)); - test_feature_info_.emplace_back(LabInfo( - kSecondTestFeatureId, base::ASCIIToUTF16(""), base::ASCIIToUTF16(""))); + test_feature_info_.emplace_back( + LabInfo(kSecondTestFeatureId, base::ASCIIToUTF16(""), + base::ASCIIToUTF16(""), version_info::Channel::UNKNOWN)); - test_feature_info_.emplace_back(LabInfo( - kThirdTestFeatureId, base::ASCIIToUTF16(""), base::ASCIIToUTF16(""))); + test_feature_info_.emplace_back( + LabInfo(kThirdTestFeatureId, base::ASCIIToUTF16(""), + base::ASCIIToUTF16(""), version_info::Channel::UNKNOWN)); } const std::vector<LabInfo>& GetTestLabInfo() { return test_feature_info_; }
diff --git a/chrome/browser/ui/views/toolbar/toolbar_account_icon_container_view.cc b/chrome/browser/ui/views/toolbar/toolbar_account_icon_container_view.cc index 6f07672..a1e9dec 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_account_icon_container_view.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_account_icon_container_view.cc
@@ -21,14 +21,10 @@ #include "ui/gfx/color_palette.h" #include "ui/views/bubble/bubble_dialog_delegate_view.h" #include "ui/views/layout/flex_layout_types.h" +#include "ui/views/metadata/metadata_impl_macros.h" #include "ui/views/view_class_properties.h" #include "ui/views/widget/widget.h" -// static -const char ToolbarAccountIconContainerView:: - kToolbarAccountIconContainerViewClassName[] = - "ToolbarAccountIconContainerView"; - ToolbarAccountIconContainerView::ToolbarAccountIconContainerView( Browser* browser) : ToolbarIconContainerView( @@ -107,12 +103,11 @@ UpdateAllIcons(); } -const char* ToolbarAccountIconContainerView::GetClassName() const { - return kToolbarAccountIconContainerViewClassName; -} - void ToolbarAccountIconContainerView::AddPageActionIcon(views::View* icon) { // Add the page action icons to the end of the container, just before the // avatar icon. AddChildViewAt(icon, GetIndexOf(avatar_)); } + +BEGIN_METADATA(ToolbarAccountIconContainerView, ToolbarIconContainerView) +END_METADATA
diff --git a/chrome/browser/ui/views/toolbar/toolbar_account_icon_container_view.h b/chrome/browser/ui/views/toolbar/toolbar_account_icon_container_view.h index 711c693a..3462707 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_account_icon_container_view.h +++ b/chrome/browser/ui/views/toolbar/toolbar_account_icon_container_view.h
@@ -9,6 +9,7 @@ #include "chrome/browser/ui/views/page_action/page_action_icon_container.h" #include "chrome/browser/ui/views/page_action/page_action_icon_view.h" #include "chrome/browser/ui/views/toolbar/toolbar_icon_container_view.h" +#include "ui/views/metadata/metadata_header_macros.h" class AvatarToolbarButton; class Browser; @@ -21,6 +22,7 @@ public PageActionIconContainer, public PageActionIconView::Delegate { public: + METADATA_HEADER(ToolbarAccountIconContainerView); explicit ToolbarAccountIconContainerView(Browser* browser); ToolbarAccountIconContainerView(const ToolbarAccountIconContainerView&) = delete; @@ -44,15 +46,12 @@ // views::View: void OnThemeChanged() override; - const char* GetClassName() const override; PageActionIconController* page_action_icon_controller() { return page_action_icon_controller_.get(); } AvatarToolbarButton* avatar_button() { return avatar_; } - static const char kToolbarAccountIconContainerViewClassName[]; - private: // PageActionIconContainer: void AddPageActionIcon(views::View* icon) override;
diff --git a/chrome/browser/ui/views/toolbar/toolbar_action_view.cc b/chrome/browser/ui/views/toolbar/toolbar_action_view.cc index f2aa855..2fe7667d 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_action_view.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_action_view.cc
@@ -37,6 +37,7 @@ #include "ui/views/controls/menu/menu_controller.h" #include "ui/views/controls/menu/menu_model_adapter.h" #include "ui/views/controls/menu/menu_runner.h" +#include "ui/views/metadata/metadata_impl_macros.h" #include "ui/views/mouse_constants.h" using views::LabelButtonBorder; @@ -51,8 +52,6 @@ //////////////////////////////////////////////////////////////////////////////// // ToolbarActionView -const char ToolbarActionView::kClassName[] = "ToolbarActionView"; - ToolbarActionView::ToolbarActionView( ToolbarActionViewController* view_controller, ToolbarActionView::Delegate* delegate) @@ -89,10 +88,6 @@ view_controller_->SetDelegate(nullptr); } -const char* ToolbarActionView::GetClassName() const { - return kClassName; -} - gfx::Rect ToolbarActionView::GetAnchorBoundsInScreen() const { gfx::Rect bounds = GetBoundsInScreen(); bounds.Inset(GetToolbarInkDropInsets(this)); @@ -320,3 +315,6 @@ ui::MENU_SOURCE_NONE); } } + +BEGIN_METADATA(ToolbarActionView, views::MenuButton) +END_METADATA
diff --git a/chrome/browser/ui/views/toolbar/toolbar_action_view.h b/chrome/browser/ui/views/toolbar/toolbar_action_view.h index 20430c2..ebfacfa 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_action_view.h +++ b/chrome/browser/ui/views/toolbar/toolbar_action_view.h
@@ -12,6 +12,7 @@ #include "ui/views/controls/button/menu_button_controller.h" #include "ui/views/controls/menu/menu_model_adapter.h" #include "ui/views/drag_controller.h" +#include "ui/views/metadata/metadata_header_macros.h" #include "ui/views/view.h" class ExtensionContextMenuController; @@ -23,6 +24,8 @@ class ToolbarActionView : public views::MenuButton, public ToolbarActionViewDelegateViews { public: + METADATA_HEADER(ToolbarActionView); + // Need DragController here because ToolbarActionView could be // dragged/dropped. class Delegate : public views::DragController { @@ -83,11 +86,9 @@ ExtensionContextMenuController* context_menu_controller_for_testing() const { return context_menu_controller_.get(); } - static const char kClassName[]; private: // views::MenuButton: - const char* GetClassName() const override; gfx::Size CalculatePreferredSize() const override; bool OnMousePressed(const ui::MouseEvent& event) override; void OnMouseReleased(const ui::MouseEvent& event) override;
diff --git a/chrome/browser/ui/views/toolbar/toolbar_icon_container_view.cc b/chrome/browser/ui/views/toolbar/toolbar_icon_container_view.cc index 526f635c..3f4b12c 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_icon_container_view.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_icon_container_view.cc
@@ -20,13 +20,10 @@ #include "ui/views/background.h" #include "ui/views/layout/animating_layout_manager.h" #include "ui/views/layout/flex_layout.h" +#include "ui/views/metadata/metadata_impl_macros.h" #include "ui/views/view_class_properties.h" #include "ui/views/view_observer.h" -// static -const char ToolbarIconContainerView::kToolbarIconContainerViewClassName[] = - "ToolbarIconContainerView"; - ToolbarIconContainerView::RoundRectBorder::RoundRectBorder(views::View* parent) : parent_(parent) { layer_.set_delegate(this); @@ -92,8 +89,10 @@ const bool is_collapsed = observed_view->bounds().IsEmpty(); if (is_collapsed != was_collapsed_) { was_collapsed_ = is_collapsed; - if (!is_collapsed) - toolbar_icon_container_view_->animating_layout_manager()->ResetLayout(); + if (!is_collapsed) { + toolbar_icon_container_view_->GetAnimatingLayoutManager() + ->ResetLayout(); + } } } @@ -159,20 +158,45 @@ observers_.RemoveObserver(obs); } -void ToolbarIconContainerView::OverrideIconColor(SkColor color) { +void ToolbarIconContainerView::SetIconColor(SkColor color) { + if (icon_color_ == color) + return; icon_color_ = color; UpdateAllIcons(); + OnPropertyChanged(&icon_color_, views::kPropertyEffectsNone); } SkColor ToolbarIconContainerView::GetIconColor() const { - if (icon_color_) - return icon_color_.value(); - return GetThemeProvider()->GetColor( - ThemeProperties::COLOR_TOOLBAR_BUTTON_ICON); + return icon_color_.value_or( + GetThemeProvider()->GetColor(ThemeProperties::COLOR_TOOLBAR_BUTTON_ICON)); } -bool ToolbarIconContainerView::IsHighlighted() { - return ShouldDisplayHighlight(); +bool ToolbarIconContainerView::GetHighlighted() const { + if (!uses_highlight_) + return false; + + if (IsMouseHovered() && (!main_button_ || !main_button_->IsMouseHovered())) + return true; + + // Focused, pressed or hovered children should trigger the highlight. + for (const views::View* child : children()) { + if (child == main_button_) + continue; + if (child->HasFocus()) + return true; + const views::Button* button = views::Button::AsButton(child); + if (!button) + continue; + if (button->GetState() == views::Button::ButtonState::STATE_PRESSED || + button->GetState() == views::Button::ButtonState::STATE_HOVERED) { + return true; + } + // The container should also be highlighted if a dialog is anchored to. + if (base::Contains(highlighted_buttons_, button)) + return true; + } + + return false; } void ToolbarIconContainerView::OnViewFocused(views::View* observed_view) { @@ -183,6 +207,21 @@ UpdateHighlight(); } +views::AnimatingLayoutManager* +ToolbarIconContainerView::GetAnimatingLayoutManager() { + return static_cast<views::AnimatingLayoutManager*>(GetLayoutManager()); +} + +const views::AnimatingLayoutManager* +ToolbarIconContainerView::GetAnimatingLayoutManager() const { + return static_cast<const views::AnimatingLayoutManager*>(GetLayoutManager()); +} + +views::FlexLayout* ToolbarIconContainerView::GetTargetLayoutManager() { + return static_cast<views::FlexLayout*>( + GetAnimatingLayoutManager()->target_layout_manager()); +} + void ToolbarIconContainerView::OnBoundsChanged( const gfx::Rect& previous_bounds) { const gfx::Rect bounds = ConvertRectToWidget(GetLocalBounds()); @@ -198,50 +237,18 @@ UpdateHighlight(); } -const char* ToolbarIconContainerView::GetClassName() const { - return kToolbarIconContainerViewClassName; -} - void ToolbarIconContainerView::AddedToWidget() { // Add an observer to reset the animation if the browser window is restored, // preventing spurious animation. (See crbug.com/1106506) restore_observer_ = std::make_unique<WidgetRestoreObserver>(this); } -bool ToolbarIconContainerView::ShouldDisplayHighlight() { - if (!uses_highlight_) - return false; - - if (IsMouseHovered() && (!main_button_ || !main_button_->IsMouseHovered())) - return true; - - // Focused, pressed or hovered children should trigger the highlight. - for (views::View* child : children()) { - if (child == main_button_) - continue; - if (child->HasFocus()) - return true; - views::Button* button = views::Button::AsButton(child); - if (!button) - continue; - if (button->GetState() == views::Button::ButtonState::STATE_PRESSED || - button->GetState() == views::Button::ButtonState::STATE_HOVERED) { - return true; - } - // The container should also be highlighted if a dialog is anchored to. - if (base::Contains(highlighted_buttons_, button)) - return true; - } - - return false; -} - void ToolbarIconContainerView::UpdateHighlight() { bool showing_before = border_.layer()->GetTargetOpacity() == 1; { ui::ScopedLayerAnimationSettings settings(border_.layer()->GetAnimator()); - border_.layer()->SetOpacity(ShouldDisplayHighlight() ? 1 : 0); + border_.layer()->SetOpacity(GetHighlighted() ? 1 : 0); } if (showing_before == (border_.layer()->GetTargetOpacity() == 1)) @@ -259,3 +266,8 @@ UpdateHighlight(); } + +BEGIN_METADATA(ToolbarIconContainerView, views::View) +ADD_PROPERTY_METADATA(SkColor, IconColor) +ADD_READONLY_PROPERTY_METADATA(bool, Highlighted) +END_METADATA
diff --git a/chrome/browser/ui/views/toolbar/toolbar_icon_container_view.h b/chrome/browser/ui/views/toolbar/toolbar_icon_container_view.h index 6ef2ccfd..1c7a561 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_icon_container_view.h +++ b/chrome/browser/ui/views/toolbar/toolbar_icon_container_view.h
@@ -12,12 +12,15 @@ #include "ui/views/controls/button/button.h" #include "ui/views/layout/animating_layout_manager.h" #include "ui/views/layout/flex_layout.h" +#include "ui/views/metadata/metadata_header_macros.h" #include "ui/views/view.h" // A general view container for any type of toolbar icons. class ToolbarIconContainerView : public views::View, public views::ViewObserver { public: + METADATA_HEADER(ToolbarIconContainerView); + class Observer : public base::CheckedObserver { public: virtual void OnHighlightChanged() = 0; @@ -41,34 +44,23 @@ void AddObserver(Observer* obs); void RemoveObserver(const Observer* obs); - void OverrideIconColor(SkColor icon_color); + void SetIconColor(SkColor icon_color); SkColor GetIconColor() const; - bool IsHighlighted(); + bool GetHighlighted() const; // views::ViewObserver: void OnViewFocused(views::View* observed_view) override; void OnViewBlurred(views::View* observed_view) override; - bool uses_highlight() { return uses_highlight_; } + bool uses_highlight() const { return uses_highlight_; } // Provides access to the animating layout manager for subclasses. - views::AnimatingLayoutManager* animating_layout_manager() { - return static_cast<views::AnimatingLayoutManager*>(GetLayoutManager()); - } - - const views::AnimatingLayoutManager* animating_layout_manager() const { - return static_cast<const views::AnimatingLayoutManager*>( - GetLayoutManager()); - } + views::AnimatingLayoutManager* GetAnimatingLayoutManager(); + const views::AnimatingLayoutManager* GetAnimatingLayoutManager() const; // Provides access to the flex layout in the animating layout manager. - views::FlexLayout* target_layout_manager() { - return static_cast<views::FlexLayout*>( - animating_layout_manager()->target_layout_manager()); - } - - static const char kToolbarIconContainerViewClassName[]; + views::FlexLayout* GetTargetLayoutManager(); protected: void OnBoundsChanged(const gfx::Rect& previous_bounds) override; @@ -100,10 +92,8 @@ // views::View: void OnMouseEntered(const ui::MouseEvent& event) override; void OnMouseExited(const ui::MouseEvent& event) override; - const char* GetClassName() const override; void AddedToWidget() override; - bool ShouldDisplayHighlight(); void UpdateHighlight(); // Called by |button| when its ink drop highlighted state changes. @@ -123,7 +113,7 @@ // Points to the child buttons that we know are currently highlighted. // TODO(pbos): Consider observing buttons leaving our hierarchy and removing // them from this set. - std::set<views::Button*> highlighted_buttons_; + std::set<const views::Button*> highlighted_buttons_; RoundRectBorder border_{this};
diff --git a/chrome/browser/ui/views/toolbar/toolbar_view.cc b/chrome/browser/ui/views/toolbar/toolbar_view.cc index 14858fc..a26a057 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_view.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_view.cc
@@ -83,6 +83,7 @@ #include "ui/native_theme/native_theme_aura.h" #include "ui/views/layout/fill_layout.h" #include "ui/views/layout/flex_layout.h" +#include "ui/views/metadata/metadata_impl_macros.h" #include "ui/views/view_class_properties.h" #include "ui/views/widget/tooltip_manager.h" #include "ui/views/widget/widget.h" @@ -143,9 +144,6 @@ } // namespace -// static -const char ToolbarView::kViewClassName[] = "ToolbarView"; - //////////////////////////////////////////////////////////////////////////////// // ToolbarView, public: @@ -413,7 +411,7 @@ SetPaneFocus(app_menu_button_); } -bool ToolbarView::IsAppMenuFocused() { +bool ToolbarView::GetAppMenuFocused() const { return app_menu_button_ && app_menu_button_->HasFocus(); } @@ -635,10 +633,6 @@ SchedulePaint(); } -const char* ToolbarView::GetClassName() const { - return kViewClassName; -} - bool ToolbarView::AcceleratorPressed(const ui::Accelerator& accelerator) { const views::View* focused_view = focus_manager()->GetFocusedView(); if (focused_view && (focused_view->GetID() == VIEW_ID_OMNIBOX)) @@ -704,7 +698,7 @@ } else if (extensions_container_) { const views::FlexSpecification extensions_flex_rule = views::FlexSpecification( - extensions_container_->animating_layout_manager() + extensions_container_->GetAnimatingLayoutManager() ->GetDefaultFlexRule()) .WithOrder(kExtensionsFlexOrder); @@ -950,3 +944,7 @@ ? views::MenuRunner::SHOULD_SHOW_MNEMONICS : views::MenuRunner::NO_FLAGS); } + +BEGIN_METADATA(ToolbarView, views::AccessiblePaneView) +ADD_READONLY_PROPERTY_METADATA(bool, AppMenuFocused) +END_METADATA
diff --git a/chrome/browser/ui/views/toolbar/toolbar_view.h b/chrome/browser/ui/views/toolbar/toolbar_view.h index 009d66a..b49d005 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_view.h +++ b/chrome/browser/ui/views/toolbar/toolbar_view.h
@@ -8,7 +8,6 @@ #include <memory> #include <vector> -#include "base/macros.h" #include "base/observer_list.h" #include "base/optional.h" #include "base/scoped_observation.h" @@ -31,6 +30,7 @@ #include "ui/views/accessible_pane_view.h" #include "ui/views/animation/animation_delegate_views.h" #include "ui/views/controls/button/menu_button.h" +#include "ui/views/metadata/metadata_header_macros.h" #include "ui/views/view.h" #include "url/origin.h" @@ -77,6 +77,8 @@ public ToolbarButtonProvider, public BrowserRootView::DropTarget { public: + METADATA_HEADER(ToolbarView); + // Types of display mode this toolbar can have. enum class DisplayMode { NORMAL, // Normal toolbar with buttons, etc. @@ -86,10 +88,9 @@ // needs to be displayed. }; - // The view class name. - static const char kViewClassName[]; - - explicit ToolbarView(Browser* browser, BrowserView* browser_view); + ToolbarView(Browser* browser, BrowserView* browser_view); + ToolbarView(const ToolbarView&) = delete; + ToolbarView& operator=(const ToolbarView&) = delete; ~ToolbarView() override; // Create the contents of the Browser Toolbar. @@ -118,7 +119,7 @@ void SetPaneFocusAndFocusAppMenu(); // Returns true if the app menu is focused. - bool IsAppMenuFocused(); + bool GetAppMenuFocused() const; void ShowIntentPickerBubble( std::vector<IntentPickerBubbleView::AppInfo> app_info, @@ -188,7 +189,6 @@ gfx::Size GetMinimumSize() const override; void Layout() override; void OnThemeChanged() override; - const char* GetClassName() const override; bool AcceleratorPressed(const ui::Accelerator& acc) override; void ChildPreferredSizeChanged(views::View* child) override; @@ -297,8 +297,6 @@ // Whether this toolbar has been initialized. bool initialized_ = false; - - DISALLOW_IMPLICIT_CONSTRUCTORS(ToolbarView); }; #endif // CHROME_BROWSER_UI_VIEWS_TOOLBAR_TOOLBAR_VIEW_H_
diff --git a/chrome/browser/ui/views/user_education/feature_promo_bubble_view.cc b/chrome/browser/ui/views/user_education/feature_promo_bubble_view.cc index e5e2b0d..8c8c41e 100644 --- a/chrome/browser/ui/views/user_education/feature_promo_bubble_view.cc +++ b/chrome/browser/ui/views/user_education/feature_promo_bubble_view.cc
@@ -316,17 +316,6 @@ feature_promo_bubble_timeout_->OnMouseExited(); } -gfx::Rect FeaturePromoBubbleView::GetBubbleBounds() { - gfx::Rect bounds = BubbleDialogDelegateView::GetBubbleBounds(); - if (!focusable_) { - if (base::i18n::IsRTL()) - bounds.Offset(5, 0); - else - bounds.Offset(-5, 0); - } - return bounds; -} - ax::mojom::Role FeaturePromoBubbleView::GetAccessibleWindowRole() { // Since we don't have any controls for the user to interact with (we're just // an information bubble), override our role to kAlert.
diff --git a/chrome/browser/ui/views/user_education/feature_promo_bubble_view.h b/chrome/browser/ui/views/user_education/feature_promo_bubble_view.h index d16bc36..2004555 100644 --- a/chrome/browser/ui/views/user_education/feature_promo_bubble_view.h +++ b/chrome/browser/ui/views/user_education/feature_promo_bubble_view.h
@@ -15,9 +15,6 @@ #include "ui/gfx/geometry/rect.h" #include "ui/views/bubble/bubble_dialog_delegate_view.h" -namespace gfx { -class Rect; -} namespace ui { class MouseEvent; @@ -89,7 +86,6 @@ bool OnMousePressed(const ui::MouseEvent& event) override; void OnMouseEntered(const ui::MouseEvent& event) override; void OnMouseExited(const ui::MouseEvent& event) override; - gfx::Rect GetBubbleBounds() override; ax::mojom::Role GetAccessibleWindowRole() override; base::string16 GetAccessibleWindowTitle() const override; void UpdateHighlightedButton(bool highlighted) override {
diff --git a/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_toolbar_button_container.cc b/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_toolbar_button_container.cc index 8dcbd3c..bd2d2c7 100644 --- a/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_toolbar_button_container.cc +++ b/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_toolbar_button_container.cc
@@ -119,7 +119,7 @@ extensions_container_->SetProperty( views::kFlexBehaviorKey, views::FlexSpecification( - extensions_container_->animating_layout_manager() + extensions_container_->GetAnimatingLayoutManager() ->GetDefaultFlexRule()) .WithOrder(kLowPriorityFlexOrder)); views::SetHitTestComponent(extensions_container_, @@ -178,7 +178,7 @@ if (content_settings_container_) content_settings_container_->SetIconColor(foreground_color_); if (extensions_container_) - extensions_container_->OverrideIconColor(foreground_color_); + extensions_container_->SetIconColor(foreground_color_); page_action_icon_controller_->SetIconColor(foreground_color_); if (web_app_menu_button_) web_app_menu_button_->SetColor(foreground_color_);
diff --git a/chrome/browser/ui/views/web_apps/web_app_integration_browsertest.cc b/chrome/browser/ui/views/web_apps/web_app_integration_browsertest.cc index d0f93bd7..68d361a9 100644 --- a/chrome/browser/ui/views/web_apps/web_app_integration_browsertest.cc +++ b/chrome/browser/ui/views/web_apps/web_app_integration_browsertest.cc
@@ -24,13 +24,19 @@ #include "chrome/browser/web_applications/components/app_registry_controller.h" #include "chrome/browser/web_applications/components/install_finalizer.h" #include "chrome/browser/web_applications/components/os_integration_manager.h" +#include "chrome/browser/web_applications/components/policy/web_app_policy_constants.h" +#include "chrome/browser/web_applications/components/policy/web_app_policy_manager.h" +#include "chrome/browser/web_applications/components/web_app_constants.h" #include "chrome/browser/web_applications/components/web_app_id.h" #include "chrome/browser/web_applications/components/web_app_provider_base.h" #include "chrome/browser/web_applications/test/web_app_install_observer.h" #include "chrome/browser/web_applications/web_app_provider.h" +#include "chrome/browser/web_applications/web_app_registrar.h" #include "chrome/common/chrome_switches.h" +#include "chrome/common/pref_names.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" +#include "components/prefs/scoped_user_pref_update.h" #include "content/public/test/browser_test.h" #include "content/public/test/test_navigation_observer.h" #include "extensions/browser/extension_dialog_auto_confirm.h" @@ -214,27 +220,37 @@ action_strings, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); } + // Non-assert actions implemented before assert actions. Implemented in + // alphabetical order. void ExecuteAction(const std::string& action_string) { - if (base::StartsWith(action_string, "navigate_installable")) { - NavigateToSite(browser(), GetInstallableAppURL()); - } else if (action_string == "navigate_browser_in_scope") { - NavigateToSite(browser(), GetInScopeURL()); - } else if (action_string == "navigate_not_installable") { - NavigateToSite(browser(), GetOutOfScopeURL()); + if (action_string == "add_policy_app_internal_tabbed") { + AddPolicyAppInternalTabbed(); + } else if (action_string == "close_pwa") { + ClosePWA(); + } else if (action_string == "install_create_shortcut_tabbed") { + InstallCreateShortcutTabbed(); } else if (action_string == "install_omnibox_or_menu") { - ExecutePwaInstallIcon(); + InstallOmniboxOrMenu(); } else if (base::StartsWith(action_string, "launch_internal")) { LaunchInternal(); + } else if (action_string == "list_apps_internal") { + ListAppsInternal(); + } else if (action_string == "navigate_browser_in_scope") { + NavigateToSite(browser(), GetInScopeURL()); + } else if (base::StartsWith(action_string, "navigate_installable")) { + NavigateToSite(browser(), GetInstallableAppURL()); + } else if (action_string == "navigate_not_installable") { + NavigateToSite(browser(), GetNonInstallableAppURL()); + } else if (action_string == "remove_policy_app") { + RemovePolicyApp(); + } else if (action_string == "set_open_in_window_internal") { + SetOpenInWindowInternal(); } else if (action_string == "uninstall_from_menu") { UninstallFromMenu(); } else if (action_string == "uninstall_internal") { UninstallInternal(); - } else if (action_string == "install_create_shortcut_tabbed") { - InstallCreateShortcutTabbed(); - } else if (action_string == "set_open_in_window_internal") { - SetOpenInWindowInternal(); - } else if (action_string == "close_pwa") { - ClosePWA(); + } else if (action_string == "assert_app_not_in_list") { + AssertAppNotInList(); } else if (action_string == "assert_installable") { AssertInstallable(); } else if (action_string == "assert_install_icon_shown") { @@ -245,46 +261,60 @@ AssertLaunchIconShown(); } else if (action_string == "assert_launch_icon_not_shown") { AssertLaunchIconNotShown(); + } else if (action_string == "assert_no_crash") { } else if (action_string == "assert_window_created") { AssertWindowCreated(); - } else if (action_string == "assert_no_crash") { } else { FAIL() << "Unimplemented action: " << action_string; } } // Automated Testing Actions - NavigateToSiteResult NavigateToSite(Browser* browser, const GURL& url) { - content::WebContents* web_contents = GetCurrentTab(browser); - auto* app_banner_manager = - webapps::TestAppBannerManagerDesktop::FromWebContents(web_contents); - DCHECK(!app_banner_manager->WaitForInstallableCheck()); - - ui_test_utils::NavigateToURL(browser, url); - bool installable = app_banner_manager->WaitForInstallableCheck(); - - last_navigation_result_ = - NavigateToSiteResult{web_contents, app_banner_manager, installable}; - return last_navigation_result_; + void AddPolicyAppInternalTabbed() { + GURL url = GetInstallableAppURL(); + auto* web_app_registrar = WebAppProvider::Get(browser()->profile()) + ->registrar() + .AsWebAppRegistrar(); + base::RunLoop run_loop; + WebAppInstallObserver observer(browser()->profile()); + observer.SetWebAppInstalledDelegate( + base::BindLambdaForTesting([&](const AppId& app_id) { + bool is_installed = web_app_registrar->IsInstalled(app_id); + GURL installed_url = web_app_registrar->GetAppStartUrl(app_id); + if (is_installed && installed_url.is_valid() && + installed_url.spec() == url.spec()) { + app_id_ = app_id; + run_loop.Quit(); + } + })); + { + base::Value item(base::Value::Type::DICTIONARY); + item.SetKey(kUrlKey, base::Value(url.spec())); + item.SetKey(kDefaultLaunchContainerKey, + base::Value(kDefaultLaunchContainerTabValue)); + ListPrefUpdate update(browser()->profile()->GetPrefs(), + prefs::kWebAppInstallForceList); + update->Append(item.Clone()); + } + run_loop.Run(); } - GURL GetInstallableAppURL() { - return https_server_.GetURL("/banners/manifest_test_page.html"); + void ClosePWA() { + DCHECK(app_browser_); + app_browser_->window()->Close(); + ui_test_utils::WaitForBrowserToClose(app_browser_); } - GURL GetInScopeURL() { - return https_server_.GetURL("/banners/manifest_test_page.html"); + void InstallCreateShortcutTabbed() { + chrome::SetAutoAcceptWebAppDialogForTesting(/*auto_accept=*/true, + /*auto_open_in_window=*/false); + WebAppInstallObserver observer(browser()->profile()); + CHECK(chrome::ExecuteCommand(browser(), IDC_CREATE_SHORTCUT)); + app_id_ = observer.AwaitNextInstall(); + chrome::SetAutoAcceptWebAppDialogForTesting(false, false); } - GURL GetOutOfScopeURL() { - return https_server_.GetURL("/out_of_scope/index.html"); - } - - content::WebContents* GetCurrentTab(Browser* browser) { - return browser->tab_strip_model()->GetActiveWebContents(); - } - - web_app::AppId ExecutePwaInstallIcon() { + web_app::AppId InstallOmniboxOrMenu() { chrome::SetAutoAcceptPWAInstallConfirmationForTesting(true); web_app::AppId app_id; @@ -315,6 +345,55 @@ return app_browser_; } + void ListAppsInternal() { + auto* web_app_registrar = WebAppProvider::Get(browser()->profile()) + ->registrar() + .AsWebAppRegistrar(); + app_ids_ = web_app_registrar->GetAppIds(); + } + + NavigateToSiteResult NavigateToSite(Browser* browser, const GURL& url) { + content::WebContents* web_contents = GetCurrentTab(browser); + auto* app_banner_manager = + webapps::TestAppBannerManagerDesktop::FromWebContents(web_contents); + DCHECK(!app_banner_manager->WaitForInstallableCheck()); + + ui_test_utils::NavigateToURL(browser, url); + bool installable = app_banner_manager->WaitForInstallableCheck(); + + last_navigation_result_ = + NavigateToSiteResult{web_contents, app_banner_manager, installable}; + return last_navigation_result_; + } + + void RemovePolicyApp() { + GURL url = GetInstallableAppURL(); + base::RunLoop run_loop; + WebAppInstallObserver observer(browser()->profile()); + observer.SetWebAppUninstalledDelegate( + base::BindLambdaForTesting([&](const AppId& app_id) { + if (app_id_ == app_id) { + run_loop.Quit(); + } + })); + { + ListPrefUpdate update(browser()->profile()->GetPrefs(), + prefs::kWebAppInstallForceList); + update->EraseListValueIf([&](const base::Value& item) { + const base::Value* url_value = item.FindKey(kUrlKey); + return url_value && url_value->GetString() == url.spec(); + }); + } + run_loop.Run(); + } + + void SetOpenInWindowInternal() { + auto& app_registry_controller = + WebAppProvider::Get(browser()->profile())->registry_controller(); + app_registry_controller.SetAppUserDisplayMode( + app_id_, blink::mojom::DisplayMode::kStandalone, true); + } + // TODO(https://crbug.com/1159651): Support this action on CrOS. void UninstallFromMenu() { DCHECK(app_browser_); @@ -364,42 +443,25 @@ run_loop.Run(); } - void InstallCreateShortcutTabbed() { - chrome::SetAutoAcceptWebAppDialogForTesting(/*auto_accept=*/true, - /*auto_open_in_window=*/false); - WebAppInstallObserver observer(browser()->profile()); - CHECK(chrome::ExecuteCommand(browser(), IDC_CREATE_SHORTCUT)); - app_id_ = observer.AwaitNextInstall(); - chrome::SetAutoAcceptWebAppDialogForTesting(false, false); - } - - void SetOpenInWindowInternal() { - auto& app_registry_controller = - WebAppProvider::Get(browser()->profile())->registry_controller(); - app_registry_controller.SetAppUserDisplayMode( - app_id_, blink::mojom::DisplayMode::kStandalone, true); - } - - void ClosePWA() { - DCHECK(app_browser_); - app_browser_->window()->Close(); - ui_test_utils::WaitForBrowserToClose(app_browser_); - } - // Assert Actions + void AssertAppNotInList() { EXPECT_FALSE(base::Contains(app_ids_, app_id_)); } void AssertInstallable() { EXPECT_TRUE(last_navigation_result_.installable); } + void AssertInstallIconShown() { EXPECT_EQ(GetAppMenuCommandState(IDC_INSTALL_PWA, browser()), kEnabled); EXPECT_TRUE(pwa_install_view()->GetVisible()); } + void AssertInstallIconNotShown() { EXPECT_EQ(GetAppMenuCommandState(IDC_INSTALL_PWA, browser()), kNotPresent); EXPECT_FALSE(pwa_install_view()->GetVisible()); } + void AssertLaunchIconShown() { EXPECT_EQ(GetAppMenuCommandState(IDC_OPEN_IN_PWA_WINDOW, browser()), kEnabled); } + void AssertLaunchIconNotShown() { EXPECT_EQ(GetAppMenuCommandState(IDC_OPEN_IN_PWA_WINDOW, browser()), kNotPresent); @@ -407,12 +469,33 @@ void AssertWindowCreated() { EXPECT_TRUE(app_browser_); } + GURL GetInstallableAppURL() { + return https_server_.GetURL("/banners/manifest_test_page.html"); + } + + GURL GetNonInstallableAppURL() { + return https_server_.GetURL("/banners/no_manifest_test_page.html"); + } + + GURL GetInScopeURL() { + return https_server_.GetURL("/banners/manifest_test_page.html"); + } + + GURL GetOutOfScopeURL() { + return https_server_.GetURL("/out_of_scope/index.html"); + } + + content::WebContents* GetCurrentTab(Browser* browser) { + return browser->tab_strip_model()->GetActiveWebContents(); + } + Browser* app_browser() { return app_browser_; } std::vector<std::string>& testing_actions() { return testing_actions_; } PageActionIconView* pwa_install_view() { return pwa_install_view_; } private: Browser* app_browser_ = nullptr; + std::vector<AppId> app_ids_; std::vector<std::string> testing_actions_; NavigateToSiteResult last_navigation_result_; AppId app_id_; @@ -435,7 +518,7 @@ EXPECT_EQ(GetAppMenuCommandState(IDC_OPEN_IN_PWA_WINDOW, browser()), kNotPresent); - ExecutePwaInstallIcon(); + InstallOmniboxOrMenu(); chrome::NewTab(browser()); NavigateToSite(browser(), GetInstallableAppURL()); @@ -450,7 +533,7 @@ EXPECT_EQ(1U, browser_list->size()); EXPECT_FALSE(AppBrowserController::IsWebApp(browser_list->GetLastActive())); NavigateToSite(browser(), GetInstallableAppURL()); - ExecutePwaInstallIcon(); + InstallOmniboxOrMenu(); EXPECT_EQ(2U, browser_list->size()); EXPECT_TRUE(AppBrowserController::IsWebApp(browser_list->GetLastActive())); ClosePWA();
diff --git a/chrome/browser/ui/web_applications/web_app_engagement_browsertest.cc b/chrome/browser/ui/web_applications/web_app_engagement_browsertest.cc index 8e97e12..77205c1 100644 --- a/chrome/browser/ui/web_applications/web_app_engagement_browsertest.cc +++ b/chrome/browser/ui/web_applications/web_app_engagement_browsertest.cc
@@ -12,7 +12,6 @@ #include "base/metrics/statistics_recorder.h" #include "base/test/bind.h" #include "base/test/metrics/histogram_tester.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_list.h" @@ -29,6 +28,7 @@ #include "chrome/common/chrome_switches.h" #include "chrome/test/base/ui_test_utils.h" #include "components/site_engagement/content/engagement_type.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_types.h" #include "content/public/browser/web_contents.h"
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 126f17e..56873fc 100644 --- a/chrome/browser/ui/web_applications/web_app_launch_manager.cc +++ b/chrome/browser/ui/web_applications/web_app_launch_manager.cc
@@ -16,7 +16,6 @@ #include "chrome/browser/apps/app_service/app_launch_params.h" #include "chrome/browser/apps/app_service/launch_utils.h" #include "chrome/browser/banners/app_banner_settings_helper.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_finder.h" @@ -41,6 +40,7 @@ #include "chrome/browser/web_launch/web_launch_files_helper.h" #include "chrome/common/chrome_features.h" #include "chrome/common/chrome_switches.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "content/public/browser/page_navigator.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/web_contents.h"
diff --git a/chrome/browser/ui/web_applications/web_app_metrics.cc b/chrome/browser/ui/web_applications/web_app_metrics.cc index ed29cfda..22293d7 100644 --- a/chrome/browser/ui/web_applications/web_app_metrics.cc +++ b/chrome/browser/ui/web_applications/web_app_metrics.cc
@@ -9,7 +9,6 @@ #include "base/optional.h" #include "base/power_monitor/power_monitor.h" #include "base/time/time.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_finder.h" @@ -21,6 +20,7 @@ #include "chrome/browser/web_applications/daily_metrics_helper.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "components/site_engagement/content/engagement_type.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "components/webapps/installable/installable_metrics.h" #include "third_party/blink/public/mojom/manifest/display_mode.mojom.h"
diff --git a/chrome/browser/ui/web_applications/web_app_metrics.h b/chrome/browser/ui/web_applications/web_app_metrics.h index b2d8b25..3359fcb 100644 --- a/chrome/browser/ui/web_applications/web_app_metrics.h +++ b/chrome/browser/ui/web_applications/web_app_metrics.h
@@ -9,11 +9,11 @@ #include "base/power_monitor/power_observer.h" #include "base/scoped_observer.h" #include "chrome/browser/banners/app_banner_manager.h" -#include "chrome/browser/engagement/site_engagement_observer.h" #include "chrome/browser/ui/browser_tab_strip_tracker.h" #include "chrome/browser/ui/tabs/tab_strip_model_observer.h" #include "chrome/browser/web_applications/components/web_app_id.h" #include "components/keyed_service/core/keyed_service.h" +#include "components/site_engagement/content/site_engagement_observer.h" class Profile; class Browser;
diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc index 09dc9d7..868d9e9 100644 --- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc +++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
@@ -19,7 +19,6 @@ #include "chrome/browser/buildflags.h" #include "chrome/browser/chromeos/login/login_pref_names.h" #include "chrome/browser/devtools/devtools_ui_bindings.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/media/history/media_history_keyed_service.h" #include "chrome/browser/media/media_engagement_service.h" #include "chrome/browser/profiles/profile.h" @@ -95,6 +94,7 @@ #include "components/security_interstitials/content/known_interception_disclosure_ui.h" #include "components/security_interstitials/content/urls.h" #include "components/signin/public/base/signin_buildflags.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_ui.h" #include "content/public/common/content_client.h"
diff --git a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc index fcad654a..1280f86 100644 --- a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
@@ -236,8 +236,10 @@ } user_manager::UserType CalculateUserType(const AccountId& account_id) { - if (user_manager::UserManager::Get()->IsSupervisedAccountId(account_id)) - return user_manager::USER_TYPE_SUPERVISED; + if (user_manager::UserManager::Get()->IsDeprecatedSupervisedAccountId( + account_id)) { + return user_manager::USER_TYPE_SUPERVISED_DEPRECATED; + } if (account_id.GetAccountType() == AccountType::ACTIVE_DIRECTORY) return user_manager::USER_TYPE_ACTIVE_DIRECTORY;
diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc index 3e786cf..27de93f 100644 --- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
@@ -359,6 +359,7 @@ builder->Add("removeUserWarningTextCalculating", base::string16()); builder->Add("removeUserWarningTextSyncNoStats", base::string16()); builder->Add("removeUserWarningTextSyncCalculating", base::string16()); + // TODO(crbug/1164090): Remove this. builder->AddF("removeLegacySupervisedUserWarningText", IDS_LOGIN_POD_LEGACY_SUPERVISED_USER_REMOVE_WARNING, base::UTF8ToUTF16(
diff --git a/chrome/browser/ui/webui/discards/discards_ui.cc b/chrome/browser/ui/webui/discards/discards_ui.cc index dc082820..ca5c5ac 100644 --- a/chrome/browser/ui/webui/discards/discards_ui.cc +++ b/chrome/browser/ui/webui/discards/discards_ui.cc
@@ -14,7 +14,6 @@ #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/resource_coordinator/lifecycle_unit.h" #include "chrome/browser/resource_coordinator/lifecycle_unit_state.mojom.h" @@ -32,6 +31,7 @@ #include "chrome/grit/browser_resources.h" #include "components/favicon_base/favicon_url_parser.h" #include "components/performance_manager/public/performance_manager.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "content/public/browser/navigation_controller.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/url_data_source.h"
diff --git a/chrome/browser/ui/webui/engagement/site_engagement_ui.cc b/chrome/browser/ui/webui/engagement/site_engagement_ui.cc index e4bdcb6f..7781c93a 100644 --- a/chrome/browser/ui/webui/engagement/site_engagement_ui.cc +++ b/chrome/browser/ui/webui/engagement/site_engagement_ui.cc
@@ -12,10 +12,10 @@ #include "base/bind.h" #include "base/callback.h" #include "base/macros.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/url_constants.h" #include "chrome/grit/dev_ui_browser_resources.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "components/site_engagement/core/mojom/site_engagement_details.mojom.h" #include "content/public/browser/web_ui.h" #include "content/public/browser/web_ui_controller.h"
diff --git a/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.cc b/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.cc index 833e8ec89..b0196e9 100644 --- a/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.cc +++ b/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.cc
@@ -1027,16 +1027,22 @@ autocomplete_controller_->AddObserver(emitter); } - if (time_of_first_autocomplete_query_.is_null() && !input.empty()) - time_of_first_autocomplete_query_ = base::TimeTicks::Now(); + // TODO(tommycli): We use the input being empty as a signal we are requesting + // on-focus suggestions. It would be nice if we had a more explicit signal. + bool is_on_focus = input.empty(); + + // Early exit if a query is already in progress for on focus inputs. + if (!autocomplete_controller_->done() && is_on_focus) + return; + + if (time_user_first_modified_realbox_.is_null() && !is_on_focus) + time_user_first_modified_realbox_ = base::TimeTicks::Now(); AutocompleteInput autocomplete_input( input, metrics::OmniboxEventProto::NTP_REALBOX, ChromeAutocompleteSchemeClassifier(profile_)); - // TODO(tommycli): We use the input being empty as a signal we are requesting - // on-focus suggestions. It would be nice if we had a more explicit signal. - autocomplete_input.set_focus_type(input.empty() ? OmniboxFocusType::ON_FOCUS - : OmniboxFocusType::DEFAULT); + autocomplete_input.set_focus_type(is_on_focus ? OmniboxFocusType::ON_FOCUS + : OmniboxFocusType::DEFAULT); autocomplete_input.set_prevent_inline_autocomplete( prevent_inline_autocomplete); @@ -1055,7 +1061,7 @@ autocomplete_controller_->Stop(clear_result); if (clear_result) - time_of_first_autocomplete_query_ = base::TimeTicks(); + time_user_first_modified_realbox_ = base::TimeTicks(); } void NewTabPageHandler::OpenAutocompleteMatch( @@ -1085,7 +1091,7 @@ const auto now = base::TimeTicks::Now(); base::TimeDelta elapsed_time_since_first_autocomplete_query = - now - time_of_first_autocomplete_query_; + now - time_user_first_modified_realbox_; autocomplete_controller_->UpdateMatchDestinationURLWithQueryFormulationTime( elapsed_time_since_first_autocomplete_query, &match); @@ -1136,7 +1142,7 @@ base::TimeDelta default_time_delta = base::TimeDelta::FromMilliseconds(-1); - if (time_of_first_autocomplete_query_.is_null()) + if (time_user_first_modified_realbox_.is_null()) elapsed_time_since_first_autocomplete_query = default_time_delta; base::TimeDelta elapsed_time_since_last_change_to_default_match =
diff --git a/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.h b/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.h index 28f5a26..f57a2029 100644 --- a/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.h +++ b/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.h
@@ -238,7 +238,7 @@ FaviconCache favicon_cache_; BitmapFetcherService* bitmap_fetcher_service_; std::vector<BitmapFetcherService::RequestId> bitmap_request_ids_; - base::TimeTicks time_of_first_autocomplete_query_; + base::TimeTicks time_user_first_modified_realbox_; content::WebContents* web_contents_; base::Time ntp_navigation_start_time_; NTPUserDataLogger logger_;
diff --git a/chrome/browser/ui/webui/settings/about_handler.cc b/chrome/browser/ui/webui/settings/about_handler.cc index 6ad4c097..c521456 100644 --- a/chrome/browser/ui/webui/settings/about_handler.cc +++ b/chrome/browser/ui/webui/settings/about_handler.cc
@@ -280,6 +280,10 @@ base::Unretained(this))); #if BUILDFLAG(IS_CHROMEOS_ASH) web_ui()->RegisterMessageCallback( + "openDiagnostics", + base::BindRepeating(&AboutHandler::HandleOpenDiagnostics, + base::Unretained(this))); + web_ui()->RegisterMessageCallback( "openOsHelpPage", base::BindRepeating(&AboutHandler::HandleOpenOsHelpPage, base::Unretained(this))); web_ui()->RegisterMessageCallback( @@ -420,6 +424,11 @@ } #if BUILDFLAG(IS_CHROMEOS_ASH) +void AboutHandler::HandleOpenDiagnostics(const base::ListValue* args) { + DCHECK(args->empty()); + chrome::ShowDiagnosticsApp(profile_); +} + void AboutHandler::HandleCheckInternetConnection(const base::ListValue* args) { CHECK_EQ(1U, args->GetSize()); std::string callback_id;
diff --git a/chrome/browser/ui/webui/settings/about_handler.h b/chrome/browser/ui/webui/settings/about_handler.h index 68754be..4b5aafa8 100644 --- a/chrome/browser/ui/webui/settings/about_handler.h +++ b/chrome/browser/ui/webui/settings/about_handler.h
@@ -154,6 +154,8 @@ #endif #if BUILDFLAG(IS_CHROMEOS_ASH) + void HandleOpenDiagnostics(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 173b784..556adc7 100644 --- a/chrome/browser/ui/webui/settings/chromeos/about_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/about_section.cc
@@ -97,6 +97,19 @@ return *tags; } +const std::vector<SearchConcept>& GetDiagnosticsAppSearchConcepts() { + static const base::NoDestructor<std::vector<SearchConcept>> tags({ + {IDS_OS_SETTINGS_TAG_ABOUT_DIAGNOSTICS, + mojom::kAboutChromeOsDetailsSubpagePath, + mojom::SearchResultIcon::kChrome, + mojom::SearchResultDefaultRank::kMedium, + mojom::SearchResultType::kSetting, + {.setting = mojom::Setting::kDiagnostics}, + {IDS_OS_SETTINGS_TAG_ABOUT_DIAGNOSTICS_ALT1, SearchConcept::kAltTagEnd}}, + }); + return *tags; +} + #if BUILDFLAG(GOOGLE_CHROME_BRANDING) const std::vector<SearchConcept>& GetAboutTermsOfServiceSearchConcepts() { static const base::NoDestructor<std::vector<SearchConcept>> tags({ @@ -166,6 +179,10 @@ : OsSettingsSection(profile, search_tag_registry) { SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate(); updater.AddSearchTags(GetAboutSearchConcepts()); + + if (base::FeatureList::IsEnabled(chromeos::features::kDiagnosticsApp)) { + updater.AddSearchTags(GetDiagnosticsAppSearchConcepts()); + } } AboutSection::~AboutSection() = default; @@ -177,6 +194,7 @@ #if BUILDFLAG(GOOGLE_CHROME_BRANDING) {"aboutReportAnIssue", IDS_SETTINGS_ABOUT_PAGE_REPORT_AN_ISSUE}, #endif + {"aboutDiagnostics", IDS_SETTINGS_ABOUT_PAGE_DIAGNOSTICS}, {"aboutRelaunch", IDS_SETTINGS_ABOUT_PAGE_RELAUNCH}, {"aboutUpgradeCheckStarted", IDS_SETTINGS_ABOUT_UPGRADE_CHECK_STARTED}, {"aboutUpgradeRelaunch", IDS_SETTINGS_UPGRADE_SUCCESSFUL_RELAUNCH}, @@ -327,6 +345,10 @@ std::string safetyInfoLink = GetSafetyInfoLink(); html_source->AddBoolean("shouldShowSafetyInfo", !safetyInfoLink.empty()); + html_source->AddBoolean( + "diagnosticsAppEnabled", + base::FeatureList::IsEnabled(chromeos::features::kDiagnosticsApp)); + #if BUILDFLAG(GOOGLE_CHROME_BRANDING) html_source->AddString("aboutTermsURL", chrome::kChromeUITermsURL); html_source->AddLocalizedString("aboutProductTos", @@ -373,9 +395,9 @@ mojom::SearchResultIcon::kChrome, mojom::SearchResultDefaultRank::kMedium, mojom::kAboutChromeOsDetailsSubpagePath); static constexpr mojom::Setting kAboutChromeOsDetailsSettings[] = { - mojom::Setting::kCheckForOsUpdate, mojom::Setting::kSeeWhatsNew, + mojom::Setting::kCheckForOsUpdate, mojom::Setting::kSeeWhatsNew, mojom::Setting::kGetHelpWithChromeOs, mojom::Setting::kReportAnIssue, - mojom::Setting::kTermsOfService}; + mojom::Setting::kTermsOfService, mojom::Setting::kDiagnostics}; 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 b5a1ec99..f28d588 100644 --- a/chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom +++ b/chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom
@@ -248,6 +248,7 @@ kGetHelpWithChromeOs = 1704, kReportAnIssue = 1705, kTermsOfService = 1706, + kDiagnostics = 1707, // Kerberos section. kAddKerberosTicketV2 = 1800,
diff --git a/chrome/browser/ui/webui/settings/import_data_handler.cc b/chrome/browser/ui/webui/settings/import_data_handler.cc index 0e356e6..5eca85a0 100644 --- a/chrome/browser/ui/webui/settings/import_data_handler.cc +++ b/chrome/browser/ui/webui/settings/import_data_handler.cc
@@ -40,8 +40,7 @@ const char kImportStatusFailed[] = "failed"; } // namespace -ImportDataHandler::ImportDataHandler() - : importer_host_(nullptr), import_did_succeed_(false) { +ImportDataHandler::ImportDataHandler() : importer_host_(nullptr) { DCHECK_CURRENTLY_ON(BrowserThread::UI); } @@ -115,6 +114,12 @@ const base::DictionaryValue* types = nullptr; CHECK(args->GetDictionary(1, &types)); + if (!importer_list_loaded_ || browser_index < 0 || + browser_index >= static_cast<int>(importer_list_->count())) { + // Prevent out-of-bounds access. + return; + } + uint16_t selected_items = importer::NONE; if (*types->FindBoolKey(prefs::kImportDialogAutofillFormData)) selected_items |= importer::AUTOFILL_FORM_DATA; @@ -180,6 +185,7 @@ void ImportDataHandler::SendBrowserProfileData(const std::string& callback_id) { DCHECK_CURRENTLY_ON(BrowserThread::UI); + importer_list_loaded_ = true; base::ListValue browser_profiles; for (size_t i = 0; i < importer_list_->count(); ++i) {
diff --git a/chrome/browser/ui/webui/settings/import_data_handler.h b/chrome/browser/ui/webui/settings/import_data_handler.h index 6ee9d1a..173e710 100644 --- a/chrome/browser/ui/webui/settings/import_data_handler.h +++ b/chrome/browser/ui/webui/settings/import_data_handler.h
@@ -69,7 +69,8 @@ // of deleting itself when import is complete. ExternalProcessImporterHost* importer_host_; // weak - bool import_did_succeed_; + bool import_did_succeed_{false}; + bool importer_list_loaded_{false}; scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
diff --git a/chrome/browser/ui/webui/settings/site_settings_handler.cc b/chrome/browser/ui/webui/settings/site_settings_handler.cc index f692ca8..73dd3c4 100644 --- a/chrome/browser/ui/webui/settings/site_settings_handler.cc +++ b/chrome/browser/ui/webui/settings/site_settings_handler.cc
@@ -23,7 +23,6 @@ #include "chrome/browser/bluetooth/bluetooth_chooser_context.h" #include "chrome/browser/bluetooth/bluetooth_chooser_context_factory.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/hid/hid_chooser_context.h" #include "chrome/browser/hid/hid_chooser_context_factory.h" #include "chrome/browser/infobars/infobar_service.h" @@ -57,6 +56,7 @@ #include "components/permissions/permission_util.h" #include "components/prefs/pref_change_registrar.h" #include "components/prefs/pref_service.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_ui.h"
diff --git a/chrome/browser/ui/webui/signin/profile_picker_handler.cc b/chrome/browser/ui/webui/signin/profile_picker_handler.cc index d070bef..b33a898 100644 --- a/chrome/browser/ui/webui/signin/profile_picker_handler.cc +++ b/chrome/browser/ui/webui/signin/profile_picker_handler.cc
@@ -215,6 +215,11 @@ "setProfileName", base::BindRepeating(&ProfilePickerHandler::HandleSetProfileName, base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "recordSignInPromoImpression", + base::BindRepeating( + &ProfilePickerHandler::HandleRecordSignInPromoImpression, + base::Unretained(this))); } void ProfilePickerHandler::OnJavascriptAllowed() { @@ -454,6 +459,12 @@ profile, Profile::CREATE_STATUS_INITIALIZED); } +void ProfilePickerHandler::HandleRecordSignInPromoImpression( + const base::ListValue* /*args*/) { + signin_metrics::RecordSigninImpressionUserActionForAccessPoint( + signin_metrics::AccessPoint::ACCESS_POINT_USER_MANAGER); +} + void ProfilePickerHandler::HandleSetProfileName(const base::ListValue* args) { CHECK_EQ(2U, args->GetSize()); const base::Value& profile_path_value = args->GetList()[0];
diff --git a/chrome/browser/ui/webui/signin/profile_picker_handler.h b/chrome/browser/ui/webui/signin/profile_picker_handler.h index b359acf..61e1eb9 100644 --- a/chrome/browser/ui/webui/signin/profile_picker_handler.h +++ b/chrome/browser/ui/webui/signin/profile_picker_handler.h
@@ -49,6 +49,9 @@ void HandleGetProfileThemeInfo(const base::ListValue* args); void HandleCreateProfile(const base::ListValue* args); + // |args| is unused. + void HandleRecordSignInPromoImpression(const base::ListValue* args); + void OnLoadSigninFinished(bool success); void GatherProfileStatistics(Profile* profile); void OnProfileStatisticsReceived(base::FilePath profile_path,
diff --git a/chrome/browser/ui/webui/signin/profile_picker_ui.cc b/chrome/browser/ui/webui/signin/profile_picker_ui.cc index 9618b16..7e790be 100644 --- a/chrome/browser/ui/webui/signin/profile_picker_ui.cc +++ b/chrome/browser/ui/webui/signin/profile_picker_ui.cc
@@ -80,6 +80,7 @@ {"browseAsGuestButton", IDS_PROFILE_PICKER_BROWSE_AS_GUEST_BUTTON}, {"needsSigninPrompt", IDS_PROFILE_PICKER_PROFILE_CARD_NEEDS_SIGNIN_PROMPT}, + {"profileCardButtonLabel", IDS_PROFILE_PICKER_PROFILE_CARD_LABEL}, {"menu", IDS_MENU}, {"profileMenuName", IDS_PROFILE_PICKER_PROFILE_MENU_BUTTON_NAME}, {"profileMenuRemoveText", IDS_PROFILE_PICKER_PROFILE_MENU_REMOVE_TEXT},
diff --git a/chrome/browser/ui/webui/signin/user_manager_screen_handler.cc b/chrome/browser/ui/webui/signin/user_manager_screen_handler.cc index 3421904..2869c86 100644 --- a/chrome/browser/ui/webui/signin/user_manager_screen_handler.cc +++ b/chrome/browser/ui/webui/signin/user_manager_screen_handler.cc
@@ -71,6 +71,7 @@ const char kKeyEmailAddress[] = "emailAddress"; const char kKeyProfilePath[] = "profilePath"; const char kKeyPublicAccount[] = "publicAccount"; +// TODO(crbug/1164090): Remove this. const char kKeyLegacySupervisedUser[] = "legacySupervisedUser"; const char kKeyChildUser[] = "childUser"; const char kKeyCanRemove[] = "canRemove"; @@ -660,6 +661,7 @@ localized_strings->SetString("cancel", l10n_util::GetStringUTF16(IDS_CANCEL)); localized_strings->SetString( "browseAsGuest", l10n_util::GetStringUTF16(IDS_BROWSE_AS_GUEST_BUTTON)); + // TODO(crbug/1164090): Remove this. localized_strings->SetString("addSupervisedUser", l10n_util::GetStringUTF16(IDS_CREATE_LEGACY_SUPERVISED_USER_MENU_LABEL)); @@ -702,6 +704,7 @@ localized_strings->SetString( "removeUserWarningTextSync", l10n_util::GetStringUTF16(IDS_LOGIN_POD_USER_REMOVE_WARNING_SYNC)); + // TODO(crbug/1164090): Remove this. localized_strings->SetString("removeLegacySupervisedUserWarningText", l10n_util::GetStringFUTF16( IDS_LOGIN_POD_LEGACY_SUPERVISED_USER_REMOVE_WARNING, @@ -803,6 +806,7 @@ profiles::GetAvatarNameForProfile(profile_path)); profile_value->SetKey(kKeyProfilePath, util::FilePathToValue(profile_path)); profile_value->SetBoolean(kKeyPublicAccount, false); + // TODO(crbug/1164090): Remove this. profile_value->SetBoolean(kKeyLegacySupervisedUser, entry->IsLegacySupervised()); profile_value->SetBoolean(kKeyChildUser, entry->IsChild());
diff --git a/chrome/browser/ui/webui/tab_strip/thumbnail_tracker.cc b/chrome/browser/ui/webui/tab_strip/thumbnail_tracker.cc index c33dfe94..ab1b9ea 100644 --- a/chrome/browser/ui/webui/tab_strip/thumbnail_tracker.cc +++ b/chrome/browser/ui/webui/tab_strip/thumbnail_tracker.cc
@@ -15,14 +15,17 @@ // Handles requests for a given tab's thumbnail and watches for thumbnail // updates for the lifetime of the tab. -class ThumbnailTracker::ContentsData : public content::WebContentsObserver, - public ThumbnailImage::Observer { +class ThumbnailTracker::ContentsData : public content::WebContentsObserver { public: ContentsData(ThumbnailTracker* parent, content::WebContents* contents) : content::WebContentsObserver(contents), parent_(parent) { thumbnail_ = parent_->thumbnail_getter_.Run(contents); - if (thumbnail_) - observation_.Observe(thumbnail_.get()); + if (!thumbnail_) + return; + + subscription_ = thumbnail_->Subscribe(); + subscription_->SetCompressedImageCallback(base::BindRepeating( + &ContentsData::ThumbnailImageCallback, base::Unretained(this))); } void RequestThumbnail() { @@ -35,8 +38,7 @@ // We must un-observe each ThumbnailImage when the WebContents it came from // closes. if (thumbnail_) { - DCHECK(observation_.IsObservingSource(thumbnail_.get())); - observation_.Reset(); + subscription_.reset(); thumbnail_.reset(); } @@ -44,17 +46,14 @@ parent_->ContentsClosed(web_contents()); } - // ThumbnailImage::Observer: - void OnCompressedThumbnailDataAvailable( - CompressedThumbnailData thumbnail_image) override { - parent_->ThumbnailUpdated(web_contents(), thumbnail_image); + private: + void ThumbnailImageCallback(CompressedThumbnailData image) { + parent_->ThumbnailUpdated(web_contents(), image); } - private: ThumbnailTracker* parent_; scoped_refptr<ThumbnailImage> thumbnail_; - base::ScopedObservation<ThumbnailImage, ThumbnailImage::Observer> - observation_{this}; + std::unique_ptr<ThumbnailImage::Subscription> subscription_; DISALLOW_COPY_AND_ASSIGN(ContentsData); };
diff --git a/chrome/browser/xsurface/BUILD.gn b/chrome/browser/xsurface/BUILD.gn index ddc8791e..63826464 100644 --- a/chrome/browser/xsurface/BUILD.gn +++ b/chrome/browser/xsurface/BUILD.gn
@@ -12,6 +12,7 @@ "android/java/src/org/chromium/chrome/browser/xsurface/ImagePrefetcher.java", "android/java/src/org/chromium/chrome/browser/xsurface/ListContentManager.java", "android/java/src/org/chromium/chrome/browser/xsurface/ListContentManagerObserver.java", + "android/java/src/org/chromium/chrome/browser/xsurface/PersistentKeyValueCache.java", "android/java/src/org/chromium/chrome/browser/xsurface/ProcessScope.java", "android/java/src/org/chromium/chrome/browser/xsurface/ProcessScopeDependencyProvider.java", "android/java/src/org/chromium/chrome/browser/xsurface/SurfaceActionsHandler.java",
diff --git a/chrome/browser/xsurface/android/java/src/org/chromium/chrome/browser/xsurface/PersistentKeyValueCache.java b/chrome/browser/xsurface/android/java/src/org/chromium/chrome/browser/xsurface/PersistentKeyValueCache.java new file mode 100644 index 0000000..154d8b6 --- /dev/null +++ b/chrome/browser/xsurface/android/java/src/org/chromium/chrome/browser/xsurface/PersistentKeyValueCache.java
@@ -0,0 +1,47 @@ +// Copyright 2020 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. + +package org.chromium.chrome.browser.xsurface; + +import androidx.annotation.Nullable; + +/** A simple key-value cache that is persisting all data on disk. Automatically evicts old data. */ +public interface PersistentKeyValueCache { + /** Consumes the result of PersistentKeyValueCache.lookup(). */ + public interface ValueConsumer { + /** + * Called when a lookup is complete. + * + * @param value The value found. null if no value was present. + */ + void run(@Nullable byte[] value); + } + + /** + * Retrieves and returns the value associated with the given key if it exists. + * This does not affect the key/value's age for automatic eviction. + * + * @param key The key to look up. + * @param consumer The consumer called when the lookup is complete. + */ + default void lookup(byte[] key, ValueConsumer consumer) {} + + /** + * Inserts the given entry into the cache, overwriting any entry that might already exist + * against the given key. + * + * @param key The key to insert. + * @param value The value to insert. + * @param onComplete Called after the key/value was inserted. + */ + default void put(byte[] key, byte[] value, @Nullable Runnable onComplete) {} + + /** + * Evicts an entry from the cache by the specified key. + * + * @param key The key whose entry must be evicted. + * @param onComplete Called after the operation completes. + */ + default void evict(byte[] key, @Nullable Runnable onComplete) {} +}
diff --git a/chrome/browser/xsurface/android/java/src/org/chromium/chrome/browser/xsurface/ProcessScopeDependencyProvider.java b/chrome/browser/xsurface/android/java/src/org/chromium/chrome/browser/xsurface/ProcessScopeDependencyProvider.java index 68e13eb..75fc160 100644 --- a/chrome/browser/xsurface/android/java/src/org/chromium/chrome/browser/xsurface/ProcessScopeDependencyProvider.java +++ b/chrome/browser/xsurface/android/java/src/org/chromium/chrome/browser/xsurface/ProcessScopeDependencyProvider.java
@@ -58,6 +58,11 @@ return null; } + @Nullable + default PersistentKeyValueCache getPersistentKeyValueCache() { + return null; + } + // Posts task to the UI thread. int TASK_TYPE_UI_THREAD = 1; // Posts to a background thread. The task may block.
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index 386be04a..05e0781 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-master-1610365490-2d34930da692ba60039f1162f9ee976fe2d1462a.profdata +chrome-linux-master-1610408110-1b25c741a858a17df9d643531610232aedd2e5da.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index 2a48652..2f4b4b7 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-master-1610365490-cff9cfe8ee50bd1daf2a4d54676a0415ea568ae4.profdata +chrome-mac-master-1610408110-5a618b6e0bdb5b4a60796f5aa8c6f6759f78cdd3.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index bf0f840..648021c 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-master-1610376073-6f28b769fbc009549335371d81a980da57e0e846.profdata +chrome-win32-master-1610398040-59038019b78fe7d9277311f636fda97275a69be4.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index 40f58e1..bf52c0a 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-master-1610376073-2cb1d075a5ed746f73a3a1ee8fa077d597a4f418.profdata +chrome-win64-master-1610387594-34ec7be13acbaa9470ba5363f8af27b0c42697d0.profdata
diff --git a/chrome/common/BUILD.gn b/chrome/common/BUILD.gn index f907062..737d5ea5 100644 --- a/chrome/common/BUILD.gn +++ b/chrome/common/BUILD.gn
@@ -261,8 +261,6 @@ "extensions/api/omnibox/omnibox_handler.h", "extensions/api/speech/tts_engine_manifest_handler.cc", "extensions/api/speech/tts_engine_manifest_handler.h", - "extensions/api/spellcheck/spellcheck_handler.cc", - "extensions/api/spellcheck/spellcheck_handler.h", "extensions/api/storage/storage_schema_manifest_handler.cc", "extensions/api/storage/storage_schema_manifest_handler.h", "extensions/api/system_indicator/system_indicator_handler.cc",
diff --git a/chrome/common/chrome_content_client_unittest.cc b/chrome/common/chrome_content_client_unittest.cc index e5983cd..ca15501 100644 --- a/chrome/common/chrome_content_client_unittest.cc +++ b/chrome/common/chrome_content_client_unittest.cc
@@ -14,6 +14,7 @@ #include "content/public/common/content_switches.h" #include "content/public/common/origin_util.h" #include "content/public/test/test_utils.h" +#include "extensions/buildflags/buildflags.h" #include "extensions/common/constants.h" #include "ppapi/buildflags/buildflags.h" #include "services/network/public/cpp/is_potentially_trustworthy.h" @@ -103,8 +104,28 @@ EXPECT_EQ("chrome-extension://abcdefghijklmnopqrstuvwxyzabcdef", origin.Serialize()); - EXPECT_TRUE( - network::IsUrlPotentiallyTrustworthy(GURL("chrome-native://newtab/"))); + // IsUrlPotentiallyTrustworthy assertions test for https://crbug.com/734581. + constexpr const char* kChromeLayerUrlsRegisteredAsSecure[] = { + // The schemes below are registered both as secure and no-access. Product + // code needs to treat such URLs as trustworthy, even though no-access + // schemes translate into an opaque origin (which is untrustworthy). + "chrome-native://newtab/", + "chrome-error://foo/", + // The schemes below are registered as secure (but not as no-access). + "chrome://foo/", + "chrome-untrusted://foo/", + "chrome-search://foo/", +#if BUILDFLAG(ENABLE_EXTENSIONS) + "chrome-extension://foo/", +#endif + "devtools://foo/", + }; + for (const std::string& str : kChromeLayerUrlsRegisteredAsSecure) { + SCOPED_TRACE(str); + GURL url(str); + EXPECT_TRUE(base::Contains(url::GetSecureSchemes(), url.scheme())); + EXPECT_TRUE(network::IsUrlPotentiallyTrustworthy(url)); + } GURL chrome_url(content::GetWebUIURL("dummyurl")); EXPECT_TRUE(network::IsUrlPotentiallyTrustworthy(chrome_url));
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc index 982cd07..0f9c497 100644 --- a/chrome/common/chrome_features.cc +++ b/chrome/common/chrome_features.cc
@@ -241,7 +241,13 @@ // Moves the Extensions "puzzle piece" icon from the title bar into the app menu // for web app windows. const base::Feature kDesktopPWAsElidedExtensionsMenu{ - "DesktopPWAsElidedExtensionsMenu", base::FEATURE_DISABLED_BY_DEFAULT}; + "DesktopPWAsElidedExtensionsMenu", +#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) + base::FEATURE_ENABLED_BY_DEFAULT +#else + base::FEATURE_DISABLED_BY_DEFAULT +#endif +}; // Replaces the origin text flash in web app titlebars with the name of the app. const base::Feature kDesktopPWAsFlashAppNameInsteadOfOrigin{
diff --git a/chrome/common/extensions/api/_manifest_features.json b/chrome/common/extensions/api/_manifest_features.json index 10b8550..832ce41 100644 --- a/chrome/common/extensions/api/_manifest_features.json +++ b/chrome/common/extensions/api/_manifest_features.json
@@ -213,10 +213,6 @@ "channel": "stable", "extension_types": "all" }, - "spellcheck": { - "channel": "dev", - "extension_types": ["extension"] - }, "storage": { "channel": "stable", "extension_types": [
diff --git a/chrome/common/extensions/api/spellcheck/spellcheck_handler.cc b/chrome/common/extensions/api/spellcheck/spellcheck_handler.cc deleted file mode 100644 index dfcf568..0000000 --- a/chrome/common/extensions/api/spellcheck/spellcheck_handler.cc +++ /dev/null
@@ -1,71 +0,0 @@ -// Copyright (c) 2013 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/common/extensions/api/spellcheck/spellcheck_handler.h" - -#include <memory> - -#include "base/strings/utf_string_conversions.h" -#include "extensions/common/manifest_constants.h" - -namespace extensions { - -namespace keys = manifest_keys; -namespace errors = manifest_errors; - -SpellcheckDictionaryInfo::SpellcheckDictionaryInfo() { -} - -SpellcheckDictionaryInfo::~SpellcheckDictionaryInfo() { -} - -SpellcheckHandler::SpellcheckHandler() { -} - -SpellcheckHandler::~SpellcheckHandler() { -} - -bool SpellcheckHandler::Parse(Extension* extension, base::string16* error) { - const base::DictionaryValue* spellcheck_value = NULL; - if (!extension->manifest()->GetDictionary(keys::kSpellcheck, - &spellcheck_value)) { - *error = base::ASCIIToUTF16(errors::kInvalidSpellcheck); - return false; - } - std::unique_ptr<SpellcheckDictionaryInfo> spellcheck_info( - new SpellcheckDictionaryInfo); - if (!spellcheck_value->HasKey(keys::kSpellcheckDictionaryLanguage) || - !spellcheck_value->GetString(keys::kSpellcheckDictionaryLanguage, - &spellcheck_info->language)) { - *error = base::ASCIIToUTF16(errors::kInvalidSpellcheckDictionaryLanguage); - return false; - } - if (!spellcheck_value->HasKey(keys::kSpellcheckDictionaryLocale) || - !spellcheck_value->GetString(keys::kSpellcheckDictionaryLocale, - &spellcheck_info->locale)) { - *error = base::ASCIIToUTF16(errors::kInvalidSpellcheckDictionaryLocale); - return false; - } - if (!spellcheck_value->HasKey(keys::kSpellcheckDictionaryFormat) || - !spellcheck_value->GetString(keys::kSpellcheckDictionaryFormat, - &spellcheck_info->format)) { - *error = base::ASCIIToUTF16(errors::kInvalidSpellcheckDictionaryFormat); - return false; - } - if (!spellcheck_value->HasKey(keys::kSpellcheckDictionaryPath) || - !spellcheck_value->GetString(keys::kSpellcheckDictionaryPath, - &spellcheck_info->path)) { - *error = base::ASCIIToUTF16(errors::kInvalidSpellcheckDictionaryPath); - return false; - } - extension->SetManifestData(keys::kSpellcheck, std::move(spellcheck_info)); - return true; -} - -base::span<const char* const> SpellcheckHandler::Keys() const { - static constexpr const char* kKeys[] = {keys::kSpellcheck}; - return kKeys; -} - -} // namespace extensions
diff --git a/chrome/common/extensions/api/spellcheck/spellcheck_handler.h b/chrome/common/extensions/api/spellcheck/spellcheck_handler.h deleted file mode 100644 index af71305..0000000 --- a/chrome/common/extensions/api/spellcheck/spellcheck_handler.h +++ /dev/null
@@ -1,42 +0,0 @@ -// Copyright (c) 2013 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_COMMON_EXTENSIONS_API_SPELLCHECK_SPELLCHECK_HANDLER_H_ -#define CHROME_COMMON_EXTENSIONS_API_SPELLCHECK_SPELLCHECK_HANDLER_H_ - -#include "base/macros.h" -#include "extensions/common/extension.h" -#include "extensions/common/manifest_handler.h" - -namespace extensions { - -// This structure holds the information parsed by the SpellcheckHandler to be -// used in the SpellcheckAPI functions. It is stored on the extension. -struct SpellcheckDictionaryInfo : public extensions::Extension::ManifestData { - SpellcheckDictionaryInfo(); - ~SpellcheckDictionaryInfo() override; - - std::string language; - std::string locale; - std::string path; - std::string format; -}; - -// Parses the "spellcheck" manifest key. -class SpellcheckHandler : public ManifestHandler { - public: - SpellcheckHandler(); - ~SpellcheckHandler() override; - - bool Parse(Extension* extension, base::string16* error) override; - - private: - base::span<const char* const> Keys() const override; - - DISALLOW_COPY_AND_ASSIGN(SpellcheckHandler); -}; - -} // namespace extensions - -#endif // CHROME_COMMON_EXTENSIONS_API_SPELLCHECK_SPELLCHECK_HANDLER_H_
diff --git a/chrome/common/extensions/chrome_manifest_handlers.cc b/chrome/common/extensions/chrome_manifest_handlers.cc index 8d2c3b5..57ba6fb 100644 --- a/chrome/common/extensions/chrome_manifest_handlers.cc +++ b/chrome/common/extensions/chrome_manifest_handlers.cc
@@ -11,7 +11,6 @@ #include "chrome/common/extensions/api/commands/commands_handler.h" #include "chrome/common/extensions/api/omnibox/omnibox_handler.h" #include "chrome/common/extensions/api/speech/tts_engine_manifest_handler.h" -#include "chrome/common/extensions/api/spellcheck/spellcheck_handler.h" #include "chrome/common/extensions/api/storage/storage_schema_manifest_handler.h" #include "chrome/common/extensions/api/system_indicator/system_indicator_handler.h" #include "chrome/common/extensions/api/url_handlers/url_handlers_parser.h" @@ -60,7 +59,6 @@ registry->RegisterHandler(std::make_unique<OmniboxHandler>()); registry->RegisterHandler(std::make_unique<OptionsPageManifestHandler>()); registry->RegisterHandler(std::make_unique<SettingsOverridesHandler>()); - registry->RegisterHandler(std::make_unique<SpellcheckHandler>()); registry->RegisterHandler(std::make_unique<StorageSchemaManifestHandler>()); registry->RegisterHandler(std::make_unique<SystemIndicatorHandler>()); registry->RegisterHandler(std::make_unique<ThemeHandler>());
diff --git a/chrome/common/url_constants.h b/chrome/common/url_constants.h index 6ad80524..36d50e9 100644 --- a/chrome/common/url_constants.h +++ b/chrome/common/url_constants.h
@@ -174,6 +174,7 @@ // Management URL for Chrome Supervised Users - version without scheme, used // for display. +// TODO(crbug/1164090): Remove this. extern const char kLegacySupervisedUserManagementDisplayURL[]; // The URL for the Learn More page about policies and enterprise enrollment.
diff --git a/chrome/common/webui_url_constants.cc b/chrome/common/webui_url_constants.cc index 015f492..9062876 100644 --- a/chrome/common/webui_url_constants.cc +++ b/chrome/common/webui_url_constants.cc
@@ -247,6 +247,7 @@ const char kChromeUICrostiniUpgraderUrl[] = "chrome://crostini-upgrader"; const char kChromeUICryptohomeHost[] = "cryptohome"; const char kChromeUIDeviceEmulatorHost[] = "device-emulator"; +const char kChromeUIDiagnosticsAppURL[] = "chrome://diagnostics"; 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 e5c9666..4495232d 100644 --- a/chrome/common/webui_url_constants.h +++ b/chrome/common/webui_url_constants.h
@@ -240,6 +240,7 @@ extern const char kChromeUICrostiniUpgraderUrl[]; extern const char kChromeUICryptohomeHost[]; extern const char kChromeUIDeviceEmulatorHost[]; +extern const char kChromeUIDiagnosticsAppURL[]; extern const char kChromeUIEmojiPickerURL[]; extern const char kChromeUIEmojiPickerHost[]; extern const char kChromeUIIntenetConfigDialogURL[];
diff --git a/chrome/renderer/v8_unwinder.cc b/chrome/renderer/v8_unwinder.cc index 813fa47..1f88919 100644 --- a/chrome/renderer/v8_unwinder.cc +++ b/chrome/renderer/v8_unwinder.cc
@@ -85,7 +85,7 @@ V8Unwinder::~V8Unwinder() = default; -void V8Unwinder::AddInitialModules(base::ModuleCache* module_cache) { +void V8Unwinder::InitializeModules(base::ModuleCache* module_cache) { // This function must be called only once. DCHECK(modules_.empty()); @@ -109,7 +109,7 @@ } // Update the modules based on what was recorded in |code_ranges_|. The singular -// embedded code range was already added in in AddInitialModules(). It is +// embedded code range was already added in in InitializeModules(). It is // preserved by the algorithm below, which is why kNonEmbedded is // unconditionally passed when creating new modules. void V8Unwinder::UpdateModules(base::ModuleCache* module_cache) {
diff --git a/chrome/renderer/v8_unwinder.h b/chrome/renderer/v8_unwinder.h index a394b822..b275a8b 100644 --- a/chrome/renderer/v8_unwinder.h +++ b/chrome/renderer/v8_unwinder.h
@@ -22,7 +22,7 @@ V8Unwinder& operator=(const V8Unwinder&) = delete; // Unwinder: - void AddInitialModules(base::ModuleCache* module_cache) override; + void InitializeModules(base::ModuleCache* module_cache) override; void OnStackCapture() override; void UpdateModules(base::ModuleCache* module_cache) override; bool CanUnwindFrom(const base::Frame& current_frame) const override;
diff --git a/chrome/renderer/v8_unwinder_unittest.cc b/chrome/renderer/v8_unwinder_unittest.cc index add0565b..acabe50 100644 --- a/chrome/renderer/v8_unwinder_unittest.cc +++ b/chrome/renderer/v8_unwinder_unittest.cc
@@ -222,7 +222,7 @@ V8Unwinder unwinder(v8_environment.isolate()); base::ModuleCache module_cache; - unwinder.AddInitialModules(&module_cache); + unwinder.InitializeModules(&module_cache); v8::MemoryRange embedded_code_range; v8_environment.isolate()->GetEmbeddedCodeRange( @@ -239,7 +239,7 @@ UpdateModulesTestUnwinder unwinder(v8_environment.isolate()); base::ModuleCache module_cache; - unwinder.AddInitialModules(&module_cache); + unwinder.InitializeModules(&module_cache); unwinder.SetCodePages({{reinterpret_cast<void*>(1), 10}, GetEmbeddedCodeRange(v8_environment.isolate())}); @@ -264,7 +264,7 @@ UpdateModulesTestUnwinder unwinder(v8_environment.isolate()); base::ModuleCache module_cache; - unwinder.AddInitialModules(&module_cache); + unwinder.InitializeModules(&module_cache); const int kDefaultCapacity = v8::Isolate::kMinCodePagesBufferSize; std::vector<v8::MemoryRange> code_pages; @@ -291,7 +291,7 @@ UpdateModulesTestUnwinder unwinder(v8_environment.isolate()); base::ModuleCache module_cache; - unwinder.AddInitialModules(&module_cache); + unwinder.InitializeModules(&module_cache); unwinder.SetCodePages({{reinterpret_cast<void*>(1), 10}, GetEmbeddedCodeRange(v8_environment.isolate())}); unwinder.OnStackCapture(); @@ -312,7 +312,7 @@ UpdateModulesTestUnwinder unwinder(v8_environment.isolate()); base::ModuleCache module_cache; - unwinder.AddInitialModules(&module_cache); + unwinder.InitializeModules(&module_cache); unwinder.SetCodePages({{reinterpret_cast<void*>(100), 10}, GetEmbeddedCodeRange(v8_environment.isolate())}); @@ -338,7 +338,7 @@ UpdateModulesTestUnwinder unwinder(v8_environment.isolate()); base::ModuleCache module_cache; - unwinder.AddInitialModules(&module_cache); + unwinder.InitializeModules(&module_cache); unwinder.SetCodePages({{reinterpret_cast<void*>(1), 10}, GetEmbeddedCodeRange(v8_environment.isolate())}); @@ -362,7 +362,7 @@ UpdateModulesTestUnwinder unwinder(v8_environment.isolate()); base::ModuleCache module_cache; - unwinder.AddInitialModules(&module_cache); + unwinder.InitializeModules(&module_cache); unwinder.SetCodePages({{reinterpret_cast<void*>(1), 10}, GetEmbeddedCodeRange(v8_environment.isolate())}); @@ -387,7 +387,7 @@ UpdateModulesTestUnwinder unwinder(v8_environment.isolate()); base::ModuleCache module_cache; - unwinder.AddInitialModules(&module_cache); + unwinder.InitializeModules(&module_cache); unwinder.SetCodePages({{{reinterpret_cast<void*>(1), 10}, GetEmbeddedCodeRange(v8_environment.isolate())}}); @@ -408,7 +408,7 @@ UpdateModulesTestUnwinder unwinder(v8_environment.isolate()); base::ModuleCache module_cache; - unwinder.AddInitialModules(&module_cache); + unwinder.InitializeModules(&module_cache); unwinder.SetCodePages({{{reinterpret_cast<void*>(1), 10}, {reinterpret_cast<void*>(100), 10}, @@ -429,7 +429,7 @@ UpdateModulesTestUnwinder unwinder(v8_environment.isolate()); base::ModuleCache module_cache; - unwinder.AddInitialModules(&module_cache); + unwinder.InitializeModules(&module_cache); const int kDefaultCapacity = v8::Isolate::kMinCodePagesBufferSize; @@ -466,7 +466,7 @@ UpdateModulesTestUnwinder unwinder(v8_environment.isolate()); base::ModuleCache module_cache; - unwinder.AddInitialModules(&module_cache); + unwinder.InitializeModules(&module_cache); const int kDefaultCapacity = v8::Isolate::kMinCodePagesBufferSize; const int kCodePages = kDefaultCapacity * 3; @@ -500,7 +500,7 @@ UpdateModulesTestUnwinder unwinder(v8_environment.isolate()); base::ModuleCache module_cache; - unwinder.AddInitialModules(&module_cache); + unwinder.InitializeModules(&module_cache); unwinder.SetCodePages({{reinterpret_cast<void*>(1), 10}, GetEmbeddedCodeRange(v8_environment.isolate())}); @@ -518,7 +518,7 @@ UpdateModulesTestUnwinder unwinder(v8_environment.isolate()); base::ModuleCache module_cache; - unwinder.AddInitialModules(&module_cache); + unwinder.InitializeModules(&module_cache); unwinder.SetCodePages({GetEmbeddedCodeRange(v8_environment.isolate())}); unwinder.OnStackCapture(); @@ -536,7 +536,7 @@ UpdateModulesTestUnwinder unwinder(v8_environment.isolate()); base::ModuleCache module_cache; - unwinder.AddInitialModules(&module_cache); + unwinder.InitializeModules(&module_cache); // Insert a non-native module to potentially exercise the Module comparator. unwinder.SetCodePages({{reinterpret_cast<void*>(1), 10},
diff --git a/chrome/services/machine_learning/BUILD.gn b/chrome/services/machine_learning/BUILD.gn index 644190e..2aefa002 100644 --- a/chrome/services/machine_learning/BUILD.gn +++ b/chrome/services/machine_learning/BUILD.gn
@@ -14,6 +14,7 @@ ":metrics", "//base", "//chrome:strings", + "//chrome/common:buildflags", "//mojo/public/cpp/bindings", ] @@ -69,6 +70,8 @@ ":metrics", "//base", "//base/test:test_support", + "//chrome/common:buildflags", + "//chrome/common:constants", "//chrome/services/machine_learning/public/cpp:cpp", "//chrome/services/machine_learning/public/cpp:test_support", "//testing/gtest",
diff --git a/chrome/services/machine_learning/in_process_tflite_predictor_unittest.cc b/chrome/services/machine_learning/in_process_tflite_predictor_unittest.cc index ffdee8f..e7e9168 100644 --- a/chrome/services/machine_learning/in_process_tflite_predictor_unittest.cc +++ b/chrome/services/machine_learning/in_process_tflite_predictor_unittest.cc
@@ -6,10 +6,14 @@ #include <string> +#include "base/files/file_path.h" +#include "base/files/file_util.h" #include "base/logging.h" #include "base/macros.h" #include "base/path_service.h" +#include "base/strings/utf_string_conversions.h" #include "base/test/task_environment.h" +#include "build/build_config.h" #include "chrome/common/chrome_paths.h" #include "testing/gtest/include/gtest/gtest.h" @@ -35,17 +39,19 @@ InProcessTFLitePredictorTest() = default; ~InProcessTFLitePredictorTest() override = default; - // Returns TFLite test model path + // Returns TFLite test model path. std::string GetTFLiteTestPath() { - // Location of generated test data (<(PROGRAM_DIR)/test_data). - base::FilePath g_gen_test_data_directory; + base::FilePath model_file_path; - base::PathService::Get(chrome::DIR_GEN_TEST_DATA, - &g_gen_test_data_directory); - g_gen_test_data_directory = - g_gen_test_data_directory.Append("simple_test.tflite"); + EXPECT_TRUE( + base::PathService::Get(base::DIR_SOURCE_ROOT, &model_file_path)); - return g_gen_test_data_directory.value().c_str(); + model_file_path = model_file_path.Append(FILE_PATH_LITERAL("chrome")) + .Append(FILE_PATH_LITERAL("test")) + .Append(FILE_PATH_LITERAL("data")) + .Append(FILE_PATH_LITERAL("simple_test.tflite")); + EXPECT_TRUE(base::PathExists(model_file_path)); + return model_file_path.value().c_str(); } };
diff --git a/chrome/services/sharing/nearby/platform/bluetooth_server_socket.cc b/chrome/services/sharing/nearby/platform/bluetooth_server_socket.cc index 58c4cd0..2c85c7c 100644 --- a/chrome/services/sharing/nearby/platform/bluetooth_server_socket.cc +++ b/chrome/services/sharing/nearby/platform/bluetooth_server_socket.cc
@@ -4,6 +4,7 @@ #include "chrome/services/sharing/nearby/platform/bluetooth_server_socket.h" +#include "base/logging.h" #include "base/task/task_traits.h" #include "base/task/thread_pool.h" #include "chrome/services/sharing/nearby/platform/bluetooth_socket.h" @@ -19,7 +20,9 @@ base::ThreadPool::CreateSequencedTaskRunner({base::MayBlock()})), server_socket_(std::move(server_socket), task_runner_) {} -BluetoothServerSocket::~BluetoothServerSocket() = default; +BluetoothServerSocket::~BluetoothServerSocket() { + Close(); +} std::unique_ptr<api::BluetoothSocket> BluetoothServerSocket::Accept() { bluetooth::mojom::AcceptConnectionResultPtr result; @@ -35,7 +38,14 @@ } Exception BluetoothServerSocket::Close() { - server_socket_.reset(); + if (server_socket_) { + if (server_socket_->Disconnect()) { + VLOG(1) << "Successfully tore down Nearby Bluetooth server socket."; + } else { + LOG(ERROR) << "Failed to tear down Nearby Bluetooth server socket."; + } + server_socket_.reset(); + } return {Exception::kSuccess}; }
diff --git a/chrome/services/sharing/nearby/platform/bluetooth_server_socket_unittest.cc b/chrome/services/sharing/nearby/platform/bluetooth_server_socket_unittest.cc index be332f8..936de61 100644 --- a/chrome/services/sharing/nearby/platform/bluetooth_server_socket_unittest.cc +++ b/chrome/services/sharing/nearby/platform/bluetooth_server_socket_unittest.cc
@@ -65,6 +65,9 @@ void Accept(AcceptCallback callback) override { std::move(callback).Run(std::move(accept_connection_result_)); } + void Disconnect(DisconnectCallback callback) override { + std::move(callback).Run(); + } bluetooth::mojom::AcceptConnectionResultPtr accept_connection_result_; base::OnceClosure on_destroy_callback_;
diff --git a/chrome/services/sharing/nearby/test_support/fake_adapter.cc b/chrome/services/sharing/nearby/test_support/fake_adapter.cc index b1efe1b6..72f1e4a 100644 --- a/chrome/services/sharing/nearby/test_support/fake_adapter.cc +++ b/chrome/services/sharing/nearby/test_support/fake_adapter.cc
@@ -72,6 +72,9 @@ void Accept(AcceptCallback callback) override { std::move(callback).Run(/*result=*/nullptr); } + void Disconnect(DisconnectCallback callback) override { + std::move(callback).Run(); + } }; } // namespace
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index ac2e26b..d6004b2 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -1047,6 +1047,7 @@ "../browser/extensions/protocol_handler_apitest.cc", "../browser/fast_shutdown_browsertest.cc", "../browser/favicon/content_favicon_driver_browsertest.cc", + "../browser/federated_learning/floc_eligibility_browsertest.cc", "../browser/federated_learning/floc_id_provider_browsertest.cc", "../browser/federated_learning/floc_origin_trial_browsertest.cc", "../browser/first_run/first_run_browsertest.cc", @@ -2782,6 +2783,7 @@ "../browser/ui/ash/accelerator_commands_browsertest.cc", "../browser/ui/ash/assistant/assistant_context_browsertest.cc", "../browser/ui/ash/back_gesture_browsertest.cc", + "../browser/ui/ash/capture_mode_browsertest.cc", "../browser/ui/ash/chrome_new_window_client_browsertest.cc", "../browser/ui/ash/chrome_screenshot_grabber_browsertest.cc", "../browser/ui/ash/clipboard_history_browsertest.cc", @@ -3459,7 +3461,6 @@ "../browser/component_updater/first_party_sets_component_installer_unittest.cc", "../browser/component_updater/floc_component_installer_unittest.cc", "../browser/component_updater/games_component_installer_unittest.cc", - "../browser/component_updater/optimization_hints_component_installer_unittest.cc", "../browser/component_updater/origin_trials_component_installer_unittest.cc", "../browser/component_updater/subresource_filter_component_installer_unittest.cc", "../browser/component_updater/trust_token_key_commitments_component_installer_unittest.cc", @@ -3500,6 +3501,7 @@ "../browser/enterprise/util/affiliation_unittest.cc", "../browser/enterprise/util/managed_browser_utils_unittest.cc", "../browser/external_protocol/external_protocol_handler_unittest.cc", + "../browser/federated_learning/floc_eligibility_unittest.cc", "../browser/federated_learning/floc_event_logger_unittest.cc", "../browser/federated_learning/floc_id_provider_unittest.cc", "../browser/federated_learning/floc_remote_permission_service_unittest.cc",
diff --git a/chrome/test/base/testing_browser_process.cc b/chrome/test/base/testing_browser_process.cc index 38f6dbd..77d3dfb 100644 --- a/chrome/test/base/testing_browser_process.cc +++ b/chrome/test/base/testing_browser_process.cc
@@ -30,7 +30,6 @@ #include "chrome/test/base/testing_browser_process_platform_part.h" #include "components/federated_learning/floc_sorting_lsh_clusters_service.h" #include "components/network_time/network_time_tracker.h" -#include "components/optimization_guide/core/optimization_guide_service.h" #include "components/permissions/permissions_client.h" #include "components/policy/core/browser/browser_policy_connector.h" #include "components/prefs/pref_service.h" @@ -286,11 +285,6 @@ return floc_sorting_lsh_clusters_service_.get(); } -optimization_guide::OptimizationGuideService* -TestingBrowserProcess::optimization_guide_service() { - return optimization_guide_service_.get(); -} - BrowserProcessPlatformPart* TestingBrowserProcess::platform_part() { return platform_part_.get(); } @@ -514,12 +508,6 @@ floc_sorting_lsh_clusters_service_.swap(service); } -void TestingBrowserProcess::SetOptimizationGuideService( - std::unique_ptr<optimization_guide::OptimizationGuideService> - optimization_guide_service) { - optimization_guide_service_.swap(optimization_guide_service); -} - void TestingBrowserProcess::SetRapporServiceImpl( rappor::RapporServiceImpl* rappor_service) { rappor_service_ = rappor_service;
diff --git a/chrome/test/base/testing_browser_process.h b/chrome/test/base/testing_browser_process.h index b17ec0a3..cdd502d1 100644 --- a/chrome/test/base/testing_browser_process.h +++ b/chrome/test/base/testing_browser_process.h
@@ -103,8 +103,6 @@ override; federated_learning::FlocSortingLshClustersService* floc_sorting_lsh_clusters_service() override; - optimization_guide::OptimizationGuideService* optimization_guide_service() - override; BrowserProcessPlatformPart* platform_part() override; extensions::EventRouterForwarder* extension_event_router_forwarder() override; @@ -157,9 +155,6 @@ void SetFlocSortingLshClustersService( std::unique_ptr<federated_learning::FlocSortingLshClustersService> service); - void SetOptimizationGuideService( - std::unique_ptr<optimization_guide::OptimizationGuideService> - optimization_guide_service); void SetSharedURLLoaderFactory( scoped_refptr<network::SharedURLLoaderFactory> shared_url_loader_factory); void SetNotificationUIManager( @@ -211,8 +206,6 @@ subresource_filter_ruleset_service_; std::unique_ptr<federated_learning::FlocSortingLshClustersService> floc_sorting_lsh_clusters_service_; - std::unique_ptr<optimization_guide::OptimizationGuideService> - optimization_guide_service_; std::unique_ptr<network_time::NetworkTimeTracker> network_time_tracker_;
diff --git a/chrome/test/chromedriver/commands.cc b/chrome/test/chromedriver/commands.cc index 8e402b0..277ed1ea 100644 --- a/chrome/test/chromedriver/commands.cc +++ b/chrome/test/chromedriver/commands.cc
@@ -87,7 +87,7 @@ namespace { void OnGetSession(const base::WeakPtr<size_t>& session_remaining_count, - const base::Closure& all_get_session_func, + const base::RepeatingClosure& all_get_session_func, base::ListValue* session_list, const Status& status, std::unique_ptr<base::Value> value, @@ -144,7 +144,7 @@ namespace { void OnSessionQuit(const base::WeakPtr<size_t>& quit_remaining_count, - const base::Closure& all_quit_func, + const base::RepeatingClosure& all_quit_func, const Status& status, std::unique_ptr<base::Value> value, const std::string& session_id, @@ -205,7 +205,7 @@ std::unique_ptr<base::DictionaryValue> params, scoped_refptr<base::SingleThreadTaskRunner> cmd_task_runner, const CommandCallback& callback_on_cmd, - const base::Closure& terminate_on_cmd) { + const base::RepeatingClosure& terminate_on_cmd) { Session* session = GetThreadLocalSession(); if (!session) {
diff --git a/chrome/test/chromedriver/element_commands.h b/chrome/test/chromedriver/element_commands.h index 01cf33137..d74c7a8 100644 --- a/chrome/test/chromedriver/element_commands.h +++ b/chrome/test/chromedriver/element_commands.h
@@ -20,12 +20,12 @@ class Timeout; class WebView; -typedef base::Callback<Status(Session* session, - WebView* web_view, - const std::string&, - const base::DictionaryValue&, - std::unique_ptr<base::Value>*)> - ElementCommand; +using ElementCommand = + base::RepeatingCallback<Status(Session* session, + WebView* web_view, + const std::string&, + const base::DictionaryValue&, + std::unique_ptr<base::Value>*)>; // Execute a command on a specific element. Status ExecuteElementCommand(
diff --git a/chrome/test/chromedriver/server/http_handler.cc b/chrome/test/chromedriver/server/http_handler.cc index 7a16c75..8785448 100644 --- a/chrome/test/chromedriver/server/http_handler.cc +++ b/chrome/test/chromedriver/server/http_handler.cc
@@ -311,12 +311,14 @@ kGet, "session/:sessionId/element/:id/enabled", WrapToCommand("IsElementEnabled", base::BindRepeating(&ExecuteIsElementEnabled))), - CommandMapping(kGet, "session/:sessionId/element/:id/computedlabel", - WrapToCommand("GetComputedLabel", - base::Bind(&ExecuteGetComputedLabel))), - CommandMapping(kGet, "session/:sessionId/element/:id/computedrole", - WrapToCommand("GetComputedRole", - base::Bind(&ExecuteGetComputedRole))), + CommandMapping( + kGet, "session/:sessionId/element/:id/computedlabel", + WrapToCommand("GetComputedLabel", + base::BindRepeating(&ExecuteGetComputedLabel))), + CommandMapping( + kGet, "session/:sessionId/element/:id/computedrole", + WrapToCommand("GetComputedRole", + base::BindRepeating(&ExecuteGetComputedRole))), CommandMapping(kPost, "session/:sessionId/element/:id/click", WrapToCommand("ClickElement", base::BindRepeating(&ExecuteClickElement))), @@ -1014,16 +1016,17 @@ Command HttpHandler::WrapToCommand(const char* name, const WindowCommand& window_command, bool w3c_standard_command) { - return WrapToCommand(name, base::Bind(&ExecuteWindowCommand, window_command), - w3c_standard_command); + return WrapToCommand( + name, base::BindRepeating(&ExecuteWindowCommand, window_command), + w3c_standard_command); } Command HttpHandler::WrapToCommand(const char* name, const ElementCommand& element_command, bool w3c_standard_command) { - return WrapToCommand(name, - base::Bind(&ExecuteElementCommand, element_command), - w3c_standard_command); + return WrapToCommand( + name, base::BindRepeating(&ExecuteElementCommand, element_command), + w3c_standard_command); } void HttpHandler::HandleCommand(
diff --git a/chrome/test/chromedriver/window_commands.h b/chrome/test/chromedriver/window_commands.h index 8299ab75..ae00910 100644 --- a/chrome/test/chromedriver/window_commands.h +++ b/chrome/test/chromedriver/window_commands.h
@@ -22,12 +22,12 @@ class Timeout; class WebView; -typedef base::Callback<Status(Session* session, - WebView* web_view, - const base::DictionaryValue&, - std::unique_ptr<base::Value>*, - Timeout*)> - WindowCommand; +using WindowCommand = + base::RepeatingCallback<Status(Session* session, + WebView* web_view, + const base::DictionaryValue&, + std::unique_ptr<base::Value>*, + Timeout*)>; // Execute a Window Command on the target window. Status ExecuteWindowCommand(const WindowCommand& command,
diff --git a/chrome/test/data/pdf/navigator_test.js b/chrome/test/data/pdf/navigator_test.js index aa9ce60..76cda3f 100644 --- a/chrome/test/data/pdf/navigator_test.js +++ b/chrome/test/data/pdf/navigator_test.js
@@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {eventToPromise} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/_test_resources/webui/test_util.m.js'; import {NavigatorDelegate, PdfNavigator, WindowOpenDisposition} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/navigator.js'; import {OpenPdfParamsParser} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/open_pdf_params_parser.js'; import {PDFScriptingAPI} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/pdf_scripting_api.js'; @@ -56,12 +55,12 @@ * @param {!MockViewportChangedCallback} viewportChangedCallback * @param {!MockNavigatorDelegate} navigatorDelegate */ -function doNavigationUrlTest( +async function doNavigationUrlTest( navigator, url, disposition, expectedResultUrl, viewportChangedCallback, navigatorDelegate) { viewportChangedCallback.reset(); navigatorDelegate.reset(); - navigator.navigate(url, disposition); + await navigator.navigate(url, disposition); chrome.test.assertFalse(viewportChangedCallback.wasCalled); chrome.test.assertEq(expectedResultUrl, navigatorDelegate.url); if (expectedResultUrl === undefined) { @@ -89,7 +88,7 @@ * @param {string} url * @param {(string|undefined)} expectedResultUrl */ -function doNavigationUrlTests(originalUrl, url, expectedResultUrl) { +async function doNavigationUrlTests(originalUrl, url, expectedResultUrl) { const mockWindow = new MockElement(100, 100, null); const mockSizer = new MockSizer(); const mockViewportChangedCallback = new MockViewportChangedCallback(); @@ -105,13 +104,13 @@ const navigator = new PdfNavigator(originalUrl, viewport, paramsParser, navigatorDelegate); - doNavigationUrlTest( + await doNavigationUrlTest( navigator, url, WindowOpenDisposition.CURRENT_TAB, expectedResultUrl, mockViewportChangedCallback, navigatorDelegate); - doNavigationUrlTest( + await doNavigationUrlTest( navigator, url, WindowOpenDisposition.NEW_BACKGROUND_TAB, expectedResultUrl, mockViewportChangedCallback, navigatorDelegate); - doNavigationUrlTest( + await doNavigationUrlTest( navigator, url, WindowOpenDisposition.NEW_WINDOW, expectedResultUrl, mockViewportChangedCallback, navigatorDelegate); } @@ -154,47 +153,36 @@ viewport.setZoom(1); mockCallback.reset(); - let navigatingDone = - eventToPromise('navigate-for-testing', navigator.getEventTarget()); // This should move viewport to page 0. - navigator.navigate(url + '#US', WindowOpenDisposition.CURRENT_TAB); - await navigatingDone; + await navigator.navigate(url + '#US', WindowOpenDisposition.CURRENT_TAB); chrome.test.assertTrue(mockCallback.wasCalled); chrome.test.assertEq(0, viewport.position.x); chrome.test.assertEq(0, viewport.position.y); mockCallback.reset(); navigatorDelegate.reset(); - navigatingDone = - eventToPromise('navigate-for-testing', navigator.getEventTarget()); // This should open "http://xyz.pdf#US" in a new tab. So current tab // viewport should not update and viewport position should remain same. - navigator.navigate(url + '#US', WindowOpenDisposition.NEW_BACKGROUND_TAB); - await navigatingDone; + await navigator.navigate( + url + '#US', WindowOpenDisposition.NEW_BACKGROUND_TAB); chrome.test.assertFalse(mockCallback.wasCalled); chrome.test.assertTrue(navigatorDelegate.navigateInNewTabCalled); chrome.test.assertEq(0, viewport.position.x); chrome.test.assertEq(0, viewport.position.y); mockCallback.reset(); - navigatingDone = - eventToPromise('navigate-for-testing', navigator.getEventTarget()); // This should move viewport to page 2. - navigator.navigate(url + '#UY', WindowOpenDisposition.CURRENT_TAB); - await navigatingDone; + await navigator.navigate(url + '#UY', WindowOpenDisposition.CURRENT_TAB); chrome.test.assertTrue(mockCallback.wasCalled); chrome.test.assertEq(0, viewport.position.x); chrome.test.assertEq(300, viewport.position.y); mockCallback.reset(); navigatorDelegate.reset(); - navigatingDone = - eventToPromise('navigate-for-testing', navigator.getEventTarget()); // #ABC is not a named destination in the page so viewport should not // update, and the viewport position should remain same as testNavigate3's // navigating results, as this link will open in the same tab. - navigator.navigate(url + '#ABC', WindowOpenDisposition.CURRENT_TAB); - await navigatingDone; + await navigator.navigate(url + '#ABC', WindowOpenDisposition.CURRENT_TAB); chrome.test.assertFalse(mockCallback.wasCalled); chrome.test.assertTrue(navigatorDelegate.navigateInCurrentTabCalled); chrome.test.assertEq(0, viewport.position.x); @@ -207,44 +195,45 @@ * a valid scheme, so the navigator must determine the url by following * similar heuristics as Adobe Acrobat Reader. */ - function testNavigateForLinksWithoutScheme() { + async function testNavigateForLinksWithoutScheme() { const url = 'http://www.example.com/subdir/xyz.pdf'; // Sanity check. - doNavigationUrlTests( + await doNavigationUrlTests( url, 'https://www.foo.com/bar.pdf', 'https://www.foo.com/bar.pdf'); // Open relative links. - doNavigationUrlTests( + await doNavigationUrlTests( url, 'foo/bar.pdf', 'http://www.example.com/subdir/foo/bar.pdf'); - doNavigationUrlTests( + await doNavigationUrlTests( url, 'foo.com/bar.pdf', 'http://www.example.com/subdir/foo.com/bar.pdf'); - doNavigationUrlTests( + await doNavigationUrlTests( url, '../www.foo.com/bar.pdf', 'http://www.example.com/www.foo.com/bar.pdf'); // Open an absolute link. - doNavigationUrlTests( + await doNavigationUrlTests( url, '/foodotcom/bar.pdf', 'http://www.example.com/foodotcom/bar.pdf'); // Open a http url without a scheme. - doNavigationUrlTests( + await doNavigationUrlTests( url, 'www.foo.com/bar.pdf', 'http://www.foo.com/bar.pdf'); // Test three dots. - doNavigationUrlTests( + await doNavigationUrlTests( url, '.../bar.pdf', 'http://www.example.com/subdir/.../bar.pdf'); // Test forward slashes. - doNavigationUrlTests(url, '..\\bar.pdf', 'http://www.example.com/bar.pdf'); - doNavigationUrlTests( + await doNavigationUrlTests( + url, '..\\bar.pdf', 'http://www.example.com/bar.pdf'); + await doNavigationUrlTests( url, '.\\bar.pdf', 'http://www.example.com/subdir/bar.pdf'); - doNavigationUrlTests( + await doNavigationUrlTests( url, '\\bar.pdf', 'http://www.example.com/subdir//bar.pdf'); // Regression test for https://crbug.com/569040 - doNavigationUrlTests( + await doNavigationUrlTests( url, 'http://something.else/foo#page=5', 'http://something.else/foo#page=5'); @@ -254,31 +243,31 @@ * Test opening a url in the same tab, in a new tab, and in a new window with * a file:/// url as the current location. */ - function testNavigateFromLocalFile() { + async function testNavigateFromLocalFile() { const url = 'file:///some/path/to/myfile.pdf'; // Open an absolute link. - doNavigationUrlTests( + await doNavigationUrlTests( url, '/foodotcom/bar.pdf', 'file:///foodotcom/bar.pdf'); chrome.test.succeed(); }, - function testNavigateInvalidUrls() { + async function testNavigateInvalidUrls() { const url = 'https://example.com/some-web-document.pdf'; // From non-file: to file: - doNavigationUrlTests(url, 'file:///bar.pdf', undefined); + await doNavigationUrlTests(url, 'file:///bar.pdf', undefined); - doNavigationUrlTests(url, 'chrome://version', undefined); + await doNavigationUrlTests(url, 'chrome://version', undefined); - doNavigationUrlTests( + await doNavigationUrlTests( url, 'javascript:// this is not a document.pdf', undefined); - doNavigationUrlTests( + await doNavigationUrlTests( url, 'this-is-not-a-valid-scheme://path.pdf', undefined); - doNavigationUrlTests(url, '', undefined); + await doNavigationUrlTests(url, '', undefined); chrome.test.succeed(); }
diff --git a/chrome/test/data/pdf/params_parser_test.js b/chrome/test/data/pdf/params_parser_test.js index 3728853..bc2f17f 100644 --- a/chrome/test/data/pdf/params_parser_test.js +++ b/chrome/test/data/pdf/params_parser_test.js
@@ -11,7 +11,7 @@ /** * Test named destinations. */ - function testParamsParser() { + async function testParamsParser() { const paramsParser = new OpenPdfParamsParser(function(destination) { // Set the dummy viewport dimensions for calculating the zoom level for // view destination with 'FitR' type. @@ -20,259 +20,248 @@ if (destination === 'RU') { return Promise.resolve( {messageId: 'getNamedDestination_1', pageNumber: 26}); - } else if (destination === 'US') { + } + if (destination === 'US') { return Promise.resolve( {messageId: 'getNamedDestination_2', pageNumber: 0}); - } else if (destination === 'UY') { + } + if (destination === 'UY') { return Promise.resolve( {messageId: 'getNamedDestination_3', pageNumber: 22}); - } else if (destination === 'DestWithXYZ') { + } + if (destination === 'DestWithXYZ') { return Promise.resolve({ messageId: 'getNamedDestination_4', namedDestinationView: 'XYZ,111,222,1.7', pageNumber: 10 }); - } else if (destination === 'DestWithXYZAtZoom0') { + } + if (destination === 'DestWithXYZAtZoom0') { return Promise.resolve({ messageId: 'getNamedDestination_5', namedDestinationView: 'XYZ,111,222,0', pageNumber: 10 }); - } else if (destination === 'DestWithXYZWithNullParameter') { + } + if (destination === 'DestWithXYZWithNullParameter') { return Promise.resolve({ messageId: 'getNamedDestination_6', namedDestinationView: 'XYZ,111,null,1.7', pageNumber: 13 }); - } else if (destination === 'DestWithFitR') { + } + if (destination === 'DestWithFitR') { return Promise.resolve({ messageId: 'getNamedDestination_7', namedDestinationView: 'FitR,20,100,120,300', pageNumber: 0 }); - } else if (destination === 'DestWithFitRReversedCoordinates') { + } + if (destination === 'DestWithFitRReversedCoordinates') { return Promise.resolve({ messageId: 'getNamedDestination_8', namedDestinationView: 'FitR,120,300,20,100', pageNumber: 0 }); - } else if (destination === 'DestWithFitRWithNull') { + } + if (destination === 'DestWithFitRWithNull') { return Promise.resolve({ messageId: 'getNamedDestination_9', namedDestinationView: 'FitR,null,100,100,300', pageNumber: 0 }); - } else { - return Promise.resolve( - {messageId: 'getNamedDestination_10', pageNumber: -1}); } + return Promise.resolve( + {messageId: 'getNamedDestination_10', pageNumber: -1}); }); const url = 'http://xyz.pdf'; // Checking #nameddest. - paramsParser.getViewportFromUrlParams(`${url}#RU`, function(params) { - chrome.test.assertEq(26, params.page); - }); + let params = await paramsParser.getViewportFromUrlParams(`${url}#RU`); + chrome.test.assertEq(26, params.page); // Checking #nameddest=name. - paramsParser.getViewportFromUrlParams( - `${url}#nameddest=US`, function(params) { - chrome.test.assertEq(0, params.page); - }); + params = await paramsParser.getViewportFromUrlParams(`${url}#nameddest=US`); + chrome.test.assertEq(0, params.page); // Checking #page=pagenum nameddest.The document first page has a pagenum // value of 1. - paramsParser.getViewportFromUrlParams(`${url}#page=6`, function(params) { - chrome.test.assertEq(5, params.page); - }); + params = await paramsParser.getViewportFromUrlParams(`${url}#page=6`); + chrome.test.assertEq(5, params.page); // Checking #zoom=scale. - paramsParser.getViewportFromUrlParams(`${url}#zoom=200`, function(params) { - chrome.test.assertEq(2, params.zoom); - }); + params = await paramsParser.getViewportFromUrlParams(`${url}#zoom=200`); + chrome.test.assertEq(2, params.zoom); // Checking #zoom=scale,left,top. - paramsParser.getViewportFromUrlParams( - `${url}#zoom=200,100,200`, function(params) { - chrome.test.assertEq(2, params.zoom); - chrome.test.assertEq(100, params.position.x); - chrome.test.assertEq(200, params.position.y); - }); + params = + await paramsParser.getViewportFromUrlParams(`${url}#zoom=200,100,200`); + chrome.test.assertEq(2, params.zoom); + chrome.test.assertEq(100, params.position.x); + chrome.test.assertEq(200, params.position.y); // Checking #nameddest=name and zoom=scale. - paramsParser.getViewportFromUrlParams( - `${url}#nameddest=UY&zoom=150`, function(params) { - chrome.test.assertEq(22, params.page); - chrome.test.assertEq(1.5, params.zoom); - }); + params = await paramsParser.getViewportFromUrlParams( + `${url}#nameddest=UY&zoom=150`); + chrome.test.assertEq(22, params.page); + chrome.test.assertEq(1.5, params.zoom); // Checking #page=pagenum and zoom=scale. - paramsParser.getViewportFromUrlParams( - `${url}#page=2&zoom=250`, function(params) { - chrome.test.assertEq(1, params.page); - chrome.test.assertEq(2.5, params.zoom); - }); + params = + await paramsParser.getViewportFromUrlParams(`${url}#page=2&zoom=250`); + chrome.test.assertEq(1, params.page); + chrome.test.assertEq(2.5, params.zoom); // Checking #nameddest=name and zoom=scale,left,top. - paramsParser.getViewportFromUrlParams( - `${url}#nameddest=UY&zoom=150,100,200`, function(params) { - chrome.test.assertEq(22, params.page); - chrome.test.assertEq(1.5, params.zoom); - chrome.test.assertEq(100, params.position.x); - chrome.test.assertEq(200, params.position.y); - }); + params = await paramsParser.getViewportFromUrlParams( + `${url}#nameddest=UY&zoom=150,100,200`); + chrome.test.assertEq(22, params.page); + chrome.test.assertEq(1.5, params.zoom); + chrome.test.assertEq(100, params.position.x); + chrome.test.assertEq(200, params.position.y); // Checking #page=pagenum and zoom=scale,left,top. - paramsParser.getViewportFromUrlParams( - `${url}#page=2&zoom=250,100,200`, function(params) { - chrome.test.assertEq(1, params.page); - chrome.test.assertEq(2.5, params.zoom); - chrome.test.assertEq(100, params.position.x); - chrome.test.assertEq(200, params.position.y); - }); + params = await paramsParser.getViewportFromUrlParams( + `${url}#page=2&zoom=250,100,200`); + chrome.test.assertEq(1, params.page); + chrome.test.assertEq(2.5, params.zoom); + chrome.test.assertEq(100, params.position.x); + chrome.test.assertEq(200, params.position.y); // Checking #nameddest=name with a nameddest that specifies the view fit // type is "XYZ" with multiple valid parameters. - paramsParser.getViewportFromUrlParams( - `${url}#nameddest=DestWithXYZ`, function(params) { - chrome.test.assertEq(10, params.page); - chrome.test.assertEq(1.7, params.zoom); - chrome.test.assertEq(111, params.position.x); - chrome.test.assertEq(222, params.position.y); - chrome.test.assertEq(undefined, params.viewPosition); - }); + params = await paramsParser.getViewportFromUrlParams( + `${url}#nameddest=DestWithXYZ`); + chrome.test.assertEq(10, params.page); + chrome.test.assertEq(1.7, params.zoom); + chrome.test.assertEq(111, params.position.x); + chrome.test.assertEq(222, params.position.y); + chrome.test.assertEq(undefined, params.viewPosition); // Checking #nameddest=name with a nameddest that specifies the view fit // type is "XYZ" with a zoom parameter of 0. - paramsParser.getViewportFromUrlParams( - `${url}#nameddest=DestWithXYZAtZoom0`, function(params) { - chrome.test.assertEq(10, params.page); - chrome.test.assertEq(undefined, params.zoom); - chrome.test.assertEq(111, params.position.x); - chrome.test.assertEq(222, params.position.y); - chrome.test.assertEq(undefined, params.viewPosition); - }); + params = await paramsParser.getViewportFromUrlParams( + `${url}#nameddest=DestWithXYZAtZoom0`); + chrome.test.assertEq(10, params.page); + chrome.test.assertEq(undefined, params.zoom); + chrome.test.assertEq(111, params.position.x); + chrome.test.assertEq(222, params.position.y); + chrome.test.assertEq(undefined, params.viewPosition); // Checking #nameddest=name with a nameddest that specifies the view fit // type is "XYZ" and one of its parameters is null. - paramsParser.getViewportFromUrlParams( - `${url}#nameddest=DestWithXYZWithNullParameter`, function(params) { - chrome.test.assertEq(13, params.page); - chrome.test.assertEq(undefined, params.zoom); - chrome.test.assertEq(undefined, params.position); - chrome.test.assertEq(undefined, params.viewPosition); - }); + params = await paramsParser.getViewportFromUrlParams( + `${url}#nameddest=DestWithXYZWithNullParameter`); + chrome.test.assertEq(13, params.page); + chrome.test.assertEq(undefined, params.zoom); + chrome.test.assertEq(undefined, params.position); + chrome.test.assertEq(undefined, params.viewPosition); // Checking #nameddest=name with a nameddest that specifies the view fit // type is "FitR" with multiple valid parameters. - paramsParser.getViewportFromUrlParams( - `${url}#nameddest=DestWithFitR`, function(params) { - chrome.test.assertEq(0, params.page); - chrome.test.assertEq(2.5, params.zoom); - chrome.test.assertEq(20, params.position.x); - chrome.test.assertEq(100, params.position.y); - chrome.test.assertEq(undefined, params.viewPosition); - }); + params = await paramsParser.getViewportFromUrlParams( + `${url}#nameddest=DestWithFitR`); + chrome.test.assertEq(0, params.page); + chrome.test.assertEq(2.5, params.zoom); + chrome.test.assertEq(20, params.position.x); + chrome.test.assertEq(100, params.position.y); + chrome.test.assertEq(undefined, params.viewPosition); // Checking #nameddest=name with a nameddest that specifies the view fit // type is "FitR" with multiple valid parameters. - paramsParser.getViewportFromUrlParams( - `${url}#nameddest=DestWithFitRReversedCoordinates`, function(params) { - chrome.test.assertEq(0, params.page); - chrome.test.assertEq(2.5, params.zoom); - chrome.test.assertEq(20, params.position.x); - chrome.test.assertEq(100, params.position.y); - chrome.test.assertEq(undefined, params.viewPosition); - }); + params = await paramsParser.getViewportFromUrlParams( + `${url}#nameddest=DestWithFitRReversedCoordinates`); + chrome.test.assertEq(0, params.page); + chrome.test.assertEq(2.5, params.zoom); + chrome.test.assertEq(20, params.position.x); + chrome.test.assertEq(100, params.position.y); + chrome.test.assertEq(undefined, params.viewPosition); // Checking #nameddest=name with a nameddest that specifies the view fit // type is "FitR" with one NULL parameters. - paramsParser.getViewportFromUrlParams( - `${url}#nameddest=DestWithFitRWithNull`, function(params) { - chrome.test.assertEq(0, params.page); - chrome.test.assertEq(undefined, params.zoom); - chrome.test.assertEq(undefined, params.position); - chrome.test.assertEq(undefined, params.viewPosition); - }); + params = await paramsParser.getViewportFromUrlParams( + `${url}#nameddest=DestWithFitRWithNull`); + chrome.test.assertEq(0, params.page); + chrome.test.assertEq(undefined, params.zoom); + chrome.test.assertEq(undefined, params.position); + chrome.test.assertEq(undefined, params.viewPosition); // Checking #view=Fit. - paramsParser.getViewportFromUrlParams(`${url}#view=Fit`, function(params) { - chrome.test.assertEq(FittingType.FIT_TO_PAGE, params.view); - chrome.test.assertEq(undefined, params.viewPosition); - }); - // Checking #view=FitH. - paramsParser.getViewportFromUrlParams(`${url}#view=FitH`, function(params) { - chrome.test.assertEq(FittingType.FIT_TO_WIDTH, params.view); - chrome.test.assertEq(undefined, params.viewPosition); - }); - // Checking #view=FitH,[int position]. - paramsParser.getViewportFromUrlParams( - `${url}#view=FitH,789`, function(params) { - chrome.test.assertEq(FittingType.FIT_TO_WIDTH, params.view); - chrome.test.assertEq(789, params.viewPosition); - }); - // Checking #view=FitH,[float position]. - paramsParser.getViewportFromUrlParams( - `${url}#view=FitH,7.89`, function(params) { - chrome.test.assertEq(FittingType.FIT_TO_WIDTH, params.view); - chrome.test.assertEq(7.89, params.viewPosition); - }); - // Checking #view=FitV. - paramsParser.getViewportFromUrlParams(`${url}#view=FitV`, function(params) { - chrome.test.assertEq(FittingType.FIT_TO_HEIGHT, params.view); - chrome.test.assertEq(undefined, params.viewPosition); - }); - // Checking #view=FitV,[int position]. - paramsParser.getViewportFromUrlParams( - `${url}#view=FitV,123`, function(params) { - chrome.test.assertEq(FittingType.FIT_TO_HEIGHT, params.view); - chrome.test.assertEq(123, params.viewPosition); - }); - // Checking #view=FitV,[float position]. - paramsParser.getViewportFromUrlParams( - `${url}#view=FitV,1.23`, function(params) { - chrome.test.assertEq(FittingType.FIT_TO_HEIGHT, params.view); - chrome.test.assertEq(1.23, params.viewPosition); - }); - // Checking #view=[wrong parameter]. - paramsParser.getViewportFromUrlParams(`${url}#view=FitW`, function(params) { - chrome.test.assertEq(undefined, params.view); - chrome.test.assertEq(undefined, params.viewPosition); - }); - // Checking #view=[wrong parameter],[position]. - paramsParser.getViewportFromUrlParams( - `${url}#view=FitW,555`, function(params) { - chrome.test.assertEq(undefined, params.view); - chrome.test.assertEq(undefined, params.viewPosition); - }); - // Checking #view=[wrong parameter]. - paramsParser.getViewportFromUrlParams(`${url}#view=XYZ`, function(params) { - chrome.test.assertEq(undefined, params.view); - chrome.test.assertEq(undefined, params.viewPosition); - }); - // Checking #view=[wrong parameter],[position]. - paramsParser.getViewportFromUrlParams( - `${url}#view=XYZ,111,222,1.7`, function(params) { - chrome.test.assertEq(undefined, params.zoom); - chrome.test.assertEq(undefined, params.position); - chrome.test.assertEq(undefined, params.view); - chrome.test.assertEq(undefined, params.viewPosition); - }); - // Checking #view=[wrong parameter]. - paramsParser.getViewportFromUrlParams(`${url}#view=FitR`, function(params) { - chrome.test.assertEq(undefined, params.view); - chrome.test.assertEq(undefined, params.viewPosition); - }); - // Checking #view=[wrong parameter],[position]. - paramsParser.getViewportFromUrlParams( - `${url}#view=FitR,20,100,120,300`, function(params) { - chrome.test.assertEq(undefined, params.zoom); - chrome.test.assertEq(undefined, params.position); - chrome.test.assertEq(undefined, params.view); - chrome.test.assertEq(undefined, params.viewPosition); - }); + params = await paramsParser.getViewportFromUrlParams(`${url}#view=Fit`); + chrome.test.assertEq(FittingType.FIT_TO_PAGE, params.view); + chrome.test.assertEq(undefined, params.viewPosition); + // Checking #view=FitH. + params = await paramsParser.getViewportFromUrlParams(`${url}#view=FitH`); + chrome.test.assertEq(FittingType.FIT_TO_WIDTH, params.view); + chrome.test.assertEq(undefined, params.viewPosition); + + // Checking #view=FitH,[int position]. + params = + await paramsParser.getViewportFromUrlParams(`${url}#view=FitH,789`); + chrome.test.assertEq(FittingType.FIT_TO_WIDTH, params.view); + chrome.test.assertEq(789, params.viewPosition); + + // Checking #view=FitH,[float position]. + params = + await paramsParser.getViewportFromUrlParams(`${url}#view=FitH,7.89`); + chrome.test.assertEq(FittingType.FIT_TO_WIDTH, params.view); + chrome.test.assertEq(7.89, params.viewPosition); + + // Checking #view=FitV. + params = await paramsParser.getViewportFromUrlParams(`${url}#view=FitV`); + chrome.test.assertEq(FittingType.FIT_TO_HEIGHT, params.view); + chrome.test.assertEq(undefined, params.viewPosition); + + // Checking #view=FitV,[int position]. + params = + await paramsParser.getViewportFromUrlParams(`${url}#view=FitV,123`); + chrome.test.assertEq(FittingType.FIT_TO_HEIGHT, params.view); + chrome.test.assertEq(123, params.viewPosition); + + // Checking #view=FitV,[float position]. + params = + await paramsParser.getViewportFromUrlParams(`${url}#view=FitV,1.23`); + chrome.test.assertEq(FittingType.FIT_TO_HEIGHT, params.view); + chrome.test.assertEq(1.23, params.viewPosition); + + // Checking #view=[wrong parameter]. + params = await paramsParser.getViewportFromUrlParams(`${url}#view=FitW`); + chrome.test.assertEq(undefined, params.view); + chrome.test.assertEq(undefined, params.viewPosition); + + // Checking #view=[wrong parameter],[position]. + params = + await paramsParser.getViewportFromUrlParams(`${url}#view=FitW,555`); + chrome.test.assertEq(undefined, params.view); + chrome.test.assertEq(undefined, params.viewPosition); + + // Checking #view=[wrong parameter]. + params = await paramsParser.getViewportFromUrlParams(`${url}#view=XYZ`); + chrome.test.assertEq(undefined, params.view); + chrome.test.assertEq(undefined, params.viewPosition); + + // Checking #view=[wrong parameter],[position]. + params = await paramsParser.getViewportFromUrlParams( + `${url}#view=XYZ,111,222,1.7`); + chrome.test.assertEq(undefined, params.zoom); + chrome.test.assertEq(undefined, params.position); + chrome.test.assertEq(undefined, params.view); + chrome.test.assertEq(undefined, params.viewPosition); + + // Checking #view=[wrong parameter]. + params = await paramsParser.getViewportFromUrlParams(`${url}#view=FitR`); + chrome.test.assertEq(undefined, params.view); + chrome.test.assertEq(undefined, params.viewPosition); + + // Checking #view=[wrong parameter],[position]. + params = await paramsParser.getViewportFromUrlParams( + `${url}#view=FitR,20,100,120,300`); + chrome.test.assertEq(undefined, params.zoom); + chrome.test.assertEq(undefined, params.position); + chrome.test.assertEq(undefined, params.view); + chrome.test.assertEq(undefined, params.viewPosition); // Checking #toolbar=0 to disable the toolbar. chrome.test.assertFalse(paramsParser.shouldShowToolbar(`${url}#toolbar=0`));
diff --git a/chrome/test/data/pdf/viewer_properties_dialog_test.js b/chrome/test/data/pdf/viewer_properties_dialog_test.js index 4cd2adc..b175a8a 100644 --- a/chrome/test/data/pdf/viewer_properties_dialog_test.js +++ b/chrome/test/data/pdf/viewer_properties_dialog_test.js
@@ -60,7 +60,7 @@ ['modified', '-'], ['application', 'Your Preferred Text Editor'], ['pdf-producer', 'fixup_pdf_template.py'], - ['pdf-version', '-'], + ['pdf-version', '1.7'], ['page-count', '-'], ['page-size', '-'], ['fast-web-view', '-'],
diff --git a/chrome/test/data/web_apps/web_app_integration_browsertest_cases.csv b/chrome/test/data/web_apps/web_app_integration_browsertest_cases.csv index 7893e73..162e049 100644 --- a/chrome/test/data/web_apps/web_app_integration_browsertest_cases.csv +++ b/chrome/test/data/web_apps/web_app_integration_browsertest_cases.csv
@@ -2,6 +2,7 @@ navigate_not_installable,assert_install_icon_not_shown, navigate_installable,assert_installable,install_omnibox_or_menu, navigate_browser_in_scope,assert_launch_icon_shown, assert_install_icon_not_shown, navigate_installable, install_create_shortcut_tabbed, set_open_in_window_internal, launch_internal, assert_window_created, -navigate_installable_site_a, assert_install_icon_shown, install_omnibox_or_menu, assert_window_created, launch_internal_site_a, close_pwa, assert_no_crash, -navigate_installable,install_omnibox_or_menu,launch_internal, uninstall_from_menu,navigate_browser_in_scope, assert_install_icon_shown,assert_launch_icon_not_shown, +navigate_installable_site_a, assert_install_icon_shown, install_omnibox_or_menu, assert_window_created, launch_internal, close_pwa, assert_no_crash, +add_policy_app_internal_tabbed, remove_policy_app, list_apps_internal, assert_app_not_in_list, +Linux, Mac, Win | navigate_installable,install_omnibox_or_menu,launch_internal, uninstall_from_menu,navigate_browser_in_scope, assert_install_icon_shown,assert_launch_icon_not_shown, ChromeOS | navigate_installable,install_omnibox_or_menu,launch_internal, uninstall_internal,navigate_browser_in_scope, assert_install_icon_shown,assert_launch_icon_not_shown,
diff --git a/chrome/test/data/webui/chromeos/diagnostics/BUILD.gn b/chrome/test/data/webui/chromeos/diagnostics/BUILD.gn index 5fe7cee..792a3c8 100644 --- a/chrome/test/data/webui/chromeos/diagnostics/BUILD.gn +++ b/chrome/test/data/webui/chromeos/diagnostics/BUILD.gn
@@ -18,6 +18,7 @@ ":diagnostics_app_test", ":diagnostics_app_unified_test", ":diagnostics_test_utils", + ":diagnostics_utils_test", ":fake_method_provider_test", ":fake_observables_test", ":fake_system_data_provider_test", @@ -105,6 +106,13 @@ ] } +js_library("diagnostics_utils_test") { + deps = [ + "../..:chai_assert", + "//chromeos/components/diagnostics_ui/resources:diagnostics_utils", + ] +} + js_library("fake_method_provider_test") { deps = [ "../..:chai_assert", @@ -141,6 +149,7 @@ "../..:chai_assert", "../..:test_util.m", "//chromeos/components/diagnostics_ui/resources:diagnostics_types", + "//chromeos/components/diagnostics_ui/resources:diagnostics_utils", "//chromeos/components/diagnostics_ui/resources:fake_data", "//chromeos/components/diagnostics_ui/resources:fake_system_data_provider", "//chromeos/components/diagnostics_ui/resources:memory_card",
diff --git a/chrome/test/data/webui/chromeos/diagnostics/diagnostics_app_unified_test.js b/chrome/test/data/webui/chromeos/diagnostics/diagnostics_app_unified_test.js index ba335ad46..be6c0b93 100644 --- a/chrome/test/data/webui/chromeos/diagnostics/diagnostics_app_unified_test.js +++ b/chrome/test/data/webui/chromeos/diagnostics/diagnostics_app_unified_test.js
@@ -9,6 +9,7 @@ import {cpuCardTestSuite} from './cpu_card_test.js'; import {dataPointTestSuite} from './data_point_test.js'; import {appTestSuite} from './diagnostics_app_test.js'; +import {diagnosticsUtilsTestSuite} from './diagnostics_utils_test.js'; import {fakeMethodResolverTestSuite} from './fake_method_provider_test.js'; import {fakeObservablesTestSuite} from './fake_observables_test.js'; import {fakeSystemDataProviderTestSuite} from './fake_system_data_provider_test.js'; @@ -35,6 +36,7 @@ runSuite('BatteryStatusCard', batteryStatusCardTestSuite); runSuite('CpuCard', cpuCardTestSuite); runSuite('DataPoint', dataPointTestSuite); +runSuite('DiagnosticsUtils', diagnosticsUtilsTestSuite); runSuite('FakeMethodProvider', fakeMethodResolverTestSuite); runSuite('FakeMojoInterface', fakeMojoProviderTestSuite); runSuite('FakeObservables', fakeObservablesTestSuite);
diff --git a/chrome/test/data/webui/chromeos/diagnostics/diagnostics_browsertest.js b/chrome/test/data/webui/chromeos/diagnostics/diagnostics_browsertest.js index 37b948e..082e5832 100644 --- a/chrome/test/data/webui/chromeos/diagnostics/diagnostics_browsertest.js +++ b/chrome/test/data/webui/chromeos/diagnostics/diagnostics_browsertest.js
@@ -44,11 +44,11 @@ // You must register all suites in unified test here as well for consistency, // although technically is not necessary. const debug_suites_list = [ - 'App', 'BatteryStatusCard', 'CpuCard', 'DataPoint', 'FakeMethodProvider', - 'FakeMojoInterface', 'FakeObservables', 'FakeSystemDataProvider', - 'FakeSystemRoutineContoller', 'MemoryCard', 'OverviewCard', 'PercentBarChart', - 'RealtimeCpuChart', 'RoutineListExecutor', 'RoutineResultEntry', - 'RoutineResultList', 'RoutineSection', 'TextBadge' + 'App', 'BatteryStatusCard', 'CpuCard', 'DataPoint', 'DiagnosticsUtils', + 'FakeMethodProvider', 'FakeMojoInterface', 'FakeObservables', + 'FakeSystemDataProvider', 'FakeSystemRoutineContoller', 'MemoryCard', + 'OverviewCard', 'PercentBarChart', 'RealtimeCpuChart', 'RoutineListExecutor', + 'RoutineResultEntry', 'RoutineResultList', 'RoutineSection', 'TextBadge' ]; TEST_F('DiagnosticsApp', 'BrowserTest', function() {
diff --git a/chrome/test/data/webui/chromeos/diagnostics/diagnostics_utils_test.js b/chrome/test/data/webui/chromeos/diagnostics/diagnostics_utils_test.js new file mode 100644 index 0000000..1fe8f3d --- /dev/null +++ b/chrome/test/data/webui/chromeos/diagnostics/diagnostics_utils_test.js
@@ -0,0 +1,21 @@ +// 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. + +import {convertKibToGibDecimalString} from 'chrome://diagnostics/diagnostics_utils.js'; +import {assertEquals} from '../../chai_assert.js'; + +export function diagnosticsUtilsTestSuite() { + test('ProperlyConvertsKibToGib', () => { + assertEquals('0', convertKibToGibDecimalString(0, 0)); + assertEquals('0.00', convertKibToGibDecimalString(0, 2)); + assertEquals('0.000000', convertKibToGibDecimalString(0, 6)); + assertEquals('0', convertKibToGibDecimalString(1, 0)); + assertEquals('5.72', convertKibToGibDecimalString(6000000, 2)); + assertEquals('5.722046', convertKibToGibDecimalString(6000000, 6)); + assertEquals('1.00', convertKibToGibDecimalString(2 ** 20, 2)); + assertEquals('1.00', convertKibToGibDecimalString(2 ** 20 + 1, 2)); + assertEquals('1.00', convertKibToGibDecimalString(2 ** 20 - 1, 2)); + assertEquals('0.999999', convertKibToGibDecimalString(2 ** 20 - 1, 6)); + }); +} \ No newline at end of file
diff --git a/chrome/test/data/webui/chromeos/diagnostics/memory_card_test.js b/chrome/test/data/webui/chromeos/diagnostics/memory_card_test.js index b055f92f..dea8153 100644 --- a/chrome/test/data/webui/chromeos/diagnostics/memory_card_test.js +++ b/chrome/test/data/webui/chromeos/diagnostics/memory_card_test.js
@@ -5,9 +5,11 @@ import 'chrome://diagnostics/memory_card.js'; import {MemoryUsage} from 'chrome://diagnostics/diagnostics_types.js'; +import {convertKibToGibDecimalString} from 'chrome://diagnostics/diagnostics_utils.js'; import {fakeMemoryUsage} from 'chrome://diagnostics/fake_data.js'; import {FakeSystemDataProvider} from 'chrome://diagnostics/fake_system_data_provider.js'; import {setSystemDataProviderForTesting} from 'chrome://diagnostics/mojo_interface_provider.js'; +import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {assertEquals, assertFalse, assertTrue} from '../../chai_assert.js'; import {flushTasks, isChildVisible} from '../../test_util.m.js'; @@ -91,8 +93,14 @@ const barChart = dx_utils.getPercentBarChartElement(memoryElement); const memInUse = fakeMemoryUsage[0].totalMemoryKib - fakeMemoryUsage[0].availableMemoryKib; + const expectedChartHeader = loadTimeData.getStringF( + 'memoryAvailable', + convertKibToGibDecimalString( + fakeMemoryUsage[0].availableMemoryKib, 2), + convertKibToGibDecimalString(fakeMemoryUsage[0].totalMemoryKib, 2)); assertEquals(fakeMemoryUsage[0].totalMemoryKib, barChart.max); assertEquals(memInUse, barChart.value); + dx_utils.assertTextContains(barChart.header, expectedChartHeader); // Verify the routine section is in the card. assertTrue(!!getRoutineSection());
diff --git a/chrome/test/data/webui/chromeos/diagnostics/percent_bar_chart_test.js b/chrome/test/data/webui/chromeos/diagnostics/percent_bar_chart_test.js index 9f2fb35..1fc2971 100644 --- a/chrome/test/data/webui/chromeos/diagnostics/percent_bar_chart_test.js +++ b/chrome/test/data/webui/chromeos/diagnostics/percent_bar_chart_test.js
@@ -58,10 +58,6 @@ assertEquals( header, percentBarChartElement.$$('#chartName').textContent.trim()); - dx_utils.assertElementContainsText( - /** @type {!HTMLElement} */ ( - percentBarChartElement.$$('#percentageLabel')), - `${percent}`); assertFalse(!!percentBarChartElement.$$('#headerIcon')); });
diff --git a/chrome/test/data/webui/engagement/site_engagement_browsertest.js b/chrome/test/data/webui/engagement/site_engagement_browsertest.js index cee7d37..0b1fe30f 100644 --- a/chrome/test/data/webui/engagement/site_engagement_browsertest.js +++ b/chrome/test/data/webui/engagement/site_engagement_browsertest.js
@@ -8,7 +8,7 @@ var EXAMPLE_URL_1 = 'http://example.com/'; var EXAMPLE_URL_2 = 'http://shmlexample.com/'; -GEN('#include "chrome/browser/engagement/site_engagement_service.h"'); +GEN('#include "components/site_engagement/content/site_engagement_service.h"'); GEN('#include "chrome/browser/engagement/site_engagement_service_factory.h"'); GEN('#include "chrome/browser/profiles/profile.h"'); GEN('#include "chrome/browser/ui/browser.h"');
diff --git a/chrome/test/data/webui/new_tab_page/middle_slot_promo_test.js b/chrome/test/data/webui/new_tab_page/middle_slot_promo_test.js index b939632..99708c5 100644 --- a/chrome/test/data/webui/new_tab_page/middle_slot_promo_test.js +++ b/chrome/test/data/webui/new_tab_page/middle_slot_promo_test.js
@@ -3,7 +3,7 @@ // found in the LICENSE file. import 'chrome://new-tab-page/lazy_load.js'; -import {BrowserProxy, PromoBrowserCommandProxy} from 'chrome://new-tab-page/new_tab_page.js'; +import {$$, BrowserProxy, PromoBrowserCommandProxy} from 'chrome://new-tab-page/new_tab_page.js'; import {createTestProxy} from 'chrome://test/new_tab_page/test_support.js'; import {TestBrowserProxy} from 'chrome://test/test_browser_proxy.m.js'; import {eventToPromise, flushTasks} from 'chrome://test/test_util.m.js'; @@ -19,7 +19,11 @@ promoBrowserCommand.mojom.CommandHandlerRemote); }); - async function createMiddleSlotPromo(canShowPromo = true) { + /** + * @param {boolean} canShowPromo + * @return {!Element} + */ + async function createMiddleSlotPromo(canShowPromo) { const testProxy = BrowserProxy.getInstance(); testProxy.handler.setResultFor('getPromo', Promise.resolve({ promo: { @@ -79,43 +83,57 @@ return middleSlotPromo; } - [true, false].forEach(canShowPromo => { - test(`render ${canShowPromo}`, async () => { - const middleSlotPromo = await createMiddleSlotPromo(canShowPromo); - assertEquals(!canShowPromo, middleSlotPromo.hasAttribute('hidden')); - const parts = middleSlotPromo.$.container.children; - assertEquals(6, parts.length); - const [image, imageWithLink, imageWithCommand, text, link, command] = - parts; + /** + * @param {boolean} hasContent + * @param {!Element} middleSlotPromo + * @private + */ + function assertHasContent(hasContent, middleSlotPromo) { + assertEquals(hasContent, !!$$(middleSlotPromo, '#container')); + } - assertEquals('https://image', image.autoSrc); + test(`render canShowPromo=true`, async () => { + const canShowPromo = true; + const middleSlotPromo = await createMiddleSlotPromo(canShowPromo); + assertHasContent(canShowPromo, middleSlotPromo); + const parts = $$(middleSlotPromo, '#container').children; + assertEquals(6, parts.length); + const [image, imageWithLink, imageWithCommand, text, link, command] = parts; - assertEquals('https://link/', imageWithLink.href); - assertEquals('https://image', imageWithLink.children[0].autoSrc); + assertEquals('https://image', image.autoSrc); - assertEquals('', imageWithCommand.href); - assertEquals('https://image', imageWithCommand.children[0].autoSrc); + assertEquals('https://link/', imageWithLink.href); + assertEquals('https://image', imageWithLink.children[0].autoSrc); - assertEquals('text', text.innerText); - assertEquals('red', text.style.color); + assertEquals('', imageWithCommand.href); + assertEquals('https://image', imageWithCommand.children[0].autoSrc); - assertEquals('https://link/', link.href); - assertEquals('link', link.innerText); - assertEquals('green', link.style.color); + assertEquals('text', text.innerText); + assertEquals('red', text.style.color); - assertEquals('', command.href); - assertEquals('command', command.text); - assertEquals('blue', command.style.color); - }); + assertEquals('https://link/', link.href); + assertEquals('link', link.innerText); + assertEquals('green', link.style.color); + + assertEquals('', command.href); + assertEquals('command', command.text); + assertEquals('blue', command.style.color); + }); + + test(`render canShowPromo=false`, async () => { + const canShowPromo = false; + const middleSlotPromo = await createMiddleSlotPromo(canShowPromo); + assertHasContent(canShowPromo, middleSlotPromo); }); test('clicking on command', async () => { - const middleSlotPromo = await createMiddleSlotPromo(); - assertFalse(middleSlotPromo.hasAttribute('hidden')); + const canShowPromo = true; + const middleSlotPromo = await createMiddleSlotPromo(canShowPromo); + assertHasContent(canShowPromo, middleSlotPromo); const testProxy = PromoBrowserCommandProxy.getInstance(); testProxy.handler.setResultFor('executeCommand', Promise.resolve()); - const imageWithCommand = middleSlotPromo.$.container.children[2]; - const command = middleSlotPromo.$.container.children[5]; + const imageWithCommand = $$(middleSlotPromo, '#container').children[2]; + const command = $$(middleSlotPromo, '#container').children[5]; await Promise.all([imageWithCommand, command].map(async el => { testProxy.handler.reset(); el.click(); @@ -138,20 +156,24 @@ })); }); - test('promo remains hidden if there is no data', async () => { - const promoBrowserCommandTestProxy = PromoBrowserCommandProxy.getInstance(); - const testProxy = BrowserProxy.getInstance(); - testProxy.handler.setResultFor('getPromo', Promise.resolve({promo: null})); - const middleSlotPromo = document.createElement('ntp-middle-slot-promo'); - document.body.appendChild(middleSlotPromo); - const loaded = - eventToPromise('ntp-middle-slot-promo-loaded', document.body); - assertEquals( - 0, - promoBrowserCommandTestProxy.handler.getCallCount( - 'canShowPromoWithCommand')); - assertEquals(0, testProxy.handler.getCallCount('onPromoRendered')); - assertTrue(middleSlotPromo.hasAttribute('hidden')); - await loaded; + [null, + {middleSlotParts: []}, + {middleSlotParts: [{break: {}}]}, + ].forEach((promo, i) => { + test(`promo remains hidden if there is no data ${i}`, async () => { + const promoBrowserCommandTestProxy = + PromoBrowserCommandProxy.getInstance(); + const testProxy = BrowserProxy.getInstance(); + testProxy.handler.setResultFor('getPromo', Promise.resolve({promo})); + const middleSlotPromo = document.createElement('ntp-middle-slot-promo'); + document.body.appendChild(middleSlotPromo); + await flushTasks(); + assertEquals( + 0, + promoBrowserCommandTestProxy.handler.getCallCount( + 'canShowPromoWithCommand')); + assertEquals(0, testProxy.handler.getCallCount('onPromoRendered')); + assertHasContent(false, middleSlotPromo); + }); }); });
diff --git a/chrome/test/data/webui/resources/list_property_update_behavior_tests.js b/chrome/test/data/webui/resources/list_property_update_behavior_tests.js index 8b571cd..a11be43 100644 --- a/chrome/test/data/webui/resources/list_property_update_behavior_tests.js +++ b/chrome/test/data/webui/resources/list_property_update_behavior_tests.js
@@ -4,7 +4,7 @@ /** @fileoverview Suite of tests for the ListPropertyUpdateBehavior. */ -// #import {ListPropertyUpdateBehavior} from 'chrome://resources/js/list_property_update_behavior.m.js'; +// #import {ListPropertyUpdateBehavior, updateListProperty} from 'chrome://resources/js/list_property_update_behavior.m.js'; // #import {Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; suite('ListPropertyUpdateBehavior', function() { @@ -76,7 +76,7 @@ updateComplexArray(newArray) { if (this.updateList( 'complexArray', x => x.letter, newArray, - true /* uidBasedUpdate */)) { + true /* identityBasedUpdate */)) { return {topArrayChanged: true, wordsArrayChanged: false}; } @@ -305,4 +305,48 @@ assertTrue(testElement.updateList('complexArray', x => x.letter, newArray)); assertDeepEquals(['apricot'], testElement.complexArray[0].words); }); + + test('updateListProperty() function triggers notifySplices()', () => { + // Ensure that the array is updated when an element is removed from the + // end. + let elementRemoved = testElement.complexArray.slice(0, 2); + updateListProperty( + testElement, 'complexArray', obj => obj, elementRemoved, true); + assertComplexArrayEquals(testElement.complexArray, elementRemoved); + + // Ensure that the array is updated when an element is removed from the + // beginning. + testElement.resetComplexArray(); + elementRemoved = testElement.complexArray.slice(1); + updateListProperty( + testElement, 'complexArray', obj => obj, elementRemoved, true); + assertComplexArrayEquals(testElement.complexArray, elementRemoved); + + // Ensure that the array is updated when an element is added to the end. + testElement.resetComplexArray(); + let elementAdded = testElement.complexArray.slice(); + elementAdded.push({letter: 'd', words: ['door', 'dice']}); + updateListProperty( + testElement, 'complexArray', obj => obj, elementAdded, true); + assertComplexArrayEquals(testElement.complexArray, elementAdded); + + // Ensure that the array is updated when an element is added to the + // beginning. + testElement.resetComplexArray(); + elementAdded = [{letter: 'A', words: ['Alphabet']}]; + elementAdded.push(...testElement.complexArray); + updateListProperty( + testElement, 'complexArray', obj => obj, elementAdded, true); + assertComplexArrayEquals(testElement.complexArray, elementAdded); + + // Ensure that the array is updated when the entire array is different. + testElement.resetComplexArray(); + const newArray = [ + {letter: 'w', words: ['water', 'woods']}, + {letter: 'x', words: ['xylophone']}, {letter: 'y', words: ['yo-yo']}, + {letter: 'z', words: ['zebra', 'zephyr']} + ]; + updateListProperty(testElement, 'complexArray', obj => obj, newArray, true); + assertComplexArrayEquals(testElement.complexArray, newArray); + }); });
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 ee2bcb0..a11485d 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
@@ -492,6 +492,43 @@ page.$.help.click(); return aboutBrowserProxy.whenCalled('openOsHelpPage'); }); + + test('LaunchDiagnostics', async function() { + loadTimeData.overrideValues({ + isDeepLinkingEnabled: true, + diagnosticsAppEnabled: true, + }); + + await initNewPage(); + Polymer.dom.flush(); + + assertTrue(!!page.$.diagnostics); + page.$.diagnostics.click(); + await aboutBrowserProxy.whenCalled('openDiagnostics'); + }); + + test('Deep link to diagnostics', async () => { + loadTimeData.overrideValues({ + isDeepLinkingEnabled: true, + diagnosticsAppEnabled: true, + }); + + await initNewPage(); + Polymer.dom.flush(); + + const params = new URLSearchParams; + params.append('settingId', '1707'); // Setting::kDiagnostics + settings.Router.getInstance().navigateTo( + settings.routes.ABOUT_ABOUT, params); + + Polymer.dom.flush(); + + const deepLinkElement = page.$$('#diagnostics').$$('cr-icon-button'); + await test_util.waitAfterNextRender(deepLinkElement); + assertEquals( + deepLinkElement, getDeepActiveElement(), + 'Diagnostics should be focused for settingId=1707.'); + }); }); suite('DetailedBuildInfoTest', function() {
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js index d7cfe5d..fff7095 100644 --- a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js +++ b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js
@@ -845,8 +845,7 @@ } }; -// TODO(https://crbug.com/1121139): Re-enable flaky test. -TEST_F('OSSettingsFingerprintListTest', 'DISABLED_AllJsTests', () => { +TEST_F('OSSettingsFingerprintListTest', 'AllJsTests', () => { mocha.run(); });
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 23481067..3cac13f 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
@@ -23,6 +23,7 @@ 'getEndOfLifeInfo', 'launchReleaseNotes', 'openOsHelpPage', + 'openDiagnostics', 'refreshTPMFirmwareUpdateStatus', 'setChannel', ]); @@ -191,6 +192,11 @@ } /** @override */ + openDiagnostics() { + this.methodCalled('openDiagnostics'); + } + + /** @override */ launchReleaseNotes() { this.methodCalled('launchReleaseNotes'); }
diff --git a/chrome/test/data/webui/settings/test_about_page_browser_proxy.js b/chrome/test/data/webui/settings/test_about_page_browser_proxy.js index d5c6bc9..98bf474 100644 --- a/chrome/test/data/webui/settings/test_about_page_browser_proxy.js +++ b/chrome/test/data/webui/settings/test_about_page_browser_proxy.js
@@ -71,6 +71,9 @@ openOsHelpPage() {} /** @override */ + openDiagnostics() {} + + /** @override */ requestUpdate() {} /** @override */
diff --git a/chrome/test/data/webui/signin/profile_type_choice_test.js b/chrome/test/data/webui/signin/profile_type_choice_test.js index b07f1a7..4ac3b62 100644 --- a/chrome/test/data/webui/signin/profile_type_choice_test.js +++ b/chrome/test/data/webui/signin/profile_type_choice_test.js
@@ -4,14 +4,23 @@ import 'chrome://profile-picker/lazy_load.js'; +import {ManageProfilesBrowserProxyImpl} from 'chrome://profile-picker/profile_picker.js'; + import {assertTrue} from '../chai_assert.js'; import {isChildVisible} from '../test_util.m.js'; +import {TestManageProfilesBrowserProxy} from './test_manage_profiles_browser_proxy.js'; + suite('ProfileTypeChoiceTest', function() { /** @type {!ProfileTypeChoiceElement} */ let choice; + /** @type {!TestManageProfilesBrowserProxy} */ + let browserProxy; + setup(function() { + browserProxy = new TestManageProfilesBrowserProxy(); + ManageProfilesBrowserProxyImpl.instance_ = browserProxy; document.body.innerHTML = ''; choice = /** @type {!ProfileTypeChoiceElement} */ ( document.createElement('profile-type-choice')); @@ -29,4 +38,8 @@ test('NotNowButton', function() { assertTrue(isChildVisible(choice, '#notNowButton')); }); + + test('VerifySignInPromoImpressionRecorded', function() { + return browserProxy.whenCalled('recordSignInPromoImpression'); + }); });
diff --git a/chrome/test/data/webui/signin/test_manage_profiles_browser_proxy.js b/chrome/test/data/webui/signin/test_manage_profiles_browser_proxy.js index 2296e8da..95e4e6f6 100644 --- a/chrome/test/data/webui/signin/test_manage_profiles_browser_proxy.js +++ b/chrome/test/data/webui/signin/test_manage_profiles_browser_proxy.js
@@ -22,6 +22,7 @@ 'loadSignInProfileCreationFlow', 'createProfile', 'setProfileName', + 'recordSignInPromoImpression', ]); /** @type {!AutogeneratedThemeColorInfo} */ @@ -116,4 +117,9 @@ setProfileName(profilePath, profileName) { this.methodCalled('setProfileName', [profilePath, profileName]); } + + /** @override */ + recordSignInPromoImpression() { + this.methodCalled('recordSignInPromoImpression'); + } }
diff --git a/chrome/test/data/webui/tab_search/infinite_list_test.js b/chrome/test/data/webui/tab_search/infinite_list_test.js index f924aed..e704262 100644 --- a/chrome/test/data/webui/tab_search/infinite_list_test.js +++ b/chrome/test/data/webui/tab_search/infinite_list_test.js
@@ -87,6 +87,7 @@ test('ScrollHeight', async () => { const tabItems = sampleTabItems(sampleSiteNames()); await setupTest(tabItems); + await waitAfterNextRender(infiniteList); assertEquals(0, infiniteList.scrollTop);
diff --git a/chrome/updater/app/app_install.cc b/chrome/updater/app/app_install.cc index 4938e63..f777e564 100644 --- a/chrome/updater/app/app_install.cc +++ b/chrome/updater/app/app_install.cc
@@ -143,14 +143,18 @@ } void AppInstall::RegisterUpdater() { - // TODO(crbug.com/1128060): We should update the updater's registration with - // the new version, brand code, etc. For now, fake it. - RegistrationResponse result; - result.status_code = 0; - RegisterUpdaterDone(result); + RegistrationRequest registration_request; + registration_request.app_id = kUpdaterAppId; + registration_request.version = base::Version(UPDATER_VERSION_STRING); + + scoped_refptr<UpdateService> update_service = CreateUpdateService(); + update_service->RegisterApp( + registration_request, + base::BindOnce(&AppInstall::RegisterUpdaterDone, this, update_service)); } -void AppInstall::RegisterUpdaterDone(const RegistrationResponse& response) { +void AppInstall::RegisterUpdaterDone(scoped_refptr<UpdateService>, + const RegistrationResponse& response) { VLOG(1) << "Updater registration complete, code = " << response.status_code; MaybeInstallApp(); }
diff --git a/chrome/updater/app/app_install.h b/chrome/updater/app/app_install.h index b10fe7f2..9fbe1129 100644 --- a/chrome/updater/app/app_install.h +++ b/chrome/updater/app/app_install.h
@@ -68,7 +68,8 @@ void RegisterUpdater(); - void RegisterUpdaterDone(const RegistrationResponse& response); + void RegisterUpdaterDone(scoped_refptr<UpdateService>, + const RegistrationResponse& response); // Handles the --tag and --app-id command line arguments, and triggers // installing of the corresponding application if either argument is present.
diff --git a/chrome/updater/win/update_service_proxy.cc b/chrome/updater/win/update_service_proxy.cc index daaf9042..efaad0f7 100644 --- a/chrome/updater/win/update_service_proxy.cc +++ b/chrome/updater/win/update_service_proxy.cc
@@ -25,6 +25,7 @@ #include "base/version.h" #include "base/win/scoped_bstr.h" #include "chrome/updater/app/server/win/updater_idl.h" +#include "chrome/updater/registration_data.h" #include "chrome/updater/util.h" namespace updater { @@ -302,7 +303,9 @@ const RegistrationRequest& request, base::OnceCallback<void(const RegistrationResponse&)> callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - NOTREACHED(); + // TODO(crbug.com/1163524): Implement registration API. + base::SequencedTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(std::move(callback), RegistrationResponse(0))); } void UpdateServiceProxy::UpdateAll(StateChangeCallback state_update,
diff --git a/chromecast/browser/webview/client/webview.cc b/chromecast/browser/webview/client/webview.cc index 3141d3b..1ee134bb 100644 --- a/chromecast/browser/webview/client/webview.cc +++ b/chromecast/browser/webview/client/webview.cc
@@ -39,6 +39,7 @@ constexpr char kPositionCommand[] = "position"; constexpr char kKeyCommand[] = "key"; constexpr char kFillCommand[] = "fill"; +constexpr char kSetInsetsCommand[] = "set_insets"; void FrameCallback(void* data, wl_callback* callback, uint32_t time) { WebviewClient* webview_client = static_cast<WebviewClient*>(data); @@ -356,6 +357,8 @@ SendKeyRequest(tokens); else if (tokens[1] == kFillCommand) HandleFillSurfaceColor(tokens); + else if (tokens[1] == kSetInsetsCommand) + HandleSetInsets(tokens); std::cout << "Enter command: "; std::cout.flush(); @@ -499,6 +502,40 @@ surfaces_[id]->buffer->sk_surface->getCanvas()->clear(color); } +void WebviewClient::HandleSetInsets(const std::vector<std::string>& tokens) { + int id, top, left, bottom, right; + if (tokens.size() != 6 || !base::StringToInt(tokens[0], &id) || + !base::StringToInt(tokens[2], &top) || + !base::StringToInt(tokens[3], &left) || + !base::StringToInt(tokens[4], &bottom) || + !base::StringToInt(tokens[5], &right)) { + LOG(ERROR) << "Usage: [ID] " << kSetInsetsCommand + << " [top] [left] [bottom] [right]"; + return; + } + + if (surfaces_.find(id) == surfaces_.end()) { + LOG(ERROR) << "Failed to find surface " << id; + return; + } + + Webview* webview = Webview::FromSurface(surfaces_[id].get()); + if (!webview) { + LOG(ERROR) << "Failed to find webview " << id; + return; + } + + WebviewRequest request; + request.mutable_set_insets()->set_top(top); + request.mutable_set_insets()->set_left(left); + request.mutable_set_insets()->set_bottom(bottom); + request.mutable_set_insets()->set_right(right); + if (!webview->client->Write(request)) { + LOG(ERROR) << "SetInsets failed"; + return; + } +} + void WebviewClient::SendResizeRequest(Webview* webview, int width, int height) { WebviewRequest resize_request; resize_request.mutable_resize()->set_width(width);
diff --git a/chromecast/browser/webview/client/webview.h b/chromecast/browser/webview/client/webview.h index e2f1733f..229e723 100644 --- a/chromecast/browser/webview/client/webview.h +++ b/chromecast/browser/webview/client/webview.h
@@ -99,6 +99,7 @@ void HandleResizeRequest(const std::vector<std::string>& tokens); void HandleFillSurfaceColor(const std::vector<std::string>& tokens); void SendKeyRequest(const std::vector<std::string>& tokens); + void HandleSetInsets(const std::vector<std::string>& tokens); void SendTouchInput(const Webview* webview, int x,
diff --git a/chromeos/chromeos_strings.grd b/chromeos/chromeos_strings.grd index 1d93b180..27ec272 100644 --- a/chromeos/chromeos_strings.grd +++ b/chromeos/chromeos_strings.grd
@@ -662,9 +662,6 @@ <message name="IDS_DIAGNOSTICS_SESSION_LOG_LABEL" desc="The label for the button that opens the session log for the diagnostics app."> Save Session log </message> - <message name="IDS_DIAGNOSTICS_USED_MEMORY_LABEL" desc="The label for the progress bar that displays the amount of used memory on a users' device." translateable="false"> - Used memory - </message> <message name="IDS_DIAGNOSTICS_BATTERY_CHIP_TEXT" desc="The text for a battery's full charge capacity represented in milliamp hours."> <ph name="CHARGE_VALUE">$1<ex>6000</ex></ph>mAh Battery </message> @@ -782,8 +779,8 @@ <message name="IDS_DIAGNOSTICS_CPU_SPEED_TEXT" desc="The text that displays the CPU speed. GHz is an SI unit for gigahertz."> <ph name="CURRENT">$1<ex>1.6</ex></ph>GHz / <ph name="MAX">$2<ex>1.9</ex></ph>GHz </message> - <message name="IDS_DIAGNOSTICS_TOTAL_MEMORY_LABEL" desc="The label for the total amount of memory on a device." translateable="false"> - Total Memory + <message name="IDS_DIAGNOSTICS_MEMORY_AVAILABLE_TEXT" desc="The text that displays the amount of memory available on a users' device."> + <ph name="AVAILABLE_MEMORY">$1<ex>13.12</ex></ph> GB of <ph name="TOTAL_MEMORY">$2<ex>16</ex></ph> GB available. </message> <!-- Quick Answers --> @@ -1022,6 +1019,9 @@ <message name="IDS_NETWORK_DIAGNOSTICS_CAPTIVE_PORTAL" desc="Label for Network diagnostics `Captive Portal` test. This test ensures that the device's internet connection is not gated by a captive portal"> Captive Portal </message> + <message name="IDS_NETWORK_DIAGNOSTICS_VIDEO_CONFERENCING" desc="Label for Network diagnostics `Video Conferencing` test. This test ensures that the device can communicate with Google's video conferencing servers"> + Video Conferencing + </message> <message name="IDS_NETWORK_DIAGNOSTICS_PASSED" desc="Label shown when a Network diagnostics routine passed"> Passed </message> @@ -1139,6 +1139,15 @@ <message name="IDS_NETWORK_DIAGNOSTICS_CAPTIVE_PORTAL_PROBLEM_NO_INTERNET" desc="Error message shown when no network portal is detected, but there is no internet connection"> No internet </message> + <message name="IDS_NETWORK_DIAGNOSTICS_VIDEO_CONFERENCING_PROBLEM_UPD_FAILURE" desc="Error message shown when there are failed UDP requests to the video conferencing servers"> + UDP request failures + </message> + <message name="IDS_NETWORK_DIAGNOSTICS_VIDEO_CONFERENCING_PROBLEM_TCP_FAILURE" desc="Error message shown when there are failed TCP requests to the video conferencing servers"> + TCP request failures + </message> + <message name="IDS_NETWORK_DIAGNOSTICS_VIDEO_CONFERENCING_PROBLEM_MEDIA_FAILURE" desc="Error message shown when a connection cannot be established to the video conferencing media servers"> + Unable to connect to media servers + </message> </messages> </release> </grit>
diff --git a/chromeos/chromeos_strings_grd/IDS_DIAGNOSTICS_MEMORY_AVAILABLE_TEXT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_DIAGNOSTICS_MEMORY_AVAILABLE_TEXT.png.sha1 new file mode 100644 index 0000000..17842aa1 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_DIAGNOSTICS_MEMORY_AVAILABLE_TEXT.png.sha1
@@ -0,0 +1 @@ +d9ac09bb04b99206d904d1aa223aff0cdda9e55e \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_NETWORK_DIAGNOSTICS_VIDEO_CONFERENCING.png.sha1 b/chromeos/chromeos_strings_grd/IDS_NETWORK_DIAGNOSTICS_VIDEO_CONFERENCING.png.sha1 new file mode 100644 index 0000000..2ee1633 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_NETWORK_DIAGNOSTICS_VIDEO_CONFERENCING.png.sha1
@@ -0,0 +1 @@ +0fb960b6498b3a45e33a8d7940e5e99b41fbfdb5 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_NETWORK_DIAGNOSTICS_VIDEO_CONFERENCING_PROBLEM_MEDIA_FAILURE.png.sha1 b/chromeos/chromeos_strings_grd/IDS_NETWORK_DIAGNOSTICS_VIDEO_CONFERENCING_PROBLEM_MEDIA_FAILURE.png.sha1 new file mode 100644 index 0000000..f8bcca3 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_NETWORK_DIAGNOSTICS_VIDEO_CONFERENCING_PROBLEM_MEDIA_FAILURE.png.sha1
@@ -0,0 +1 @@ +82498a3f69a603a3414828a24ba45cb542aa7f36 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_NETWORK_DIAGNOSTICS_VIDEO_CONFERENCING_PROBLEM_TCP_FAILURE.png.sha1 b/chromeos/chromeos_strings_grd/IDS_NETWORK_DIAGNOSTICS_VIDEO_CONFERENCING_PROBLEM_TCP_FAILURE.png.sha1 new file mode 100644 index 0000000..1ea61c5 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_NETWORK_DIAGNOSTICS_VIDEO_CONFERENCING_PROBLEM_TCP_FAILURE.png.sha1
@@ -0,0 +1 @@ +180bb8dce3224095afc380d498e84a7c1585b5da \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_NETWORK_DIAGNOSTICS_VIDEO_CONFERENCING_PROBLEM_UPD_FAILURE.png.sha1 b/chromeos/chromeos_strings_grd/IDS_NETWORK_DIAGNOSTICS_VIDEO_CONFERENCING_PROBLEM_UPD_FAILURE.png.sha1 new file mode 100644 index 0000000..59d335a --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_NETWORK_DIAGNOSTICS_VIDEO_CONFERENCING_PROBLEM_UPD_FAILURE.png.sha1
@@ -0,0 +1 @@ +d3d4d620e9bf27e0ff76251d812bd293efbe4ab4 \ No newline at end of file
diff --git a/chromeos/components/camera_app_ui/camera_app_ui.cc b/chromeos/components/camera_app_ui/camera_app_ui.cc index 3de983eb..10efcde 100644 --- a/chromeos/components/camera_app_ui/camera_app_ui.cc +++ b/chromeos/components/camera_app_ui/camera_app_ui.cc
@@ -223,6 +223,8 @@ delegate_->SetLaunchDirectory(); + window()->SetProperty(ash::kMinimizeOnBackKey, false); + // Set up the data source. content::WebUIDataSource::Add(browser_context, CreateCameraAppUIHTMLSource(delegate_.get()));
diff --git a/chromeos/components/camera_app_ui/resources/js/main.js b/chromeos/components/camera_app_ui/resources/js/main.js index f371da3..97b6f89 100644 --- a/chromeos/components/camera_app_ui/resources/js/main.js +++ b/chromeos/components/camera_app_ui/resources/js/main.js
@@ -363,6 +363,8 @@ bgOps = createFakeBackgroundOps(); } + state.set(state.State.INTENT, bgOps.getIntent() !== null); + browserProxy.setupUnloadListener(() => { // For SWA, we don't cancel the unhandled intent here since there is no // guarantee that asynchronous calls in unload listener can be executed
diff --git a/chromeos/components/camera_app_ui/resources/js/nav.js b/chromeos/components/camera_app_ui/resources/js/nav.js index 0de44a48..858a8d1 100644 --- a/chromeos/components/camera_app_ui/resources/js/nav.js +++ b/chromeos/components/camera_app_ui/resources/js/nav.js
@@ -179,7 +179,16 @@ const key = util.getShortcutIdentifier(event); switch (key) { case 'BrowserBack': - windowController.minimize(); + // Only works for non-intent instance. + if (!state.get(state.State.INTENT)) { + windowController.minimize(); + } + break; + case 'Alt--': + // Prevent intent window from minimizing. + if (state.get(state.State.INTENT)) { + event.preventDefault(); + } break; case 'Ctrl-=': case 'Ctrl--':
diff --git a/chromeos/components/camera_app_ui/resources/js/state.js b/chromeos/components/camera_app_ui/resources/js/state.js index ed8792f..18dd48d0 100644 --- a/chromeos/components/camera_app_ui/resources/js/state.js +++ b/chromeos/components/camera_app_ui/resources/js/state.js
@@ -26,6 +26,7 @@ HAS_BACK_CAMERA: 'has-back-camera', HAS_EXTERNAL_SCREEN: 'has-external-screen', HAS_FRONT_CAMERA: 'has-front-camera', + INTENT: 'intent', MAX_WND: 'max-wnd', MIC: 'mic', MIRROR: 'mirror',
diff --git a/chromeos/components/diagnostics_ui/diagnostics_ui.cc b/chromeos/components/diagnostics_ui/diagnostics_ui.cc index 0f7e3ffb..164dfe5 100644 --- a/chromeos/components/diagnostics_ui/diagnostics_ui.cc +++ b/chromeos/components/diagnostics_ui/diagnostics_ui.cc
@@ -70,6 +70,7 @@ {"hideReportText", IDS_DIAGNOSTICS_HIDE_REPORT_TEXT}, {"learnMore", IDS_DIANOSTICS_LEARN_MORE_LABEL}, {"learnMoreShort", IDS_DIAGNOSTICS_LEARN_MORE_LABEL_SHORT}, + {"memoryAvailable", IDS_DIAGNOSTICS_MEMORY_AVAILABLE_TEXT}, {"memoryRoutineText", IDS_DIAGNOSTICS_MEMORY_ROUTINE_TEXT}, {"memoryTitle", IDS_DIAGNOSTICS_MEMORY_TITLE}, {"percentageLabel", IDS_DIAGNOSTICS_PERCENTAGE_LABEL}, @@ -92,8 +93,6 @@ {"testRunningBadgeText", IDS_DIAGNOSTICS_TEST_RUNNING_BADGE_TEXT}, {"testSuccess", IDS_DIAGNOSTICS_TEST_SUCCESS_TEXT}, {"testSucceededBadgeText", IDS_DIAGNOSTICS_TEST_SUCCESS_BADGE_TEXT}, - {"totalMemory", IDS_DIAGNOSTICS_TOTAL_MEMORY_LABEL}, - {"usedMemory", IDS_DIAGNOSTICS_USED_MEMORY_LABEL}, }; for (const auto& str : kLocalizedStrings) { html_source->AddLocalizedString(str.name, str.id);
diff --git a/chromeos/components/diagnostics_ui/resources/BUILD.gn b/chromeos/components/diagnostics_ui/resources/BUILD.gn index 7d3626f..357c7e6 100644 --- a/chromeos/components/diagnostics_ui/resources/BUILD.gn +++ b/chromeos/components/diagnostics_ui/resources/BUILD.gn
@@ -16,6 +16,7 @@ ":diagnostics_app", ":diagnostics_card", ":diagnostics_types", + ":diagnostics_utils", ":fake_data", ":fake_method_resolver", ":fake_observables", @@ -89,6 +90,9 @@ js_library("diagnostics_types") { } +js_library("diagnostics_utils") { +} + js_library("fake_data") { deps = [ ":diagnostics_types" ] } @@ -112,9 +116,11 @@ js_library("memory_card") { deps = [ ":data_point", + ":diagnostics_utils", ":mojo_interface_provider", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//ui/webui/resources/js:i18n_behavior.m", + "//ui/webui/resources/js:load_time_data.m", ] }
diff --git a/chromeos/components/diagnostics_ui/resources/battery_status_card.html b/chromeos/components/diagnostics_ui/resources/battery_status_card.html index a5e5ced..8a95de24 100644 --- a/chromeos/components/diagnostics_ui/resources/battery_status_card.html +++ b/chromeos/components/diagnostics_ui/resources/battery_status_card.html
@@ -2,12 +2,12 @@ <diagnostics-card> <div id="cardTitle" slot="title">[[i18n('batteryTitle')]]</div> - <div id="batteryStatusChipInfo" slot="chip"> + <div id="batteryStatusChipInfo" slot="chip" class="diagnostics-chip"> [[getDesignedFullCharge_(batteryHealth_.chargeFullDesignMilliampHours)]] </div> <!-- TODO(michaelcheco): Replace placeholder icon. --> <iron-icon slot="icon" icon="cr:add"></iron-icon> - <percent-bar-chart slot="left-panel" header="[[i18n('remainingCharge')]]" + <percent-bar-chart slot="left-panel" header="[[powerTimeString_]]" value="[[batteryChargeStatus_.chargeNowMilliampHours]]" max="[[batteryHealth_.chargeFullNowMilliampHours]]"> </percent-bar-chart>
diff --git a/chromeos/components/diagnostics_ui/resources/cpu_card.html b/chromeos/components/diagnostics_ui/resources/cpu_card.html index 7ef34b24..90045aa 100644 --- a/chromeos/components/diagnostics_ui/resources/cpu_card.html +++ b/chromeos/components/diagnostics_ui/resources/cpu_card.html
@@ -2,7 +2,9 @@ <diagnostics-card> <div id="cardTitle" slot="title">[[i18n('cpuTitle')]]</div> - <div id="cpuChipInfo" slot="chip">[[cpuChipInfo_]]</div> + <div id="cpuChipInfo" slot="chip" class="diagnostics-chip"> + [[cpuChipInfo_]] + </div> <!-- TODO(michaelcheco): Replace placeholder icon. --> <iron-icon slot="icon" icon="cr:add"></iron-icon> <!-- TODO(michaelcheco): Add i18n string for percent number format -->
diff --git a/chromeos/components/diagnostics_ui/resources/diagnostics_app_resources.grd b/chromeos/components/diagnostics_ui/resources/diagnostics_app_resources.grd index 6399743..1d3bc0b 100644 --- a/chromeos/components/diagnostics_ui/resources/diagnostics_app_resources.grd +++ b/chromeos/components/diagnostics_ui/resources/diagnostics_app_resources.grd
@@ -41,6 +41,7 @@ <include name="IDR_DIAGNOSTICS_SYSTEM_ROUTINE_CONTROLLER_MOJO_LITE_JS" file="${root_gen_dir}/chromeos/components/diagnostics_ui/mojom/system_routine_controller.mojom-lite.js" use_base_dir="false" type="BINDATA" /> <include name="IDR_DIAGNOSTICS_TEXT_BADGE_JS" file="${root_gen_dir}/chromeos/components/diagnostics_ui/resources/text_badge.js" use_base_dir="false" type="BINDATA"/> <include name="IDR_DIAGNOSTICS_TYPES_JS" file="diagnostics_types.js" type="BINDATA"/> + <include name="IDR_DIAGNOSTICS_UTILS_JS" file="diagnostics_utils.js" type="BINDATA"/> <include name="IDR_D3_SRC_D3_MIN_JS" file="../../../../third_party/d3/src/d3.min.js" type="BINDATA" /> </includes> </release>
diff --git a/chromeos/components/diagnostics_ui/resources/diagnostics_card.html b/chromeos/components/diagnostics_ui/resources/diagnostics_card.html index 22939d5..560b7f2 100644 --- a/chromeos/components/diagnostics_ui/resources/diagnostics_card.html +++ b/chromeos/components/diagnostics_ui/resources/diagnostics_card.html
@@ -1,21 +1,20 @@ <style include="diagnostics-shared diagnostics-fonts"> - ::slotted([slot=chip]) { - background-color: var(--google-grey-100); - border-radius: 16px; - color: var(--diagnostics-overview-text-color); - padding: 4px 8px; - } ::slotted([slot=icon]) { - background-color: rgba(var(--google-blue-refresh-500-rgb), .12); + background-color: var(--google-blue-50); border-radius: 50%; color: var(--google-blue-600); + height: 26px; left: 5px; + margin-left: 20px; + margin-right: 28px; padding: 2px; position: relative; + width: 20px; } ::slotted([slot=left-panel]) { flex: 1; + margin-bottom: 16px; } .card-container { @@ -25,7 +24,6 @@ } .card-header { - @apply --diagnostics-default-font; display: flex; justify-content: space-between; min-height: 25px; @@ -44,10 +42,6 @@ padding-inline: var(--data-point-container-padding); } - .icon { - width: 10%; - } - .routine-container { @apply --diagnostics-default-font; } @@ -61,11 +55,7 @@ .top-section { border-bottom: 1px solid var(--diagnostics-border-color); display: flex; - margin-bottom: 6px; - margin-top: 12px; - padding-bottom: 12px; - padding-inline-end: 15px; - padding-inline-start: 15px; + margin-top: 16px; } </style> <div class="card-container"> @@ -75,9 +65,7 @@ </div> <div class="card-wrapper"> <div class="top-section"> - <div class="icon"> - <slot name="icon"></slot> - </div> + <slot name="icon"></slot> <slot name="left-panel"></slot> </div> <div id="body" class="data-points" hidden$="[[hideDataPoints]]">
diff --git a/chromeos/components/diagnostics_ui/resources/diagnostics_fonts_css.html b/chromeos/components/diagnostics_ui/resources/diagnostics_fonts_css.html index 739a375..9614c6f 100644 --- a/chromeos/components/diagnostics_ui/resources/diagnostics_fonts_css.html +++ b/chromeos/components/diagnostics_ui/resources/diagnostics_fonts_css.html
@@ -4,6 +4,7 @@ --diagnostics-default-font-family: "Google Sans", Roboto, sans-serif; --diagnostics-header-font-family: Roboto, sans-serif; --diagnostics-data-point-font-family: Roboto, sans-serif; + --diagnostics-overview-font-family: Roboto, sans-serif; --diagnostics-default-font-size: 14px; --diagnostics-header-font-size: 22px; @@ -18,11 +19,11 @@ --diagnostics-header-font-weight: 600; --diagnostics-data-point-title-font-weight: 400; --diagnostics-data-point-subtitle-font-weight: 450; - --diagnostics-overview-font-weight: 500; + --diagnostics-overview-font-weight: 400; --diagnostics-default-text-color: var(--google-grey-900); --diagnostics-header-text-color: var(--google-grey-900); - --diagnostics-overview-text-color: var(--google-grey-600); + --diagnostics-overview-text-color: var(--google-grey-900); --diagnostics-data-point-title-color: var(--google-grey-900); --diagnostics-data-point-subtitle-color: var(--google-grey-700); @@ -48,7 +49,7 @@ font-weight: var(--diagnostics-data-point-subtitle-font-weight); }; --diagnostics-overview-font: { - font-family: var(--diagnostics-default-font-family); + font-family: var(--diagnostics-overview-font-family); font-size: var(--diagnostics-overview-font-size); font-weight: var(--diagnostics-overview-font-weight); };
diff --git a/chromeos/components/diagnostics_ui/resources/diagnostics_shared_css.html b/chromeos/components/diagnostics_ui/resources/diagnostics_shared_css.html index 7db368eb..18354ee 100644 --- a/chromeos/components/diagnostics_ui/resources/diagnostics_shared_css.html +++ b/chromeos/components/diagnostics_ui/resources/diagnostics_shared_css.html
@@ -21,6 +21,15 @@ margin-left: 20px; } + .diagnostics-chip { + @apply --diagnostics-overview-font; + background-color: var(--google-grey-200); + border-radius: 16px; + color: var(--diagnostics-overview-text-color); + height: 20px; + padding: 4px 8px 0; + } + .divider { border-left: 1px solid var(--google-grey-200); height: 32px;
diff --git a/chromeos/components/diagnostics_ui/resources/diagnostics_utils.js b/chromeos/components/diagnostics_ui/resources/diagnostics_utils.js new file mode 100644 index 0000000..f299951 --- /dev/null +++ b/chromeos/components/diagnostics_ui/resources/diagnostics_utils.js
@@ -0,0 +1,14 @@ +// 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. + +/** + * Converts a KiB storage value to GiB and returns a fixed-point string + * to the desired number of decimal places. + * @param {number} value + * @param {number} numDecimalPlaces + * @return {string} + */ +export function convertKibToGibDecimalString(value, numDecimalPlaces) { + return (value / 2 ** 20).toFixed(numDecimalPlaces); +}
diff --git a/chromeos/components/diagnostics_ui/resources/memory_card.html b/chromeos/components/diagnostics_ui/resources/memory_card.html index 7e5cb38..0dbd498 100644 --- a/chromeos/components/diagnostics_ui/resources/memory_card.html +++ b/chromeos/components/diagnostics_ui/resources/memory_card.html
@@ -4,7 +4,8 @@ <diagnostics-card hide-data-points="true"> <div id="cardTitle" slot="title">[[i18n('memoryTitle')]]</div> <iron-icon slot="icon" icon="cr:add"></iron-icon> - <percent-bar-chart slot="left-panel" header="[[i18n('usedMemory')]]" + <percent-bar-chart slot="left-panel" + header="[[getAvailableMemory_(memoryUsage_)]]" value="[[getTotalUsedMemory_(memoryUsage_)]]" max="[[memoryUsage_.totalMemoryKib]]"> </percent-bar-chart>
diff --git a/chromeos/components/diagnostics_ui/resources/memory_card.js b/chromeos/components/diagnostics_ui/resources/memory_card.js index 5dd2d70..b74353e 100644 --- a/chromeos/components/diagnostics_ui/resources/memory_card.js +++ b/chromeos/components/diagnostics_ui/resources/memory_card.js
@@ -12,9 +12,11 @@ import './strings.m.js'; import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js'; +import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {MemoryUsage, RoutineType, SystemDataProviderInterface} from './diagnostics_types.js' +import {convertKibToGibDecimalString} from './diagnostics_utils.js'; import {getSystemDataProvider} from './mojo_interface_provider.js'; /** @@ -103,5 +105,19 @@ */ getTotalUsedMemory_(memoryUsage) { return memoryUsage.totalMemoryKib - memoryUsage.availableMemoryKib; - } + }, + + /** + * Calculates total available memory from MemoryUsage object. + * @return {string} + * @protected + */ + getAvailableMemory_() { + // Note: The storage value is converted to GiB but we still display "GB" to + // the user since this is the convention memory manufacturers use. + return loadTimeData.getStringF( + 'memoryAvailable', + convertKibToGibDecimalString(this.memoryUsage_.availableMemoryKib, 2), + convertKibToGibDecimalString(this.memoryUsage_.totalMemoryKib, 2)); + }, });
diff --git a/chromeos/components/diagnostics_ui/resources/overview_card.html b/chromeos/components/diagnostics_ui/resources/overview_card.html index 8e510740..08ae8b0 100644 --- a/chromeos/components/diagnostics_ui/resources/overview_card.html +++ b/chromeos/components/diagnostics_ui/resources/overview_card.html
@@ -1,25 +1,17 @@ <style include="diagnostics-shared diagnostics-fonts"> #marketingName { - font-weight: var(--diagnostics-overview-font-weight); - margin-right: 5px; + font-weight: 500; + margin-right: 4px; } #overviewCardContainer { display: flex; + height: 48px; justify-content: center; } - - .overview-chip { - @apply --diagnostics-overview-font; - background-color: var(--google-grey-100); - border-radius: 16px; - color: var(--diagnostics-overview-text-color); - margin-right: 15px; - padding: 10px; - } </style> <div id="overviewCardContainer"> - <div class="overview-chip"> + <div class="diagnostics-chip"> <span id="marketingName">[[systemInfo_.marketingName]]</span> <span id="deviceInfo">[[deviceInfo_]]</span> </div>
diff --git a/chromeos/components/diagnostics_ui/resources/percent_bar_chart.html b/chromeos/components/diagnostics_ui/resources/percent_bar_chart.html index 1d78d87..dbc6f6fb 100644 --- a/chromeos/components/diagnostics_ui/resources/percent_bar_chart.html +++ b/chromeos/components/diagnostics_ui/resources/percent_bar_chart.html
@@ -1,7 +1,11 @@ <style include="diagnostics-shared diagnostics-fonts"> - #barChartContainer > label { + #chartName { @apply --diagnostics-chart-title-font; - color: var(--diagnostics-overview-text-color); + color: var(--google-grey-700); + font-family: Roboto; + font-size: 13px; + line-height: 20px; + margin-top: 8px; } #headerIcon { @@ -18,28 +22,20 @@ width: 85%; --paper-progress-active-color: var(--google-blue-500); --paper-progress-container-color: var(--google-blue-100); - --paper-progress-height: 8px; + --paper-progress-height: 4px; } - - #percentageLabel { - @apply --diagnostics-chart-label-font; - display: inline; - padding-left: 5px; - } - </style> <div id="barChartContainer"> + <div class="body"> + <paper-progress id="barChart" + value="[[getAdjustedValue_(value, max)]]" max="[[max]]"> + </paper-progress> + </div> <label id="chartName"> <template is="dom-if" if="[[headerIcon.length]]"> <iron-icon id="headerIcon" icon="[[headerIcon]]"></iron-icon> </template> [[header]] </label> - <div class="body"> - <paper-progress id="barChart" - value="[[getAdjustedValue_(value, max)]]" max="[[max]]"> - </paper-progress> - <label id="percentageLabel">[[computePercentage_(value, max)]]</label> - </div> </div>
diff --git a/chromeos/components/diagnostics_ui/resources/percent_bar_chart.js b/chromeos/components/diagnostics_ui/resources/percent_bar_chart.js index c3a7ea8..26d5137 100644 --- a/chromeos/components/diagnostics_ui/resources/percent_bar_chart.js +++ b/chromeos/components/diagnostics_ui/resources/percent_bar_chart.js
@@ -48,19 +48,6 @@ }, /** - * Returns the percentage of the current bar chart, rounded to the nearest - * whole number. - * @param {number} currentValue - * @param {number} maxValue - * @return {string} i18n string for the percentage value. - * @private - */ - computePercentage_(currentValue, maxValue) { - return loadTimeData.getStringF( - 'percentageLabel', Math.round(100 * currentValue / maxValue)); - }, - - /** * Get adjusted value clamped to max value. paper-progress breaks for a while * when value is set higher than max in certain cases (e.g. due to fetching of * max being resolved later).
diff --git a/chromeos/components/network_ui/network_diagnostics_resource_provider.cc b/chromeos/components/network_ui/network_diagnostics_resource_provider.cc index 9ed87316..9e93b7d 100644 --- a/chromeos/components/network_ui/network_diagnostics_resource_provider.cc +++ b/chromeos/components/network_ui/network_diagnostics_resource_provider.cc
@@ -32,6 +32,8 @@ {"NetworkDiagnosticsHttpsFirewall", IDS_NETWORK_DIAGNOSTICS_HTTPS_FIREWALL}, {"NetworkDiagnosticsHttpsLatency", IDS_NETWORK_DIAGNOSTICS_HTTPS_LATENCY}, {"NetworkDiagnosticsCaptivePortal", IDS_NETWORK_DIAGNOSTICS_CAPTIVE_PORTAL}, + {"NetworkDiagnosticsVideoConferencing", + IDS_NETWORK_DIAGNOSTICS_VIDEO_CONFERENCING}, {"NetworkDiagnosticsPassed", IDS_NETWORK_DIAGNOSTICS_PASSED}, {"NetworkDiagnosticsFailed", IDS_NETWORK_DIAGNOSTICS_FAILED}, {"NetworkDiagnosticsNotRun", IDS_NETWORK_DIAGNOSTICS_NOT_RUN}, @@ -99,6 +101,12 @@ IDS_NETWORK_DIAGNOSTICS_CAPTIVE_PORTAL_PROBLEM_PROXY_AUTH_REQUIRED}, {"CaptivePortalProblem_NoInternet", IDS_NETWORK_DIAGNOSTICS_CAPTIVE_PORTAL_PROBLEM_NO_INTERNET}, + {"VideoConferencingProblem_UdpFailure", + IDS_NETWORK_DIAGNOSTICS_VIDEO_CONFERENCING_PROBLEM_UPD_FAILURE}, + {"VideoConferencingProblem_TcpFailure", + IDS_NETWORK_DIAGNOSTICS_VIDEO_CONFERENCING_PROBLEM_TCP_FAILURE}, + {"VideoConferencingProblem_MediaFailure", + IDS_NETWORK_DIAGNOSTICS_VIDEO_CONFERENCING_PROBLEM_MEDIA_FAILURE}, }; struct WebUiResource { @@ -131,6 +139,7 @@ {"NetworkDiagnosticsGatewayGroup", "Gateway"}, {"NetworkDiagnosticsFirewallGroup", "Firewall"}, {"NetworkDiagnosticsDnsGroup", "DNS"}, + {"NetworkDiagnosticsGoogleServicesGroup", "Google Services"}, }; } // namespace
diff --git a/chromeos/components/scanning/resources/scan_preview.html b/chromeos/components/scanning/resources/scan_preview.html index 23ccf2f..bee743e 100644 --- a/chromeos/components/scanning/resources/scan_preview.html +++ b/chromeos/components/scanning/resources/scan_preview.html
@@ -52,7 +52,7 @@ } .preview-item { - border: 1px solid var(--google-grey-200); + border: 1px solid var(--google-grey-300); border-radius: 4px; /* Subtract 2px for the border. */ width: calc(100% - 2px);
diff --git a/chromeos/constants/chromeos_features.cc b/chromeos/constants/chromeos_features.cc index 3ff4352..0d47d25 100644 --- a/chromeos/constants/chromeos_features.cc +++ b/chromeos/constants/chromeos_features.cc
@@ -88,8 +88,8 @@ "ArcManagedAdbSideloadingSupport", base::FEATURE_DISABLED_BY_DEFAULT}; // Controls whether to enable support for View.onKeyPreIme() of ARC apps. -const base::Feature kArcPreImeKeyEventSupport{ - "ArcPreImeKeyEventSupport", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kArcPreImeKeyEventSupport{"ArcPreImeKeyEventSupport", + base::FEATURE_ENABLED_BY_DEFAULT}; // Enables or disables auto screen-brightness adjustment when ambient light // changes.
diff --git a/chromeos/constants/chromeos_switches.cc b/chromeos/constants/chromeos_switches.cc index 0aa4211..d4ee905 100644 --- a/chromeos/constants/chromeos_switches.cc +++ b/chromeos/constants/chromeos_switches.cc
@@ -97,14 +97,20 @@ // 'en-US,en' as preferred languages. const char kArcDisableLocaleSync[] = "arc-disable-locale-sync"; -// Used for development of Android app that are included into ARC++ as system -// default apps in order to be able to install them via adb. -const char kArcDisableSystemDefaultApps[] = "arc-disable-system-default-apps"; +// Used to disable GMS scheduling of media store periodic indexing and corpora +// maintenance tasks. Used in performance tests to prevent running during +// testing which can cause unstable results or CPU not idle pre-test failures. +const char kArcDisableMediaStoreMaintenance[] = + "arc-disable-media-store-maintenance"; // Flag that disables ARC Play Auto Install flow that installs set of predefined // apps silently. Used in autotests to resolve racy conditions. const char kArcDisablePlayAutoInstall[] = "arc-disable-play-auto-install"; +// Used for development of Android app that are included into ARC as system +// default apps in order to be able to install them via adb. +const char kArcDisableSystemDefaultApps[] = "arc-disable-system-default-apps"; + // Flag that forces ARC to cache icons for apps. const char kArcForceCacheAppIcons[] = "arc-force-cache-app-icons";
diff --git a/chromeos/constants/chromeos_switches.h b/chromeos/constants/chromeos_switches.h index 109c851..2bef31a 100644 --- a/chromeos/constants/chromeos_switches.h +++ b/chromeos/constants/chromeos_switches.h
@@ -41,6 +41,8 @@ extern const char kArcDisableGmsCoreCache[]; COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const char kArcDisableLocaleSync[]; COMPONENT_EXPORT(CHROMEOS_CONSTANTS) +extern const char kArcDisableMediaStoreMaintenance[]; +COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const char kArcDisableSystemDefaultApps[]; COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const char kArcDisablePlayAutoInstall[];
diff --git a/chromeos/login/auth/authenticator.h b/chromeos/login/auth/authenticator.h index 08f5a75c..2e7d31c 100644 --- a/chromeos/login/auth/authenticator.h +++ b/chromeos/login/auth/authenticator.h
@@ -44,10 +44,6 @@ virtual void AuthenticateToLogin(content::BrowserContext* browser_context, const UserContext& user_context) = 0; - // Initiates supervised user login. - // TODO(crbug.com/866790): Remove this as a part of Supervised users cleanup. - virtual void LoginAsSupervisedUser(const UserContext& user_context) = 0; - // Initiates incognito ("browse without signing in") login. virtual void LoginOffTheRecord() = 0;
diff --git a/chromeos/login/auth/cryptohome_authenticator.cc b/chromeos/login/auth/cryptohome_authenticator.cc index d86d41c..89bb6895 100644 --- a/chromeos/login/auth/cryptohome_authenticator.cc +++ b/chromeos/login/auth/cryptohome_authenticator.cc
@@ -113,8 +113,8 @@ return "GUEST_LOGIN"; case CryptohomeAuthenticator::PUBLIC_ACCOUNT_LOGIN: return "PUBLIC_ACCOUNT_LOGIN"; - case CryptohomeAuthenticator::SUPERVISED_USER_LOGIN: - return "SUPERVISED_USER_LOGIN"; + case CryptohomeAuthenticator::SUPERVISED_USER_LOGIN_DEPRECATED: + return "SUPERVISED_USER_LOGIN_DEPRECATED"; case CryptohomeAuthenticator::LOGIN_FAILED: return "LOGIN_FAILED"; case CryptohomeAuthenticator::OWNER_REQUIRED: @@ -628,22 +628,6 @@ this)); } -void CryptohomeAuthenticator::LoginAsSupervisedUser( - const UserContext& user_context) { - DCHECK(task_runner_->RunsTasksInCurrentSequence()); - DCHECK_EQ(user_manager::USER_TYPE_SUPERVISED, user_context.GetUserType()); - - // TODO(nkostylev): Pass proper value for |user_is_new| or remove (not used). - current_state_.reset(new AuthAttemptState(user_context, - false, // unlock - false, // online_complete - false)); // user_is_new - remove_user_data_on_failure_ = false; - StartMount(current_state_->AsWeakPtr(), - scoped_refptr<CryptohomeAuthenticator>(this), - false /* ephemeral */, false /* create_if_nonexistent */); -} - void CryptohomeAuthenticator::LoginOffTheRecord() { DCHECK(task_runner_->RunsTasksInCurrentSequence()); current_state_.reset( @@ -962,7 +946,7 @@ FROM_HERE, base::BindOnce(&CryptohomeAuthenticator::OnAuthSuccess, this)); break; - case SUPERVISED_USER_LOGIN: + case SUPERVISED_USER_LOGIN_DEPRECATED: current_state_->user_context.SetIsUsingOAuth(false); task_runner_->PostTask( FROM_HERE, @@ -1141,8 +1125,9 @@ return PUBLIC_ACCOUNT_LOGIN; if (user_type == user_manager::USER_TYPE_KIOSK_APP) return KIOSK_ACCOUNT_LOGIN; - if (user_type == user_manager::USER_TYPE_SUPERVISED) - return SUPERVISED_USER_LOGIN; + // TODO(crbug/1155729): If this check is never true, remove the enum field. + if (user_type == user_manager::USER_TYPE_SUPERVISED_DEPRECATED) + return SUPERVISED_USER_LOGIN_DEPRECATED; if (!VerifyOwner()) return CONTINUE;
diff --git a/chromeos/login/auth/cryptohome_authenticator.h b/chromeos/login/auth/cryptohome_authenticator.h index d32fbde..2fa01e0 100644 --- a/chromeos/login/auth/cryptohome_authenticator.h +++ b/chromeos/login/auth/cryptohome_authenticator.h
@@ -84,10 +84,12 @@ ONLINE_FAILED = 15, // Obsolete (ClientLogin): Online login disallowed, // but offline succeeded. GUEST_LOGIN = 16, // Logged in guest mode. - PUBLIC_ACCOUNT_LOGIN = 17, // Logged into a public account. - SUPERVISED_USER_LOGIN = 18, // Logged in as a supervised user. - LOGIN_FAILED = 19, // Obsolete: Login denied. - OWNER_REQUIRED = 20, // Login is restricted to the owner only. + PUBLIC_ACCOUNT_LOGIN = 17, // Logged into a public account. + // TODO(crbug/1155729): Remove this enum. + SUPERVISED_USER_LOGIN_DEPRECATED = + 18, // Logged in as deprecated legacy supervised user. + LOGIN_FAILED = 19, // Obsolete: Login denied. + OWNER_REQUIRED = 20, // Login is restricted to the owner only. FAILED_USERNAME_HASH = 21, // Failed GetSanitizedUsername request. KIOSK_ACCOUNT_LOGIN = 22, // Logged into a kiosk account. REMOVED_DATA_AFTER_FAILURE = 23, // Successfully removed the user's @@ -121,11 +123,6 @@ void AuthenticateToLogin(content::BrowserContext* context, const UserContext& user_context) override; - // Initiates supervised user login. - // Creates cryptohome if missing or mounts existing one and - // notifies consumer on the success/failure. - void LoginAsSupervisedUser(const UserContext& user_context) override; - // Initiates incognito ("browse without signing in") login. // Mounts tmpfs and notifies consumer on the success/failure. void LoginOffTheRecord() override;
diff --git a/chromeos/login/auth/stub_authenticator.cc b/chromeos/login/auth/stub_authenticator.cc index 6218b3c..8ddc575f 100644 --- a/chromeos/login/auth/stub_authenticator.cc +++ b/chromeos/login/auth/stub_authenticator.cc
@@ -80,13 +80,6 @@ AuthFailure::FromNetworkAuthFailure(error))); } -void StubAuthenticator::LoginAsSupervisedUser(const UserContext& user_context) { - UserContext new_user_context = user_context; - new_user_context.SetUserIDHash(user_context.GetAccountId().GetUserEmail() + - kUserIdHashSuffix); - consumer_->OnAuthSuccess(new_user_context); -} - void StubAuthenticator::LoginOffTheRecord() { consumer_->OnOffTheRecordAuthSuccess(); }
diff --git a/chromeos/login/auth/stub_authenticator.h b/chromeos/login/auth/stub_authenticator.h index 7e9b717..3189efb 100644 --- a/chromeos/login/auth/stub_authenticator.h +++ b/chromeos/login/auth/stub_authenticator.h
@@ -46,7 +46,6 @@ const UserContext& user_context) override; void AuthenticateToLogin(content::BrowserContext* context, const UserContext& user_context) override; - void LoginAsSupervisedUser(const UserContext& user_context) override; void LoginOffTheRecord() override; void LoginAsPublicSession(const UserContext& user_context) override; void LoginAsKioskAccount(const AccountId& app_account_id,
diff --git a/chromeos/login/login_state/login_state.cc b/chromeos/login/login_state/login_state.cc index c0d8dbf1..bb05cbf 100644 --- a/chromeos/login/login_state/login_state.cc +++ b/chromeos/login/login_state/login_state.cc
@@ -123,7 +123,7 @@ bool LoginState::IsUserAuthenticated() const { return logged_in_user_type_ == LOGGED_IN_USER_REGULAR || logged_in_user_type_ == LOGGED_IN_USER_OWNER || - logged_in_user_type_ == LOGGED_IN_USER_SUPERVISED || + logged_in_user_type_ == LOGGED_IN_USER_SUPERVISED_DEPRECATED || logged_in_user_type_ == LOGGED_IN_USER_CHILD; }
diff --git a/chromeos/login/login_state/login_state.h b/chromeos/login/login_state/login_state.h index 86151437..2523b93 100644 --- a/chromeos/login/login_state/login_state.h +++ b/chromeos/login/login_state/login_state.h
@@ -27,7 +27,9 @@ LOGGED_IN_USER_GUEST, // A guest is logged in (i.e. incognito) LOGGED_IN_USER_PUBLIC_ACCOUNT, // A user is logged in to a public session. LOGGED_IN_USER_PUBLIC_ACCOUNT_MANAGED, // Public session v2. - LOGGED_IN_USER_SUPERVISED, // A supervised user is logged in + // TODO(crbug/1155729): Remove this enum field. + LOGGED_IN_USER_SUPERVISED_DEPRECATED, // A deprecated legacy supervised + // user is logged in. LOGGED_IN_USER_KIOSK_APP, // Is in one of the kiosk modes -- Chrome App, // Arc or Web App LOGGED_IN_USER_CHILD // A child is logged in
diff --git a/chromeos/profiles/atom.afdo.newest.txt b/chromeos/profiles/atom.afdo.newest.txt index a9a4247..a5f2ee1 100644 --- a/chromeos/profiles/atom.afdo.newest.txt +++ b/chromeos/profiles/atom.afdo.newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-atom-89-4367.0-1609757097-benchmark-89.0.4384.0-r1-redacted.afdo.xz +chromeos-chrome-amd64-atom-89-4380.0-1610362181-benchmark-89.0.4385.0-r1-redacted.afdo.xz
diff --git a/chromeos/profiles/bigcore.afdo.newest.txt b/chromeos/profiles/bigcore.afdo.newest.txt index 97ec8d9..4d7151f 100644 --- a/chromeos/profiles/bigcore.afdo.newest.txt +++ b/chromeos/profiles/bigcore.afdo.newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-bigcore-89-4367.0-1609764762-benchmark-89.0.4384.0-r1-redacted.afdo.xz +chromeos-chrome-amd64-bigcore-89-4374.0-1610361443-benchmark-89.0.4385.0-r1-redacted.afdo.xz
diff --git a/chromeos/services/assistant/assistant_manager_service_impl.cc b/chromeos/services/assistant/assistant_manager_service_impl.cc index 946e900..357e038 100644 --- a/chromeos/services/assistant/assistant_manager_service_impl.cc +++ b/chromeos/services/assistant/assistant_manager_service_impl.cc
@@ -35,6 +35,7 @@ #include "chromeos/services/assistant/libassistant_service_host_impl.h" #include "chromeos/services/assistant/media_session/assistant_media_session.h" #include "chromeos/services/assistant/platform_api_impl.h" +#include "chromeos/services/assistant/proxy/conversation_controller_proxy.h" #include "chromeos/services/assistant/proxy/service_controller_proxy.h" #include "chromeos/services/assistant/public/cpp/assistant_client.h" #include "chromeos/services/assistant/public/cpp/device_actions.h" @@ -506,22 +507,10 @@ AssistantQuerySource source, bool allow_tts) { DVLOG(1) << __func__; - assistant_client::VoicelessOptions options; - options.is_user_initiated = true; - if (!allow_tts) { - options.modality = - assistant_client::VoicelessOptions::Modality::TYPING_MODALITY; - } - - // Cache metadata about this interaction that can be resolved when the - // associated conversation turn starts in LibAssistant. - options.conversation_turn_id = - NewPendingInteraction(AssistantInteractionType::kText, source, query); - - std::string interaction = CreateTextQueryInteraction(query); - assistant_manager_internal()->SendVoicelessInteraction( - interaction, /*description=*/"text_query", options, [](auto) {}); + conversation_controller_proxy().SendTextQuery( + query, allow_tts, + NewPendingInteraction(AssistantInteractionType::kText, source, query)); } void AssistantManagerServiceImpl::AddAssistantInteractionSubscriber( @@ -1403,6 +1392,11 @@ audio_input_host_->SetMicState(mic_open); } +ConversationControllerProxy& +AssistantManagerServiceImpl::conversation_controller_proxy() { + return assistant_proxy_->conversation_controller_proxy(); +} + ServiceControllerProxy& AssistantManagerServiceImpl::service_controller() { return assistant_proxy_->service_controller(); }
diff --git a/chromeos/services/assistant/assistant_manager_service_impl.h b/chromeos/services/assistant/assistant_manager_service_impl.h index cff59765..e4f358cd 100644 --- a/chromeos/services/assistant/assistant_manager_service_impl.h +++ b/chromeos/services/assistant/assistant_manager_service_impl.h
@@ -24,6 +24,7 @@ #include "chromeos/services/assistant/assistant_settings_impl.h" #include "chromeos/services/assistant/chromium_api_delegate.h" #include "chromeos/services/assistant/proxy/assistant_proxy.h" +#include "chromeos/services/assistant/proxy/conversation_controller_proxy.h" #include "chromeos/services/assistant/proxy/libassistant_service_host.h" #include "chromeos/services/assistant/public/cpp/assistant_notification.h" #include "chromeos/services/assistant/public/cpp/assistant_service.h" @@ -299,6 +300,7 @@ DeviceActions* device_actions(); scoped_refptr<base::SequencedTaskRunner> main_task_runner(); + ConversationControllerProxy& conversation_controller_proxy(); CrosDisplayConnection* display_connection(); ServiceControllerProxy& service_controller(); const ServiceControllerProxy& service_controller() const;
diff --git a/chromeos/services/assistant/proxy/BUILD.gn b/chromeos/services/assistant/proxy/BUILD.gn index dc5ee5ae..56808eaf 100644 --- a/chromeos/services/assistant/proxy/BUILD.gn +++ b/chromeos/services/assistant/proxy/BUILD.gn
@@ -11,6 +11,8 @@ sources = [ "assistant_proxy.cc", "assistant_proxy.h", + "conversation_controller_proxy.cc", + "conversation_controller_proxy.h", "libassistant_service_host.h", "service_controller_proxy.cc", "service_controller_proxy.h",
diff --git a/chromeos/services/assistant/proxy/assistant_proxy.cc b/chromeos/services/assistant/proxy/assistant_proxy.cc index 6cee87f..cfdf6fba 100644 --- a/chromeos/services/assistant/proxy/assistant_proxy.cc +++ b/chromeos/services/assistant/proxy/assistant_proxy.cc
@@ -8,6 +8,7 @@ #include "base/bind.h" #include "base/check.h" +#include "chromeos/services/assistant/proxy/conversation_controller_proxy.h" #include "chromeos/services/assistant/proxy/libassistant_service_host.h" #include "chromeos/services/assistant/proxy/service_controller_proxy.h" #include "chromeos/services/libassistant/libassistant_service.h" @@ -30,6 +31,9 @@ service_controller_proxy_ = std::make_unique<ServiceControllerProxy>(host, BindServiceController()); + conversation_controller_proxy_ = + std::make_unique<ConversationControllerProxy>( + BindConversationController()); } void AssistantProxy::LaunchLibassistantService() { @@ -78,6 +82,14 @@ return pending_remote; } +mojo::PendingRemote<AssistantProxy::ConversationControllerMojom> +AssistantProxy::BindConversationController() { + mojo::PendingRemote<ConversationControllerMojom> pending_remote; + libassistant_service_remote_->BindConversationController( + pending_remote.InitWithNewPipeAndPassReceiver()); + return pending_remote; +} + scoped_refptr<base::SingleThreadTaskRunner> AssistantProxy::background_task_runner() { return background_thread_.task_runner(); @@ -88,5 +100,10 @@ return *service_controller_proxy_; } +ConversationControllerProxy& AssistantProxy::conversation_controller_proxy() { + DCHECK(conversation_controller_proxy_); + return *conversation_controller_proxy_; +} + } // namespace assistant } // namespace chromeos
diff --git a/chromeos/services/assistant/proxy/assistant_proxy.h b/chromeos/services/assistant/proxy/assistant_proxy.h index bece8e34..4cadf62 100644 --- a/chromeos/services/assistant/proxy/assistant_proxy.h +++ b/chromeos/services/assistant/proxy/assistant_proxy.h
@@ -8,6 +8,7 @@ #include <memory> #include "base/threading/thread.h" +#include "chromeos/services/libassistant/public/mojom/conversation_controller.mojom.h" #include "chromeos/services/libassistant/public/mojom/service.mojom.h" #include "mojo/public/cpp/bindings/remote.h" @@ -20,6 +21,7 @@ namespace chromeos { namespace assistant { +class ConversationControllerProxy; class LibassistantServiceHost; class ServiceControllerProxy; @@ -38,6 +40,9 @@ // service. ServiceControllerProxy& service_controller(); + // Returns the controller that manages conversations with Libassistant. + ConversationControllerProxy& conversation_controller_proxy(); + // The background thread is temporary exposed until the entire Libassistant // API is hidden behind this proxy API. base::Thread& background_thread() { return background_thread_; } @@ -47,6 +52,8 @@ chromeos::libassistant::mojom::LibassistantService; using ServiceControllerMojom = chromeos::libassistant::mojom::ServiceController; + using ConversationControllerMojom = + chromeos::libassistant::mojom::ConversationController; scoped_refptr<base::SingleThreadTaskRunner> background_task_runner(); @@ -57,12 +64,14 @@ void StopLibassistantServiceOnBackgroundThread(); mojo::PendingRemote<ServiceControllerMojom> BindServiceController(); + mojo::PendingRemote<ConversationControllerMojom> BindConversationController(); // Owned by |AssistantManagerServiceImpl|. LibassistantServiceHost* libassistant_service_host_ = nullptr; mojo::Remote<LibassistantServiceMojom> libassistant_service_remote_; std::unique_ptr<ServiceControllerProxy> service_controller_proxy_; + std::unique_ptr<ConversationControllerProxy> conversation_controller_proxy_; // The thread on which the Libassistant service runs. // Warning: must be the last object, so it is destroyed (and flushed) first.
diff --git a/chromeos/services/assistant/proxy/conversation_controller_proxy.cc b/chromeos/services/assistant/proxy/conversation_controller_proxy.cc new file mode 100644 index 0000000..8a1a159 --- /dev/null +++ b/chromeos/services/assistant/proxy/conversation_controller_proxy.cc
@@ -0,0 +1,28 @@ +// Copyright 2020 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 "chromeos/services/assistant/proxy/conversation_controller_proxy.h" + +#include "chromeos/assistant/internal/internal_util.h" + +namespace chromeos { +namespace assistant { + +ConversationControllerProxy::ConversationControllerProxy( + mojo::PendingRemote<ConversationController> conversation_controller_remote) + : conversation_controller_remote_( + std::move(conversation_controller_remote)) {} + +ConversationControllerProxy::~ConversationControllerProxy() = default; + +void ConversationControllerProxy::SendTextQuery( + const std::string& query, + bool allow_tts, + const std::string& conversation_id) { + conversation_controller_remote_->SendTextQuery(query, allow_tts, + conversation_id); +} + +} // namespace assistant +} // namespace chromeos
diff --git a/chromeos/services/assistant/proxy/conversation_controller_proxy.h b/chromeos/services/assistant/proxy/conversation_controller_proxy.h new file mode 100644 index 0000000..a39835d --- /dev/null +++ b/chromeos/services/assistant/proxy/conversation_controller_proxy.h
@@ -0,0 +1,39 @@ +// Copyright 2020 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 CHROMEOS_SERVICES_ASSISTANT_PROXY_CONVERSATION_CONTROLLER_PROXY_H_ +#define CHROMEOS_SERVICES_ASSISTANT_PROXY_CONVERSATION_CONTROLLER_PROXY_H_ + +#include <string> + +#include "chromeos/services/libassistant/public/mojom/conversation_controller.mojom.h" +#include "mojo/public/cpp/bindings/remote.h" + +namespace chromeos { +namespace assistant { + +using chromeos::libassistant::mojom::ConversationController; + +class ConversationControllerProxy { + public: + explicit ConversationControllerProxy( + mojo::PendingRemote<ConversationController> + conversation_controller_remote); + ConversationControllerProxy(const ConversationControllerProxy&) = delete; + ConversationControllerProxy& operator=(const ConversationControllerProxy&) = + delete; + ~ConversationControllerProxy(); + + void SendTextQuery(const std::string& query, + bool allow_tts, + const std::string& conversation_id); + + private: + mojo::Remote<ConversationController> conversation_controller_remote_; +}; + +} // namespace assistant +} // namespace chromeos + +#endif // CHROMEOS_SERVICES_ASSISTANT_PROXY_CONVERSATION_CONTROLLER_PROXY_H_
diff --git a/chromeos/services/assistant/test_support/fake_libassistant_service.h b/chromeos/services/assistant/test_support/fake_libassistant_service.h index 9265ec6..413b842f 100644 --- a/chromeos/services/assistant/test_support/fake_libassistant_service.h +++ b/chromeos/services/assistant/test_support/fake_libassistant_service.h
@@ -33,9 +33,11 @@ void BindServiceController( mojo::PendingReceiver<libassistant::mojom::ServiceController> receiver) override; + void BindConversationController( + mojo::PendingReceiver<libassistant::mojom::ConversationController> + receiver) override {} void BindAudioInputController() override {} void BindAudioOutputController() override {} - void BindInteractionController() override {} private: mojo::Receiver<libassistant::mojom::LibassistantService> receiver_;
diff --git a/chromeos/services/libassistant/BUILD.gn b/chromeos/services/libassistant/BUILD.gn index 674865d..10babbf 100644 --- a/chromeos/services/libassistant/BUILD.gn +++ b/chromeos/services/libassistant/BUILD.gn
@@ -33,6 +33,8 @@ sources = [ "assistant_manager_observer.h", + "conversation_controller.cc", + "conversation_controller.h", "platform_api.cc", "platform_api.h", "service_controller.cc", @@ -40,9 +42,12 @@ ] deps = [ + "//chromeos/assistant/internal", + "//chromeos/assistant/internal/proto/google3", "//chromeos/services/assistant/public/cpp", "//chromeos/services/assistant/public/cpp/migration", "//chromeos/services/libassistant/public/mojom", + "//libassistant/shared/internal_api:assistant_manager_internal", "//libassistant/shared/public", ]
diff --git a/chromeos/services/libassistant/conversation_controller.cc b/chromeos/services/libassistant/conversation_controller.cc new file mode 100644 index 0000000..dd7bdc1 --- /dev/null +++ b/chromeos/services/libassistant/conversation_controller.cc
@@ -0,0 +1,68 @@ +// Copyright 2020 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 "chromeos/services/libassistant/conversation_controller.h" + +#include "chromeos/assistant/internal/internal_util.h" +#include "chromeos/services/libassistant/public/mojom/conversation_controller.mojom.h" +#include "chromeos/services/libassistant/service_controller.h" +#include "libassistant/shared/internal_api/assistant_manager_internal.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" + +namespace chromeos { +namespace libassistant { + +ConversationController::ConversationController( + ServiceController* service_controller) + : receiver_(this), service_controller_(service_controller) { + DCHECK(service_controller_); +} + +ConversationController::~ConversationController() = default; + +void ConversationController::Bind( + mojo::PendingReceiver<mojom::ConversationController> receiver) { + // Cannot bind the receiver twice. + DCHECK(!receiver_.is_bound()); + receiver_.Bind(std::move(receiver)); +} + +void ConversationController::SendTextQuery( + const std::string& query, + bool allow_tts, + const base::Optional<std::string>& conversation_id) { + // DCHECKs if this function gets invoked after the service has been fully + // started. + // TODO(meilinw): only check for the |ServiceState::kRunning| state instead + // after it has been wired up. + DCHECK(service_controller_->IsStarted()) + << "Libassistant service is not ready to handle queries."; + DCHECK(assistant_manager_internal()); + + // Configs |VoicelessOptions|. + assistant_client::VoicelessOptions options; + options.is_user_initiated = true; + if (!allow_tts) { + options.modality = + assistant_client::VoicelessOptions::Modality::TYPING_MODALITY; + } + // Ensure LibAssistant uses the requested conversation id. + if (conversation_id.has_value()) + options.conversation_turn_id = conversation_id.value(); + + // Builds text interaction. + std::string interaction = + chromeos::assistant::CreateTextQueryInteraction(query); + + assistant_manager_internal()->SendVoicelessInteraction( + interaction, /*description=*/"text_query", options, [](auto) {}); +} + +assistant_client::AssistantManagerInternal* +ConversationController::assistant_manager_internal() { + return service_controller_->assistant_manager_internal(); +} + +} // namespace libassistant +} // namespace chromeos
diff --git a/chromeos/services/libassistant/conversation_controller.h b/chromeos/services/libassistant/conversation_controller.h new file mode 100644 index 0000000..52ba96dc --- /dev/null +++ b/chromeos/services/libassistant/conversation_controller.h
@@ -0,0 +1,50 @@ +// Copyright 2020 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 CHROMEOS_SERVICES_LIBASSISTANT_CONVERSATION_CONTROLLER_H_ +#define CHROMEOS_SERVICES_LIBASSISTANT_CONVERSATION_CONTROLLER_H_ + +#include "base/component_export.h" +#include "base/optional.h" +#include "chromeos/services/libassistant/public/mojom/conversation_controller.mojom.h" +#include "mojo/public/cpp/bindings/receiver.h" + +namespace assistant_client { +class AssistantManagerInternal; +} // namespace assistant_client + +namespace chromeos { +namespace libassistant { + +class ServiceController; + +class COMPONENT_EXPORT(LIBASSISTANT_SERVICE) ConversationController + : public mojom::ConversationController { + public: + explicit ConversationController(ServiceController* service_controller); + ConversationController(const ConversationController&) = delete; + ConversationController& operator=(const ConversationController&) = delete; + ~ConversationController() override; + + void Bind(mojo::PendingReceiver<mojom::ConversationController> receiver); + + // mojom::ConversationController implementation: + void SendTextQuery( + const std::string& query, + bool allow_tts, + const base::Optional<std::string>& conversation_id) override; + + private: + assistant_client::AssistantManagerInternal* assistant_manager_internal(); + + mojo::Receiver<mojom::ConversationController> receiver_; + + // Owned by |LibassistantService|. + ServiceController* const service_controller_; +}; + +} // namespace libassistant +} // namespace chromeos + +#endif // CHROMEOS_SERVICES_LIBASSISTANT_CONVERSATION_CONTROLLER_H_
diff --git a/chromeos/services/libassistant/libassistant_service.cc b/chromeos/services/libassistant/libassistant_service.cc index d3bbd7a..82bc4048 100644 --- a/chromeos/services/libassistant/libassistant_service.cc +++ b/chromeos/services/libassistant/libassistant_service.cc
@@ -10,6 +10,7 @@ #include "base/check.h" #include "base/logging.h" #include "chromeos/services/assistant/public/cpp/migration/cros_platform_api.h" +#include "chromeos/services/libassistant/conversation_controller.h" #include "chromeos/services/libassistant/platform_api.h" #include "chromeos/services/libassistant/service_controller.h" @@ -23,7 +24,9 @@ : receiver_(this, std::move(receiver)), platform_api_(std::make_unique<PlatformApi>()), service_controller_( - std::make_unique<ServiceController>(delegate, platform_api_.get())) { + std::make_unique<ServiceController>(delegate, platform_api_.get())), + conversation_controller_( + std::make_unique<ConversationController>(service_controller_.get())) { platform_api_->SetAudioInputProvider(&platform_api->GetAudioInputProvider()) .SetAudioOutputProvider(&platform_api->GetAudioOutputProvider()) .SetAuthProvider(&platform_api->GetAuthProvider()) @@ -43,5 +46,10 @@ service_controller().SetInitializeCallback(std::move(callback)); } +void LibassistantService::BindConversationController( + mojo::PendingReceiver<mojom::ConversationController> receiver) { + conversation_controller_->Bind(std::move(receiver)); +} + } // namespace libassistant } // namespace chromeos
diff --git a/chromeos/services/libassistant/libassistant_service.h b/chromeos/services/libassistant/libassistant_service.h index c485d11..c15c17a 100644 --- a/chromeos/services/libassistant/libassistant_service.h +++ b/chromeos/services/libassistant/libassistant_service.h
@@ -8,7 +8,9 @@ #include <memory> #include "base/component_export.h" +#include "chromeos/services/libassistant/public/mojom/conversation_controller.mojom.h" #include "chromeos/services/libassistant/public/mojom/service.mojom.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/receiver.h" namespace assistant_client { @@ -26,6 +28,7 @@ namespace chromeos { namespace libassistant { +class ConversationController; class PlatformApi; class ServiceController; @@ -52,13 +55,15 @@ // mojom::LibassistantService implementation: void BindServiceController( mojo::PendingReceiver<mojom::ServiceController> receiver) override; + void BindConversationController( + mojo::PendingReceiver<mojom::ConversationController> receiver) override; void BindAudioInputController() override {} void BindAudioOutputController() override {} - void BindInteractionController() override {} mojo::Receiver<mojom::LibassistantService> receiver_; std::unique_ptr<PlatformApi> platform_api_; std::unique_ptr<ServiceController> service_controller_; + std::unique_ptr<ConversationController> conversation_controller_; }; } // namespace libassistant
diff --git a/chromeos/services/libassistant/public/mojom/BUILD.gn b/chromeos/services/libassistant/public/mojom/BUILD.gn index 96ead4f..2a52ce7b 100644 --- a/chromeos/services/libassistant/public/mojom/BUILD.gn +++ b/chromeos/services/libassistant/public/mojom/BUILD.gn
@@ -6,6 +6,7 @@ mojom("mojom") { sources = [ + "conversation_controller.mojom", "service.mojom", "service_controller.mojom", ]
diff --git a/chromeos/services/libassistant/public/mojom/conversation_controller.mojom b/chromeos/services/libassistant/public/mojom/conversation_controller.mojom new file mode 100644 index 0000000..3672263 --- /dev/null +++ b/chromeos/services/libassistant/public/mojom/conversation_controller.mojom
@@ -0,0 +1,14 @@ +// Copyright 2020 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. + +module chromeos.libassistant.mojom; + +// Interface for controller in charge of Assistant conversations. +interface ConversationController { + // Sends the specific text query to Libassistant. |conversation_id| is an + // identifier that will be propagated through the speech processor event + // pipeline to uniquely identify a conversation turn. If omitted, a unique + // identifier will be automatically generated. + SendTextQuery(string query, bool allow_tts, string? conversation_id); +};
diff --git a/chromeos/services/libassistant/public/mojom/service.mojom b/chromeos/services/libassistant/public/mojom/service.mojom index c79d1fb..252b8470 100644 --- a/chromeos/services/libassistant/public/mojom/service.mojom +++ b/chromeos/services/libassistant/public/mojom/service.mojom
@@ -5,6 +5,7 @@ module chromeos.libassistant.mojom; import "chromeos/services/libassistant/public/mojom/service_controller.mojom"; +import "chromeos/services/libassistant/public/mojom/conversation_controller.mojom"; // The main interface to the Libassistant service on ChromeOS. // Libassistant provides access to the Google Assistant. @@ -17,9 +18,12 @@ // of the Libassistant process (start/stop). BindServiceController(pending_receiver<ServiceController> receiver); + // Bind the conversation controller, which in charge of handling + // conversations with Libassistant. + BindConversationController(pending_receiver<ConversationController> receiver); + // This service will further expose methods to bind all other helper // controllers. BindAudioInputController(/* pending_receiver */); BindAudioOutputController(/* pending_receiver */); - BindInteractionController(/* pending_receiver */); };
diff --git a/chromeos/services/libassistant/service_controller.cc b/chromeos/services/libassistant/service_controller.cc index 3f7a799..c5e014e 100644 --- a/chromeos/services/libassistant/service_controller.cc +++ b/chromeos/services/libassistant/service_controller.cc
@@ -124,7 +124,7 @@ } bool ServiceController::IsStarted() const { - return state_ != mojom::ServiceState::kStopped; + return state_ != ServiceState::kStopped; } bool ServiceController::IsInitialized() const {
diff --git a/chromeos/services/machine_learning/public/cpp/fake_service_connection.cc b/chromeos/services/machine_learning/public/cpp/fake_service_connection.cc index d16e68e..23d02dd 100644 --- a/chromeos/services/machine_learning/public/cpp/fake_service_connection.cc +++ b/chromeos/services/machine_learning/public/cpp/fake_service_connection.cc
@@ -71,7 +71,7 @@ mojo::PendingReceiver<mojom::HandwritingRecognizer> receiver, mojom::MachineLearningService::LoadHandwritingModelCallback callback) { ScheduleCall(base::BindOnce( - &FakeServiceConnectionImpl::HandleLoadHandwritingModel, + &FakeServiceConnectionImpl::HandleLoadHandwritingModelCall, base::Unretained(this), std::move(receiver), std::move(callback))); } @@ -81,7 +81,7 @@ mojom::MachineLearningService::LoadHandwritingModelWithSpecCallback callback) { ScheduleCall(base::BindOnce( - &FakeServiceConnectionImpl::HandleLoadHandwritingModelWithSpec, + &FakeServiceConnectionImpl::HandleLoadHandwritingModelWithSpecCall, base::Unretained(this), std::move(receiver), std::move(callback))); } @@ -89,7 +89,7 @@ mojo::PendingReceiver<mojom::GrammarChecker> receiver, mojom::MachineLearningService::LoadGrammarCheckerCallback callback) { ScheduleCall(base::BindOnce( - &FakeServiceConnectionImpl::HandleLoadGrammarChecker, + &FakeServiceConnectionImpl::HandleLoadGrammarCheckerCall, base::Unretained(this), std::move(receiver), std::move(callback))); } void FakeServiceConnectionImpl::LoadSpeechRecognizer( @@ -98,7 +98,7 @@ mojo::PendingReceiver<mojom::SodaRecognizer> soda_recognizer, mojom::MachineLearningService::LoadSpeechRecognizerCallback callback) { ScheduleCall( - base::BindOnce(&FakeServiceConnectionImpl::HandleLoadSpeechRecognizer, + base::BindOnce(&FakeServiceConnectionImpl::HandleLoadSpeechRecognizerCall, base::Unretained(this), std::move(soda_client), std::move(soda_recognizer), std::move(callback))); } @@ -303,7 +303,7 @@ void FakeServiceConnectionImpl::Recognize( mojom::HandwritingRecognitionQueryPtr query, mojom::HandwritingRecognizer::RecognizeCallback callback) { - ScheduleCall(base::BindOnce(&FakeServiceConnectionImpl::HandleRecognize, + ScheduleCall(base::BindOnce(&FakeServiceConnectionImpl::HandleRecognizeCall, base::Unretained(this), std::move(query), std::move(callback))); } @@ -312,36 +312,36 @@ mojom::GrammarCheckerQueryPtr query, mojom::GrammarChecker::CheckCallback callback) { ScheduleCall(base::BindOnce( - &FakeServiceConnectionImpl::HandleGrammarCheckerQuery, + &FakeServiceConnectionImpl::HandleGrammarCheckerQueryCall, base::Unretained(this), std::move(query), std::move(callback))); } -void FakeServiceConnectionImpl::HandleStop() { +void FakeServiceConnectionImpl::HandleStopCall() { // Do something on the client } -void FakeServiceConnectionImpl::HandleStart() { +void FakeServiceConnectionImpl::HandleStartCall() { // Do something on the client. } -void FakeServiceConnectionImpl::HandleMarkDone() { - HandleStop(); +void FakeServiceConnectionImpl::HandleMarkDoneCall() { + HandleStopCall(); } void FakeServiceConnectionImpl::AddAudio(const std::vector<uint8_t>& audio) {} void FakeServiceConnectionImpl::Stop() { - ScheduleCall(base::BindOnce(&FakeServiceConnectionImpl::HandleStop, + ScheduleCall(base::BindOnce(&FakeServiceConnectionImpl::HandleStopCall, base::Unretained(this))); } void FakeServiceConnectionImpl::Start() { - ScheduleCall(base::BindOnce(&FakeServiceConnectionImpl::HandleStart, + ScheduleCall(base::BindOnce(&FakeServiceConnectionImpl::HandleStartCall, base::Unretained(this))); } void FakeServiceConnectionImpl::MarkDone() { - ScheduleCall(base::BindOnce(&FakeServiceConnectionImpl::HandleMarkDone, + ScheduleCall(base::BindOnce(&FakeServiceConnectionImpl::HandleMarkDoneCall, base::Unretained(this))); } -void FakeServiceConnectionImpl::HandleLoadHandwritingModel( +void FakeServiceConnectionImpl::HandleLoadHandwritingModelCall( mojo::PendingReceiver<mojom::HandwritingRecognizer> receiver, mojom::MachineLearningService::LoadHandwritingModelCallback callback) { if (load_handwriting_model_result_ == mojom::LoadHandwritingModelResult::OK) @@ -349,7 +349,7 @@ std::move(callback).Run(load_handwriting_model_result_); } -void FakeServiceConnectionImpl::HandleLoadHandwritingModelWithSpec( +void FakeServiceConnectionImpl::HandleLoadHandwritingModelWithSpecCall( mojo::PendingReceiver<mojom::HandwritingRecognizer> receiver, mojom::MachineLearningService::LoadHandwritingModelWithSpecCallback callback) { @@ -359,13 +359,13 @@ std::move(callback).Run(load_model_result_); } -void FakeServiceConnectionImpl::HandleRecognize( +void FakeServiceConnectionImpl::HandleRecognizeCall( mojom::HandwritingRecognitionQueryPtr query, mojom::HandwritingRecognizer::RecognizeCallback callback) { std::move(callback).Run(handwriting_result_.Clone()); } -void FakeServiceConnectionImpl::HandleLoadGrammarChecker( +void FakeServiceConnectionImpl::HandleLoadGrammarCheckerCall( mojo::PendingReceiver<mojom::GrammarChecker> receiver, mojom::MachineLearningService::LoadGrammarCheckerCallback callback) { if (load_model_result_ == mojom::LoadModelResult::OK) @@ -373,7 +373,7 @@ std::move(callback).Run(load_model_result_); } -void FakeServiceConnectionImpl::HandleLoadSpeechRecognizer( +void FakeServiceConnectionImpl::HandleLoadSpeechRecognizerCall( mojo::PendingRemote<mojom::SodaClient> soda_client, mojo::PendingReceiver<mojom::SodaRecognizer> soda_recognizer, mojom::MachineLearningService::LoadSpeechRecognizerCallback callback) { @@ -384,7 +384,7 @@ std::move(callback).Run(load_soda_result_); } -void FakeServiceConnectionImpl::HandleGrammarCheckerQuery( +void FakeServiceConnectionImpl::HandleGrammarCheckerQueryCall( mojom::GrammarCheckerQueryPtr query, mojom::GrammarChecker::CheckCallback callback) { std::move(callback).Run(grammar_checker_result_.Clone());
diff --git a/chromeos/services/machine_learning/public/cpp/fake_service_connection.h b/chromeos/services/machine_learning/public/cpp/fake_service_connection.h index c517308f..f052bc5 100644 --- a/chromeos/services/machine_learning/public/cpp/fake_service_connection.h +++ b/chromeos/services/machine_learning/public/cpp/fake_service_connection.h
@@ -204,29 +204,29 @@ void HandleFindLanguagesCall( std::string text, mojom::TextClassifier::FindLanguagesCallback callback); - void HandleLoadHandwritingModel( + void HandleLoadHandwritingModelCall( mojo::PendingReceiver<mojom::HandwritingRecognizer> receiver, mojom::MachineLearningService::LoadHandwritingModelCallback callback); - void HandleLoadHandwritingModelWithSpec( + void HandleLoadHandwritingModelWithSpecCall( mojo::PendingReceiver<mojom::HandwritingRecognizer> receiver, mojom::MachineLearningService::LoadHandwritingModelWithSpecCallback callback); - void HandleRecognize( + void HandleRecognizeCall( mojom::HandwritingRecognitionQueryPtr query, mojom::HandwritingRecognizer::RecognizeCallback callback); - void HandleLoadGrammarChecker( + void HandleLoadGrammarCheckerCall( mojo::PendingReceiver<mojom::GrammarChecker> receiver, mojom::MachineLearningService::LoadGrammarCheckerCallback callback); - void HandleGrammarCheckerQuery(mojom::GrammarCheckerQueryPtr query, + void HandleGrammarCheckerQueryCall(mojom::GrammarCheckerQueryPtr query, mojom::GrammarChecker::CheckCallback callback); - void HandleLoadSpeechRecognizer( + void HandleLoadSpeechRecognizerCall( mojo::PendingRemote<mojom::SodaClient> soda_client, mojo::PendingReceiver<mojom::SodaRecognizer> soda_recognizer, mojom::MachineLearningService::LoadSpeechRecognizerCallback callback); - void HandleStop(); - void HandleStart(); - void HandleMarkDone(); + void HandleStopCall(); + void HandleStartCall(); + void HandleMarkDoneCall(); mojo::ReceiverSet<mojom::Model> model_receivers_; mojo::ReceiverSet<mojom::GraphExecutor> graph_receivers_;
diff --git a/components/BUILD.gn b/components/BUILD.gn index 287b9d43..0aea246 100644 --- a/components/BUILD.gn +++ b/components/BUILD.gn
@@ -75,6 +75,7 @@ "//components/client_update_protocol:unit_tests", "//components/cloud_devices/common:unit_tests", "//components/component_updater:unit_tests", + "//components/component_updater/installer_policies:unit_tests", "//components/consent_auditor:unit_tests", "//components/content_capture/common:unit_tests", "//components/content_settings/core/browser:unit_tests", @@ -595,7 +596,6 @@ "dom_distiller/content/browser/test/test_util.cc", "dom_distiller/content/browser/test/test_util.h", "metrics/content/subprocess_metrics_provider_browsertest.cc", - "offline_pages/content/renovations/test/page_renovator_browsertest.cc", "paint_preview/renderer/paint_preview_recorder_browsertest.cc", "security_state/content/content_utils_browsertest.cc", "ukm/content/source_url_recorder_browsertest.cc", @@ -628,8 +628,6 @@ "//components/dom_distiller/core:test_support", "//components/error_page/content/browser:browser_tests", "//components/metrics:content", - "//components/offline_pages/content/renovations", - "//components/offline_pages/core/renovations", "//components/paint_preview/renderer", "//components/password_manager/content/browser", "//components/performance_manager:browser_tests",
diff --git a/components/arc/arc_util_unittest.cc b/components/arc/arc_util_unittest.cc index b3153c5..fde639c 100644 --- a/components/arc/arc_util_unittest.cc +++ b/components/arc/arc_util_unittest.cc
@@ -280,7 +280,7 @@ {user_manager::USER_TYPE_REGULAR, true}, {user_manager::USER_TYPE_GUEST, false}, {user_manager::USER_TYPE_PUBLIC_ACCOUNT, true}, - {user_manager::USER_TYPE_SUPERVISED, false}, + {user_manager::USER_TYPE_SUPERVISED_DEPRECATED, false}, {user_manager::USER_TYPE_KIOSK_APP, false}, {user_manager::USER_TYPE_CHILD, true}, {user_manager::USER_TYPE_ARC_KIOSK_APP, true},
diff --git a/components/arc/session/arc_container_client_adapter.cc b/components/arc/session/arc_container_client_adapter.cc index 336d2dd..976327d 100644 --- a/components/arc/session/arc_container_client_adapter.cc +++ b/components/arc/session/arc_container_client_adapter.cc
@@ -116,6 +116,8 @@ request.set_arc_custom_tabs_experiment(params.arc_custom_tabs_experiment); request.set_disable_system_default_app( params.arc_disable_system_default_app); + request.set_disable_media_store_maintenance( + params.disable_media_store_maintenance); chromeos::SessionManagerClient::Get()->StartArcMiniContainer( request, std::move(callback)); }
diff --git a/components/arc/session/arc_container_client_adapter_unittest.cc b/components/arc/session/arc_container_client_adapter_unittest.cc index a15f22d..30eedc02 100644 --- a/components/arc/session/arc_container_client_adapter_unittest.cc +++ b/components/arc/session/arc_container_client_adapter_unittest.cc
@@ -41,6 +41,10 @@ content::BrowserTaskEnvironment browser_task_environment_; }; +void OnMiniInstanceStarted(bool result) { + DCHECK(result); +} + // b/164816080 This test ensures that a new container instance that is // created while handling the shutting down of the previous instance, // doesn't incorrectly receive the shutdown event as well. @@ -91,6 +95,17 @@ EXPECT_FALSE(child_observer.stopped_called()); } +TEST_F(ArcContainerClientAdapterTest, StartArc_DisableMediaStoreMaintenance) { + StartParams start_params; + start_params.disable_media_store_maintenance = true; + client_adapter()->StartMiniArc(std::move(start_params), + base::BindOnce(&OnMiniInstanceStarted)); + const auto& request = chromeos::FakeSessionManagerClient::Get() + ->last_start_arc_mini_container_request(); + EXPECT_TRUE(request.has_disable_media_store_maintenance()); + EXPECT_TRUE(request.disable_media_store_maintenance()); +} + struct DalvikMemoryProfileTestParam { // Requested profile. StartParams::DalvikMemoryProfile profile; @@ -120,9 +135,6 @@ ArcContainerClientAdapterDalvikMemoryProfileTest, ::testing::ValuesIn(kDalvikMemoryProfileTestCases)); -void OnMiniInstanceStarted(bool result) { - DCHECK(result); -} TEST_P(ArcContainerClientAdapterDalvikMemoryProfileTest, Profile) { const auto& test_param = GetParam();
diff --git a/components/arc/session/arc_session_impl.cc b/components/arc/session/arc_session_impl.cc index c91672d..72ad8d9 100644 --- a/components/arc/session/arc_session_impl.cc +++ b/components/arc/session/arc_session_impl.cc
@@ -460,6 +460,14 @@ params.arc_disable_system_default_app = base::CommandLine::ForCurrentProcess()->HasSwitch( chromeos::switches::kArcDisableSystemDefaultApps); + if (params.arc_disable_system_default_app) + VLOG(1) << "System default app(s) are disabled"; + + params.disable_media_store_maintenance = + base::CommandLine::ForCurrentProcess()->HasSwitch( + chromeos::switches::kArcDisableMediaStoreMaintenance); + if (params.disable_media_store_maintenance) + VLOG(1) << "MediaStore maintenance task(s) are disabled"; VLOG(1) << "Starting ARC mini instance with lcd_density=" << params.lcd_density
diff --git a/components/arc/session/arc_start_params.h b/components/arc/session/arc_start_params.h index e906422..5e5889b3 100644 --- a/components/arc/session/arc_start_params.h +++ b/components/arc/session/arc_start_params.h
@@ -56,6 +56,9 @@ // Flag to disable system default apps. bool arc_disable_system_default_app = false; + // Flag to disable scheduling of media store periodic maintenance tasks. + bool disable_media_store_maintenance = false; + // The number of logical CPU cores that are currently disabled on the host. // This parameter is used only for starting ARCVM. uint32_t num_cores_disabled = 0;
diff --git a/components/arc/session/arc_vm_client_adapter.cc b/components/arc/session/arc_vm_client_adapter.cc index 5ee39ee..0b62850 100644 --- a/components/arc/session/arc_vm_client_adapter.cc +++ b/components/arc/session/arc_vm_client_adapter.cc
@@ -238,6 +238,10 @@ // TODO(niwa): Check if we need to set ro.boot.enable_adb_sideloading for // ARCVM. + // Only add boot property if flag to disable media store maintenance is set. + if (start_params.disable_media_store_maintenance) + result.push_back("androidboot.disable_media_store_maintenance=1"); + // Conditionally sets some properties based on |start_params|. switch (start_params.play_store_auto_update) { case StartParams::PlayStoreAutoUpdate::AUTO_UPDATE_DEFAULT:
diff --git a/components/arc/session/arc_vm_client_adapter_unittest.cc b/components/arc/session/arc_vm_client_adapter_unittest.cc index 9e4639e6..742b85a8 100644 --- a/components/arc/session/arc_vm_client_adapter_unittest.cc +++ b/components/arc/session/arc_vm_client_adapter_unittest.cc
@@ -1226,6 +1226,20 @@ "androidboot.disable_system_default_app=1")); } +TEST_F(ArcVmClientAdapterTest, StartUpgradeArc_DisableMediaStoreMaintenance) { + StartParams start_params(GetPopulatedStartParams()); + start_params.disable_media_store_maintenance = true; + SetValidUserInfo(); + StartMiniArcWithParams(true, std::move(start_params)); + UpgradeParams params(GetPopulatedUpgradeParams()); + UpgradeArcWithParams(true, std::move(params)); + EXPECT_TRUE(GetTestConciergeClient()->start_arc_vm_called()); + EXPECT_FALSE(arc_instance_stopped_called()); + EXPECT_TRUE( + base::Contains(GetTestConciergeClient()->start_arc_vm_request().params(), + "androidboot.disable_media_store_maintenance=1")); +} + // Tests that StartArcVm() is called with valid parameters. TEST_F(ArcVmClientAdapterTest, StartMiniArc_StartArcVmParams) { SetValidUserInfo();
diff --git a/components/autofill/core/browser/autofill_download_manager_unittest.cc b/components/autofill/core/browser/autofill_download_manager_unittest.cc index abfd223..f939418 100644 --- a/components/autofill/core/browser/autofill_download_manager_unittest.cc +++ b/components/autofill/core/browser/autofill_download_manager_unittest.cc
@@ -14,6 +14,7 @@ #include "base/base64url.h" #include "base/bind.h" #include "base/format_macros.h" +#include "base/numerics/safe_conversions.h" #include "base/run_loop.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" @@ -84,23 +85,14 @@ // the response body data is utilized. std::string GetStringFromDataElements( const std::vector<network::DataElement>* data_elements) { - network::DataElement unified_data_element; - auto data_elements_it = data_elements->begin(); - if (data_elements_it != data_elements->end()) { - unified_data_element.SetToBytes(data_elements_it->bytes(), - data_elements_it->length()); + std::string result; + for (const network::DataElement& e : *data_elements) { + DCHECK_EQ(e.type(), network::mojom::DataElementType::kBytes); + // Provide the length of the bytes explicitly, not to rely on the null + // termination. + result.append(e.bytes(), base::checked_cast<size_t>(e.length())); } - ++data_elements_it; - while (data_elements_it != data_elements->end()) { - unified_data_element.AppendBytes(data_elements_it->bytes(), - data_elements_it->length()); - ++data_elements_it; - } - // Using the std::string constructor with length ensures that we don't rely - // on having a termination character to delimit the string. This is the - // safest approach. - return std::string(unified_data_element.bytes(), - unified_data_element.length()); + return result; } // Gets the AutofillUploadRequest proto from the HTTP loader request payload.
diff --git a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/AlwaysDismissedDialog.java b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/AlwaysDismissedDialog.java index b99ce4c..68cbd01 100644 --- a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/AlwaysDismissedDialog.java +++ b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/AlwaysDismissedDialog.java
@@ -9,7 +9,6 @@ import org.chromium.base.ActivityState; import org.chromium.base.ApplicationStatus; -import org.chromium.base.Log; /** * Dialog subclass that ensures that dismiss() is called, even if the dialog is implicitly dismissed @@ -19,7 +18,6 @@ */ public class AlwaysDismissedDialog extends Dialog implements ApplicationStatus.ActivityStateListener { - private static final String TAG = "AlwaysDisDialog"; public AlwaysDismissedDialog(Activity ownerActivity, int theme) { super(ownerActivity, theme); ApplicationStatus.registerStateListenerForActivity(this, ownerActivity); @@ -35,10 +33,6 @@ @Override public void onActivityStateChange(Activity activity, int newState) { - if (newState == ActivityState.DESTROYED) { - Thread.dumpStack(); - Log.i(TAG, "Activity " + activity + " is destroyed. Dismissing dialog " + this); - dismiss(); - } + if (newState == ActivityState.DESTROYED) dismiss(); } }
diff --git a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/ContextMenuDialog.java b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/ContextMenuDialog.java index c79803cb..6ddd7c43 100644 --- a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/ContextMenuDialog.java +++ b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/ContextMenuDialog.java
@@ -20,7 +20,6 @@ import android.widget.FrameLayout; import org.chromium.base.ContextUtils; -import org.chromium.base.Log; import org.chromium.components.browser_ui.widget.animation.Interpolators; import org.chromium.ui.widget.AnchoredPopupWindow; import org.chromium.ui.widget.RectProvider; @@ -32,7 +31,6 @@ public class ContextMenuDialog extends AlwaysDismissedDialog { public static final int NO_CUSTOM_MARGIN = -1; - private static final String TAG = "ContextMenuDialog"; private static final long ENTER_ANIMATION_DURATION_MS = 250; // Exit animation duration should be set to 60% of the enter animation duration. private static final long EXIT_ANIMATION_DURATION_MS = 150; @@ -159,9 +157,6 @@ return; } - Thread.dumpStack(); - Log.i(TAG, "Dialog " + this + " is being dismissed."); - int[] contextMenuFinalLocationPx = new int[2]; mContentView.getLocationOnScreen(contextMenuFinalLocationPx); // Recalculate mContextMenuDestinationY because the context menu's final location may not be @@ -180,7 +175,6 @@ @Override public void onAnimationEnd(Animation animation) { - Log.i(TAG, "Dismiss animation just ended for " + this); ContextMenuDialog.super.dismiss(); } });
diff --git a/components/component_updater/installer_policies/BUILD.gn b/components/component_updater/installer_policies/BUILD.gn index 1e0d8eab..92a11b9f 100644 --- a/components/component_updater/installer_policies/BUILD.gn +++ b/components/component_updater/installer_policies/BUILD.gn
@@ -6,6 +6,8 @@ sources = [ "on_device_head_suggest_component_installer.cc", "on_device_head_suggest_component_installer.h", + "optimization_hints_component_installer.cc", + "optimization_hints_component_installer.h", "safety_tips_component_installer.cc", "safety_tips_component_installer.h", ] @@ -15,7 +17,23 @@ "//components/component_updater", "//components/omnibox/browser", "//components/omnibox/common", + "//components/optimization_guide/core", "//components/reputation/core", "//components/reputation/core:proto", ] } + +source_set("unit_tests") { + testonly = true + sources = [ "optimization_hints_component_installer_unittest.cc" ] + + deps = [ + ":installer_policies", + "//base", + "//base/test:test_support", + "//components/component_updater:test_support", + "//components/optimization_guide/core", + "//testing/gmock", + "//testing/gtest", + ] +}
diff --git a/components/component_updater/installer_policies/DEPS b/components/component_updater/installer_policies/DEPS index 188a1ba..774802a 100644 --- a/components/component_updater/installer_policies/DEPS +++ b/components/component_updater/installer_policies/DEPS
@@ -1,5 +1,6 @@ include_rules = [ "+components/omnibox/browser", "+components/omnibox/common", + "+components/optimization_guide/core", "+components/reputation/core", ]
diff --git a/chrome/browser/component_updater/optimization_hints_component_installer.cc b/components/component_updater/installer_policies/optimization_hints_component_installer.cc similarity index 85% rename from chrome/browser/component_updater/optimization_hints_component_installer.cc rename to components/component_updater/installer_policies/optimization_hints_component_installer.cc index b8cd86ea..cc3bcb8 100644 --- a/chrome/browser/component_updater/optimization_hints_component_installer.cc +++ b/components/component_updater/installer_policies/optimization_hints_component_installer.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/component_updater/optimization_hints_component_installer.h" +#include "components/component_updater/installer_policies/optimization_hints_component_installer.h" #include <utility> @@ -12,12 +12,10 @@ #include "base/path_service.h" #include "base/task/post_task.h" #include "base/version.h" -#include "chrome/browser/browser_process.h" #include "components/component_updater/component_updater_paths.h" -#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h" #include "components/optimization_guide/core/optimization_guide_constants.h" #include "components/optimization_guide/core/optimization_guide_features.h" -#include "components/optimization_guide/core/optimization_guide_service.h" +#include "components/optimization_guide/core/optimization_hints_component_update_listener.h" using component_updater::ComponentUpdateService; @@ -88,15 +86,15 @@ DVLOG(1) << "Got incompatible ruleset_format. Bailing out."; return; } - optimization_guide::OptimizationGuideService* optimization_guide_service = - g_browser_process->optimization_guide_service(); - if (optimization_guide_service && - !base::CommandLine::ForCurrentProcess()->HasSwitch( - kDisableInstallerUpdate)) { + optimization_guide::OptimizationHintsComponentUpdateListener* + update_listener = optimization_guide:: + OptimizationHintsComponentUpdateListener::GetInstance(); + if (update_listener && !base::CommandLine::ForCurrentProcess()->HasSwitch( + kDisableInstallerUpdate)) { optimization_guide::HintsComponentInfo info( version, install_dir.Append(optimization_guide::kUnindexedHintsFileName)); - optimization_guide_service->MaybeUpdateHintsComponent(info); + update_listener->MaybeUpdateHintsComponent(info); } } @@ -135,15 +133,9 @@ return std::vector<std::string>(); } -void RegisterOptimizationHintsComponent(ComponentUpdateService* cus, - bool is_off_the_record_profile) { - if (is_off_the_record_profile) { +void RegisterOptimizationHintsComponent(ComponentUpdateService* cus) { + if (!optimization_guide::features::IsOptimizationHintsEnabled()) return; - } - - if (!optimization_guide::features::IsOptimizationHintsEnabled()) { - return; - } auto installer = base::MakeRefCounted<ComponentInstaller>( std::make_unique<OptimizationHintsComponentInstallerPolicy>());
diff --git a/chrome/browser/component_updater/optimization_hints_component_installer.h b/components/component_updater/installer_policies/optimization_hints_component_installer.h similarity index 85% rename from chrome/browser/component_updater/optimization_hints_component_installer.h rename to components/component_updater/installer_policies/optimization_hints_component_installer.h index 38a3566..b1f78ea 100644 --- a/chrome/browser/component_updater/optimization_hints_component_installer.h +++ b/components/component_updater/installer_policies/optimization_hints_component_installer.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_COMPONENT_UPDATER_OPTIMIZATION_HINTS_COMPONENT_INSTALLER_H_ -#define CHROME_BROWSER_COMPONENT_UPDATER_OPTIMIZATION_HINTS_COMPONENT_INSTALLER_H_ +#ifndef COMPONENTS_COMPONENT_UPDATER_INSTALLER_POLICIES_OPTIMIZATION_HINTS_COMPONENT_INSTALLER_H_ +#define COMPONENTS_COMPONENT_UPDATER_INSTALLER_POLICIES_OPTIMIZATION_HINTS_COMPONENT_INSTALLER_H_ #include <memory> #include <string> @@ -56,9 +56,8 @@ DISALLOW_COPY_AND_ASSIGN(OptimizationHintsComponentInstallerPolicy); }; -void RegisterOptimizationHintsComponent(ComponentUpdateService* cus, - bool is_off_the_record_profile); +void RegisterOptimizationHintsComponent(ComponentUpdateService* cus); } // namespace component_updater -#endif // CHROME_BROWSER_COMPONENT_UPDATER_OPTIMIZATION_HINTS_COMPONENT_INSTALLER_H_ +#endif // COMPONENTS_COMPONENT_UPDATER_INSTALLER_POLICIES_OPTIMIZATION_HINTS_COMPONENT_INSTALLER_H_
diff --git a/chrome/browser/component_updater/optimization_hints_component_installer_unittest.cc b/components/component_updater/installer_policies/optimization_hints_component_installer_unittest.cc similarity index 64% rename from chrome/browser/component_updater/optimization_hints_component_installer_unittest.cc rename to components/component_updater/installer_policies/optimization_hints_component_installer_unittest.cc index 6d9d5fd..6538af9 100644 --- a/chrome/browser/component_updater/optimization_hints_component_installer_unittest.cc +++ b/components/component_updater/installer_policies/optimization_hints_component_installer_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/component_updater/optimization_hints_component_installer.h" +#include "components/component_updater/installer_policies/optimization_hints_component_installer.h" #include <utility> @@ -16,14 +16,10 @@ #include "base/test/task_environment.h" #include "base/threading/thread_task_runner_handle.h" #include "base/version.h" -#include "chrome/common/pref_names.h" -#include "chrome/test/base/testing_browser_process.h" #include "components/component_updater/mock_component_updater_service.h" #include "components/optimization_guide/core/optimization_guide_constants.h" #include "components/optimization_guide/core/optimization_guide_features.h" -#include "components/optimization_guide/core/optimization_guide_service.h" -#include "components/prefs/pref_registry_simple.h" -#include "components/prefs/testing_pref_service.h" +#include "components/optimization_guide/core/optimization_hints_component_update_listener.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/platform_test.h" @@ -31,30 +27,6 @@ static const char kTestHintsVersion[] = "1.2.3"; -class TestOptimizationGuideService - : public optimization_guide::OptimizationGuideService { - public: - explicit TestOptimizationGuideService( - scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner) - : optimization_guide::OptimizationGuideService(io_thread_task_runner) {} - ~TestOptimizationGuideService() override = default; - - void MaybeUpdateHintsComponent( - const optimization_guide::HintsComponentInfo& info) override { - hints_component_info_ = - std::make_unique<optimization_guide::HintsComponentInfo>(info); - } - - optimization_guide::HintsComponentInfo* hints_component_info() const { - return hints_component_info_.get(); - } - - private: - std::unique_ptr<optimization_guide::HintsComponentInfo> hints_component_info_; - - DISALLOW_COPY_AND_ASSIGN(TestOptimizationGuideService); -}; - class OptimizationHintsMockComponentUpdateService : public component_updater::MockComponentUpdateService { public: @@ -72,31 +44,16 @@ class OptimizationHintsComponentInstallerTest : public PlatformTest { public: OptimizationHintsComponentInstallerTest() = default; + ~OptimizationHintsComponentInstallerTest() override = default; void SetUp() override { PlatformTest::SetUp(); ASSERT_TRUE(component_install_dir_.CreateUniqueTempDir()); - auto optimization_guide_service = - std::make_unique<TestOptimizationGuideService>( - base::ThreadTaskRunnerHandle::Get()); - optimization_guide_service_ = optimization_guide_service.get(); - - TestingBrowserProcess::GetGlobal()->SetOptimizationGuideService( - std::move(optimization_guide_service)); policy_ = std::make_unique<OptimizationHintsComponentInstallerPolicy>(); } - void TearDown() override { - TestingBrowserProcess::GetGlobal()->SetOptimizationGuideService(nullptr); - PlatformTest::TearDown(); - } - - TestOptimizationGuideService* service() { - return optimization_guide_service_; - } - base::FilePath component_install_dir() { return component_install_dir_.GetPath(); } @@ -136,12 +93,9 @@ base::test::TaskEnvironment task_environment_; base::ScopedTempDir component_install_dir_; - std::unique_ptr<TestingPrefServiceSimple> pref_service_; std::unique_ptr<OptimizationHintsComponentInstallerPolicy> policy_; - TestOptimizationGuideService* optimization_guide_service_ = nullptr; - DISALLOW_COPY_AND_ASSIGN(OptimizationHintsComponentInstallerTest); }; @@ -153,7 +107,7 @@ std::unique_ptr<OptimizationHintsMockComponentUpdateService> cus( new OptimizationHintsMockComponentUpdateService()); EXPECT_CALL(*cus, RegisterComponent(testing::_)).Times(0); - RegisterOptimizationHintsComponent(cus.get(), false); + RegisterOptimizationHintsComponent(cus.get()); RunUntilIdle(); } @@ -167,32 +121,21 @@ EXPECT_CALL(*cus, RegisterComponent(testing::_)) .Times(1) .WillOnce(testing::Return(true)); - RegisterOptimizationHintsComponent(cus.get(), false); - RunUntilIdle(); -} - -TEST_F(OptimizationHintsComponentInstallerTest, - ComponentRegistrationWhenFeatureEnabledButOffTheRecordProfile) { - base::test::ScopedFeatureList scoped_list; - scoped_list.InitAndEnableFeature( - optimization_guide::features::kOptimizationHints); - std::unique_ptr<OptimizationHintsMockComponentUpdateService> cus( - new OptimizationHintsMockComponentUpdateService()); - EXPECT_CALL(*cus, RegisterComponent(testing::_)).Times(0); - RegisterOptimizationHintsComponent(cus.get(), true); + RegisterOptimizationHintsComponent(cus.get()); RunUntilIdle(); } TEST_F(OptimizationHintsComponentInstallerTest, NoRulesetFormatIgnored) { - ASSERT_TRUE(service()); ASSERT_NO_FATAL_FAILURE(CreateTestOptimizationHints("some hints")); ASSERT_NO_FATAL_FAILURE(LoadOptimizationHints(base::Version(""))); - EXPECT_EQ(nullptr, service()->hints_component_info()); + EXPECT_FALSE(optimization_guide::OptimizationHintsComponentUpdateListener:: + GetInstance() + ->hints_component_info() + .has_value()); } TEST_F(OptimizationHintsComponentInstallerTest, FutureRulesetFormatIgnored) { - ASSERT_TRUE(service()); ASSERT_NO_FATAL_FAILURE(CreateTestOptimizationHints("some hints")); base::Version version = ruleset_format_version(); const std::vector<uint32_t> future_ruleset_components = { @@ -201,18 +144,22 @@ ASSERT_NO_FATAL_FAILURE( LoadOptimizationHints(base::Version(future_ruleset_components))); - EXPECT_EQ(nullptr, service()->hints_component_info()); + EXPECT_FALSE(optimization_guide::OptimizationHintsComponentUpdateListener:: + GetInstance() + ->hints_component_info() + .has_value()); } TEST_F(OptimizationHintsComponentInstallerTest, LoadFileWithData) { - ASSERT_TRUE(service()); - const std::string expected_hints = "some hints"; ASSERT_NO_FATAL_FAILURE(CreateTestOptimizationHints(expected_hints)); ASSERT_NO_FATAL_FAILURE(LoadOptimizationHints(ruleset_format_version())); - auto* component_info = service()->hints_component_info(); - EXPECT_NE(nullptr, component_info); + base::Optional<optimization_guide::HintsComponentInfo> component_info = + optimization_guide::OptimizationHintsComponentUpdateListener:: + GetInstance() + ->hints_component_info(); + EXPECT_TRUE(component_info.has_value()); EXPECT_EQ(base::Version(kTestHintsVersion), component_info->version); std::string actual_hints; ASSERT_TRUE(base::ReadFileToString(component_info->path, &actual_hints));
diff --git a/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/FeatureConstants.java b/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/FeatureConstants.java index bf7134d..74bd827 100644 --- a/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/FeatureConstants.java +++ b/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/FeatureConstants.java
@@ -30,6 +30,7 @@ FeatureConstants.KEYBOARD_ACCESSORY_BAR_SWIPING_FEATURE, FeatureConstants.KEYBOARD_ACCESSORY_PASSWORD_FILLING_FEATURE, FeatureConstants.KEYBOARD_ACCESSORY_PAYMENT_FILLING_FEATURE, + FeatureConstants.KEYBOARD_ACCESSORY_PAYMENT_OFFER_FEATURE, FeatureConstants.DOWNLOAD_SETTINGS_FEATURE, FeatureConstants.DOWNLOAD_INFOBAR_DOWNLOAD_CONTINUING_FEATURE, FeatureConstants.DOWNLOAD_INFOBAR_DOWNLOADS_ARE_FASTER_FEATURE, @@ -60,6 +61,7 @@ String KEYBOARD_ACCESSORY_ADDRESS_FILL_FEATURE = "IPH_KeyboardAccessoryAddressFilling"; String KEYBOARD_ACCESSORY_PASSWORD_FILLING_FEATURE = "IPH_KeyboardAccessoryPasswordFilling"; String KEYBOARD_ACCESSORY_PAYMENT_FILLING_FEATURE = "IPH_KeyboardAccessoryPaymentFilling"; + String KEYBOARD_ACCESSORY_PAYMENT_OFFER_FEATURE = "IPH_KeyboardAccessoryPaymentOffer"; String KEYBOARD_ACCESSORY_BAR_SWIPING_FEATURE = "IPH_KeyboardAccessoryBarSwiping"; String PREVIEWS_OMNIBOX_UI_FEATURE = "IPH_PreviewsOmniboxUI"; String TRANSLATE_MENU_BUTTON_FEATURE = "IPH_TranslateMenuButton";
diff --git a/components/feature_engagement/public/feature_constants.cc b/components/feature_engagement/public/feature_constants.cc index fde7586..31f4000 100644 --- a/components/feature_engagement/public/feature_constants.cc +++ b/components/feature_engagement/public/feature_constants.cc
@@ -99,6 +99,8 @@ "IPH_KeyboardAccessoryPasswordFilling", base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kIPHKeyboardAccessoryPaymentFillingFeature{ "IPH_KeyboardAccessoryPaymentFilling", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kIPHKeyboardAccessoryPaymentOfferFeature{ + "IPH_KeyboardAccessoryPaymentOffer", base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kIPHNewTabPageHomeButtonFeature{ "IPH_NewTabPageHomeButton", base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kIPHPreviewsOmniboxUIFeature{
diff --git a/components/feature_engagement/public/feature_constants.h b/components/feature_engagement/public/feature_constants.h index c6bc56f2..57f5e07 100644 --- a/components/feature_engagement/public/feature_constants.h +++ b/components/feature_engagement/public/feature_constants.h
@@ -62,6 +62,7 @@ extern const base::Feature kIPHKeyboardAccessoryBarSwipingFeature; extern const base::Feature kIPHKeyboardAccessoryPasswordFillingFeature; extern const base::Feature kIPHKeyboardAccessoryPaymentFillingFeature; +extern const base::Feature kIPHKeyboardAccessoryPaymentOfferFeature; extern const base::Feature kIPHNewTabPageHomeButtonFeature; extern const base::Feature kIPHPreviewsOmniboxUIFeature; extern const base::Feature kIPHQuietNotificationPromptsFeature;
diff --git a/components/feature_engagement/public/feature_list.cc b/components/feature_engagement/public/feature_list.cc index 7b2f29d..ffd6921 100644 --- a/components/feature_engagement/public/feature_list.cc +++ b/components/feature_engagement/public/feature_list.cc
@@ -45,6 +45,7 @@ &kIPHKeyboardAccessoryBarSwipingFeature, &kIPHKeyboardAccessoryPasswordFillingFeature, &kIPHKeyboardAccessoryPaymentFillingFeature, + &kIPHKeyboardAccessoryPaymentOfferFeature, &kIPHNewTabPageHomeButtonFeature, &kIPHPreviewsOmniboxUIFeature, &kIPHPwaInstallAvailableFeature,
diff --git a/components/feature_engagement/public/feature_list.h b/components/feature_engagement/public/feature_list.h index 38fb616..aa5dd8f 100644 --- a/components/feature_engagement/public/feature_list.h +++ b/components/feature_engagement/public/feature_list.h
@@ -93,6 +93,8 @@ "IPH_KeyboardAccessoryPasswordFilling"); DEFINE_VARIATION_PARAM(kIPHKeyboardAccessoryPaymentFillingFeature, "IPH_KeyboardAccessoryPaymentFilling"); +DEFINE_VARIATION_PARAM(kIPHKeyboardAccessoryPaymentOfferFeature, + "IPH_KeyboardAccessoryPaymentOffer"); DEFINE_VARIATION_PARAM(kIPHNewTabPageButtonFeature, "IPH_NewTabPageHomeButton"); DEFINE_VARIATION_PARAM(kIPHPreviewsOmniboxUIFeature, "IPH_PreviewsOmniboxUI"); DEFINE_VARIATION_PARAM(kIPHPwaInstallAvailableFeature, @@ -196,6 +198,7 @@ VARIATION_ENTRY(kIPHKeyboardAccessoryBarSwipingFeature), VARIATION_ENTRY(kIPHKeyboardAccessoryPasswordFillingFeature), VARIATION_ENTRY(kIPHKeyboardAccessoryPaymentFillingFeature), + VARIATION_ENTRY(kIPHKeyboardAccessoryPaymentOfferFeature), VARIATION_ENTRY(kIPHNewTabPageButtonFeature), VARIATION_ENTRY(kIPHPreviewsOmniboxUIFeature), VARIATION_ENTRY(kIPHPwaInstallAvailableFeature),
diff --git a/components/feed/core/proto/BUILD.gn b/components/feed/core/proto/BUILD.gn index 9244b9ae..3221e2c 100644 --- a/components/feed/core/proto/BUILD.gn +++ b/components/feed/core/proto/BUILD.gn
@@ -23,6 +23,7 @@ #UNUSED_IN_CHROME "v2/wire/in_place_update_handle.proto", #UNUSED_IN_CHROME "v2/wire/response_status_code.proto", #UNUSED_IN_CHROME "v2/wire/templates.proto", + "v2/keyvalue_store.proto", "v2/packing.proto", "v2/store.proto", "v2/ui.proto",
diff --git a/components/feed/core/proto/v2/keyvalue_store.proto b/components/feed/core/proto/v2/keyvalue_store.proto new file mode 100644 index 0000000..7bdfbe4 --- /dev/null +++ b/components/feed/core/proto/v2/keyvalue_store.proto
@@ -0,0 +1,15 @@ +// Copyright 2020 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. + +syntax = "proto3"; + +package feedkvstore; + +option optimize_for = LITE_RUNTIME; + +message Entry { + bytes value = 1; + // Unix timetamp in milliseconds. + int64 modification_time = 2; +}
diff --git a/components/feed/core/v2/BUILD.gn b/components/feed/core/v2/BUILD.gn index 9fb5329a..d8bde6d 100644 --- a/components/feed/core/v2/BUILD.gn +++ b/components/feed/core/v2/BUILD.gn
@@ -31,6 +31,8 @@ "notice_card_tracker.h", "offline_page_spy.cc", "offline_page_spy.h", + "persistent_key_value_store_impl.cc", + "persistent_key_value_store_impl.h", "prefs.cc", "prefs.h", "proto_util.cc", @@ -41,6 +43,8 @@ "public/feed_service.h", "public/feed_stream_api.cc", "public/feed_stream_api.h", + "public/persistent_key_value_store.cc", + "public/persistent_key_value_store.h", "public/types.h", "refresh_task_scheduler.h", "request_throttler.cc", @@ -117,12 +121,14 @@ "image_fetcher_unittest.cc", "metrics_reporter_unittest.cc", "notice_card_tracker_unittest.cc", + "persistent_key_value_store_impl_unittest.cc", "proto_util_unittest.cc", "protocol_translator_unittest.cc", "public/feed_service_unittest.cc", "request_throttler_unittest.cc", "scheduling_unittest.cc", "stream_model_unittest.cc", + "test/callback_receiver.cc", "test/callback_receiver.h", "test/callback_receiver_unittest.cc", "test/proto_printer.cc",
diff --git a/components/feed/core/v2/config.h b/components/feed/core/v2/config.h index 1eb0d61..025b287 100644 --- a/components/feed/core/v2/config.h +++ b/components/feed/core/v2/config.h
@@ -44,6 +44,14 @@ base::TimeDelta session_id_max_age = base::TimeDelta::FromDays(30); // Maximum number of images prefetched per refresh. int max_prefetch_image_requests_per_refresh = 50; + + // Configuration for `PersistentKeyValueStore`. + + // Maximum total database size before items are evicted. + int64_t persistent_kv_store_maximum_size_before_eviction = 1000000; + // Eviction task is performed after this many bytes are written. + int persistent_kv_store_cleanup_interval_in_written_bytes = 1000000; + // Set of optional capabilities included in requests. See // CreateFeedQueryRequest() for required capabilities. base::flat_set<feedwire::Capability> experimental_capabilities = {
diff --git a/components/feed/core/v2/feed_stream.cc b/components/feed/core/v2/feed_stream.cc index 15e3d41..cc73904 100644 --- a/components/feed/core/v2/feed_stream.cc +++ b/components/feed/core/v2/feed_stream.cc
@@ -168,6 +168,7 @@ FeedNetwork* feed_network, ImageFetcher* image_fetcher, FeedStore* feed_store, + PersistentKeyValueStoreImpl* persistent_key_value_store, offline_pages::PrefetchService* prefetch_service, offline_pages::OfflinePageModel* offline_page_model, const ChromeInfo& chrome_info) @@ -179,6 +180,7 @@ feed_network_(feed_network), image_fetcher_(image_fetcher), store_(feed_store), + persistent_key_value_store_(persistent_key_value_store), chrome_info_(chrome_info), task_queue_(this), request_throttler_(profile_prefs), @@ -727,6 +729,10 @@ return image_fetcher_->Fetch(url, std::move(callback)); } +PersistentKeyValueStoreImpl* FeedStream::GetPersistentKeyValueStore() { + return persistent_key_value_store_; +} + void FeedStream::CancelImageFetch(ImageFetchId id) { image_fetcher_->Cancel(id); }
diff --git a/components/feed/core/v2/feed_stream.h b/components/feed/core/v2/feed_stream.h index 1a269812..e40d7a9 100644 --- a/components/feed/core/v2/feed_stream.h +++ b/components/feed/core/v2/feed_stream.h
@@ -20,6 +20,7 @@ #include "components/feed/core/proto/v2/wire/response.pb.h" #include "components/feed/core/v2/enums.h" #include "components/feed/core/v2/notice_card_tracker.h" +#include "components/feed/core/v2/persistent_key_value_store_impl.h" #include "components/feed/core/v2/protocol_translator.h" #include "components/feed/core/v2/public/feed_stream_api.h" #include "components/feed/core/v2/request_throttler.h" @@ -44,6 +45,7 @@ class MetricsReporter; class OfflinePageSpy; class RefreshTaskScheduler; +class PersistentKeyValueStoreImpl; class StreamModel; class SurfaceUpdater; struct StreamModelUpdateRequest; @@ -110,6 +112,7 @@ FeedNetwork* feed_network, ImageFetcher* image_fetcher, FeedStore* feed_store, + PersistentKeyValueStoreImpl* persistent_key_value_store, offline_pages::PrefetchService* prefetch_service, offline_pages::OfflinePageModel* offline_page_model, const ChromeInfo& chrome_info); @@ -135,6 +138,7 @@ const GURL& url, base::OnceCallback<void(NetworkResponse)> callback) override; void CancelImageFetch(ImageFetchId id) override; + PersistentKeyValueStoreImpl* GetPersistentKeyValueStore() override; void LoadMore(SurfaceId surface_id, base::OnceCallback<void(bool)> callback) override; void ExecuteOperations( @@ -327,6 +331,7 @@ FeedNetwork* feed_network_; ImageFetcher* image_fetcher_; FeedStore* store_; + PersistentKeyValueStoreImpl* persistent_key_value_store_; const WireResponseTranslator* wire_response_translator_; ChromeInfo chrome_info_;
diff --git a/components/feed/core/v2/feed_stream_unittest.cc b/components/feed/core/v2/feed_stream_unittest.cc index 78cbb82..ccb9683a 100644 --- a/components/feed/core/v2/feed_stream_unittest.cc +++ b/components/feed/core/v2/feed_stream_unittest.cc
@@ -26,6 +26,7 @@ #include "base/threading/sequenced_task_runner_handle.h" #include "base/time/clock.h" #include "components/feed/core/common/pref_names.h" +#include "components/feed/core/proto/v2/keyvalue_store.pb.h" #include "components/feed/core/proto/v2/store.pb.h" #include "components/feed/core/proto/v2/ui.pb.h" #include "components/feed/core/proto/v2/wire/chrome_client_info.pb.h" @@ -37,8 +38,10 @@ #include "components/feed/core/v2/feed_network.h" #include "components/feed/core/v2/image_fetcher.h" #include "components/feed/core/v2/metrics_reporter.h" +#include "components/feed/core/v2/persistent_key_value_store_impl.h" #include "components/feed/core/v2/prefs.h" #include "components/feed/core/v2/protocol_translator.h" +#include "components/feed/core/v2/public/persistent_key_value_store.h" #include "components/feed/core/v2/refresh_task_scheduler.h" #include "components/feed/core/v2/scheduling.h" #include "components/feed/core/v2/stream_model.h" @@ -593,8 +596,9 @@ // Ensure the task queue can return to idle. Failure to do so may be due // to a stuck task that never called |TaskComplete()|. WaitForIdleTaskQueue(); - // Store requires PostTask to clean up. + // ProtoDatabase requires PostTask to clean up. store_.reset(); + persistent_key_value_store_.reset(); task_environment_.RunUntilIdle(); } @@ -625,7 +629,8 @@ chrome_info.version = base::Version({99, 1, 9911, 2}); stream_ = std::make_unique<FeedStream>( &refresh_scheduler_, metrics_reporter_.get(), this, &profile_prefs_, - &network_, image_fetcher_.get(), store_.get(), &prefetch_service_, + &network_, image_fetcher_.get(), store_.get(), + persistent_key_value_store_.get(), &prefetch_service_, &offline_page_model_, chrome_info); WaitForIdleTaskQueue(); // Wait for any initialization. @@ -694,8 +699,16 @@ std::unique_ptr<FeedStore> store_ = std::make_unique<FeedStore>( leveldb_proto::ProtoDatabaseProvider::GetUniqueDB<feedstore::Record>( leveldb_proto::ProtoDbType::FEED_STREAM_DATABASE, - /*file_path=*/{}, + /*db_dir=*/{}, task_environment_.GetMainThreadTaskRunner())); + + std::unique_ptr<PersistentKeyValueStoreImpl> persistent_key_value_store_ = + std::make_unique<PersistentKeyValueStoreImpl>( + leveldb_proto::ProtoDatabaseProvider::GetUniqueDB<feedkvstore::Entry>( + leveldb_proto::ProtoDbType::FEED_KEY_VALUE_DATABASE, + /*db_dir=*/{}, + task_environment_.GetMainThreadTaskRunner())); + FakeRefreshTaskScheduler refresh_scheduler_; TestPrefetchService prefetch_service_; TestOfflinePageModel offline_page_model_; @@ -2789,5 +2802,22 @@ EXPECT_TIME_EQ(kExpiryTime, stream_->GetMetadata()->GetSessionIdExpiryTime()); } +TEST_F(FeedStreamTest, PersistentKeyValueStoreIsClearedOnClearAll) { + // Store some data and verify it exists. + PersistentKeyValueStore* store = stream_->GetPersistentKeyValueStore(); + store->Put("x", "y", base::DoNothing()); + CallbackReceiver<PersistentKeyValueStore::Result> get_result; + store->Get("x", get_result.Bind()); + ASSERT_EQ("y", *get_result.RunAndGetResult().get_result); + + stream_->OnCacheDataCleared(); // triggers ClearAll(). + WaitForIdleTaskQueue(); + + // Verify ClearAll() deleted the data. + get_result.Clear(); + store->Get("x", get_result.Bind()); + EXPECT_FALSE(get_result.RunAndGetResult().get_result); +} + } // namespace } // namespace feed
diff --git a/components/feed/core/v2/persistent_key_value_store_impl.cc b/components/feed/core/v2/persistent_key_value_store_impl.cc new file mode 100644 index 0000000..7be37daf --- /dev/null +++ b/components/feed/core/v2/persistent_key_value_store_impl.cc
@@ -0,0 +1,325 @@ +// Copyright 2020 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 "components/feed/core/v2/persistent_key_value_store_impl.h" + +#include <vector> + +#include "base/bind.h" +#include "base/rand_util.h" +#include "base/time/time.h" +#include "components/feed/core/proto/v2/keyvalue_store.pb.h" +#include "components/feed/core/v2/config.h" +#include "components/offline_pages/task/task.h" + +namespace feed { +namespace { +using ::feed::internal::kMaxEntriesInMemory; +using feedkvstore::Entry; +} // namespace + +// Eviction task functionality. +class EvictTask { + public: + static void Start(base::WeakPtr<PersistentKeyValueStoreImpl> store, + base::OnceCallback<void(bool)> done_callback) { + auto state = std::make_unique<State>(); + state->store = store; + state->done_callback = std::move(done_callback); + + auto* db = GetDbOrFinish(state); + if (!db) + return; + db->LoadKeys(base::BindOnce(&EvictTask::LoadKeysDone, std::move(state))); + } + + private: + struct EntryMetadata { + std::string key; + int64_t size_bytes; + int64_t modification_time; + }; + + struct State { + base::WeakPtr<PersistentKeyValueStoreImpl> store; + base::OnceCallback<void(bool)> done_callback; + + std::vector<std::string> all_keys; + size_t next_key_index = 0; + std::vector<EntryMetadata> metadata; + }; + + static void Finish(std::unique_ptr<State> state) { + std::move(state->done_callback).Run(true); + } + + static leveldb_proto::ProtoDatabase<Entry>* GetDbOrFinish( + std::unique_ptr<State>& state) { + if (state->store) { + return state->store->GetDatabase(); + } + Finish(std::move(state)); + return nullptr; + } + + static void IndexMore(std::unique_ptr<State> state) { + auto* db = GetDbOrFinish(state); + if (!db) + return; + if (state->next_key_index >= state->all_keys.size()) { + IndexingDone(std::move(state)); + return; + } + const size_t first_index = state->next_key_index; + std::string last_key; + state->next_key_index = std::min( + state->next_key_index + kMaxEntriesInMemory, state->all_keys.size()); + + std::string lower_bound = state->all_keys[first_index], + upper_bound = state->all_keys[state->next_key_index - 1]; + db->LoadKeysAndEntriesInRange( + lower_bound, upper_bound, + base::BindOnce(&EvictTask::IndexMore_LoadChunkDone, std::move(state))); + } + + static void IndexMore_LoadChunkDone( + std::unique_ptr<State> state, + bool ok, + std::unique_ptr<std::map<std::string, feedkvstore::Entry>> entries) { + const int64_t now = + base::Time::Now().ToDeltaSinceWindowsEpoch().InMilliseconds(); + for (auto& entry : *entries) { + EntryMetadata m; + m.key = entry.first; + m.modification_time = entry.second.modification_time(); + // If modification time is in the future, assume the information is out + // of date. + if (m.modification_time > now) + m.modification_time = 0; + m.size_bytes = entry.second.value().size(); + state->metadata.push_back(m); + } + IndexMore(std::move(state)); + } + + static void LoadKeysDone(std::unique_ptr<State> state, + bool ok, + std::unique_ptr<std::vector<std::string>> keys) { + if (!ok || !keys) { + Finish(std::move(state)); + return; + } + state->all_keys = std::move(*keys); + IndexMore(std::move(state)); + } + + static void IndexingDone(std::unique_ptr<State> state) { + auto* db = GetDbOrFinish(state); + if (!db) + return; + std::sort(state->metadata.begin(), state->metadata.end(), + [&](const EntryMetadata& a, const EntryMetadata& b) { + return a.modification_time > b.modification_time; + }); + + size_t i = 0; + int64_t total_size = 0; + const int64_t max_db_size_bytes = + GetFeedConfig().persistent_kv_store_maximum_size_before_eviction; + for (; i < state->metadata.size(); ++i) { + total_size += state->metadata[i].size_bytes; + if (total_size > max_db_size_bytes) { + break; + } + } + + auto keys_to_remove = std::make_unique<std::vector<std::string>>(); + for (; i < state->metadata.size(); ++i) { + keys_to_remove->push_back(state->metadata[i].key); + } + + db->UpdateEntries( + std::make_unique<std::vector<std::pair<std::string, Entry>>>(), + std::move(keys_to_remove), + base::BindOnce([](std::unique_ptr<State> state, + bool ok) { Finish(std::move(state)); }, + std::move(state))); + } +}; + +PersistentKeyValueStoreImpl::Task::Task() = default; +PersistentKeyValueStoreImpl::Task::Task(TaskType task_type, + ResultCallback callback) + : Task(task_type, std::string(), std::move(callback)) {} +PersistentKeyValueStoreImpl::Task::Task(TaskType task_type, + std::string key, + ResultCallback callback) + : type(task_type), key(key), done_callback(std::move(callback)) {} +PersistentKeyValueStoreImpl::Task::Task(Task&&) noexcept = default; +PersistentKeyValueStoreImpl::Task::~Task() = default; + +PersistentKeyValueStoreImpl::PersistentKeyValueStoreImpl( + std::unique_ptr<leveldb_proto::ProtoDatabase<feedkvstore::Entry>> database) + : database_(std::move(database)) {} + +PersistentKeyValueStoreImpl::~PersistentKeyValueStoreImpl() = default; + +void PersistentKeyValueStoreImpl::OnDatabaseInitialized( + leveldb_proto::Enums::InitStatus status) { + database_status_ = status; + TaskComplete({}, {}); +} + +bool PersistentKeyValueStoreImpl::IsInitialized() const { + return database_status_ == leveldb_proto::Enums::InitStatus::kOK; +} + +void PersistentKeyValueStoreImpl::AddTask(Task task) { + if (!triggered_initialize_) { + triggered_initialize_ = true; + running_task_ = true; + database_->Init(base::BindOnce( + &PersistentKeyValueStoreImpl::OnDatabaseInitialized, GetWeakPtr())); + } + if (!running_task_) { + StartTask(std::move(task)); + } else { + queued_tasks_.push(std::move(task)); + } +} + +void PersistentKeyValueStoreImpl::ClearAll(ResultCallback callback) { + AddTask({TaskType::kClearAll, std::move(callback)}); +} + +void PersistentKeyValueStoreImpl::Put(const std::string& key, + const std::string& value, + ResultCallback callback) { + // Use a random number to trigger EvictOldEntries(). + // The expected number of calls to EvictOldEntries() is =~ + // (sum of bytes written) / `cleanup_interval_in_written_bytes`. + int cleanup_interval_in_written_bytes = + GetFeedConfig().persistent_kv_store_cleanup_interval_in_written_bytes; + int rand_int = base::RandInt(0, cleanup_interval_in_written_bytes); + if (cleanup_interval_in_written_bytes > 0 && + rand_int < static_cast<int>(value.size())) { + EvictOldEntries(base::DoNothing()); + } + Task task(TaskType::kPut, key, std::move(callback)); + task.put_value = value; + AddTask(std::move(task)); +} + +void PersistentKeyValueStoreImpl::Get(const std::string& key, + ResultCallback callback) { + AddTask({TaskType::kGet, key, std::move(callback)}); +} + +void PersistentKeyValueStoreImpl::Delete(const std::string& key, + ResultCallback callback) { + AddTask({TaskType::kDelete, key, std::move(callback)}); +} + +void PersistentKeyValueStoreImpl::EvictOldEntries(ResultCallback callback) { + AddTask({TaskType::kEvictOldEntries, std::move(callback)}); +} + +void PersistentKeyValueStoreImpl::StartTask(Task task) { + if (!IsInitialized()) { + TaskComplete(std::move(task), {}); + return; + } + running_task_ = true; + + switch (task.type) { + case TaskType::kGet: { + std::string key = std::move(task.key); + database_->GetEntry(key, + base::BindOnce(&PersistentKeyValueStoreImpl::GetDone, + GetWeakPtr(), std::move(task))); + break; + } + case TaskType::kPut: { + auto entries_to_save = std::make_unique< + leveldb_proto::ProtoDatabase<feedkvstore::Entry>::KeyEntryVector>(); + { + feedkvstore::Entry new_entry; + new_entry.set_value(std::move(task.put_value)); + new_entry.set_modification_time( + base::Time::Now().ToDeltaSinceWindowsEpoch().InMilliseconds()); + entries_to_save->emplace_back(task.key, std::move(new_entry)); + } + database_->UpdateEntries( + std::move(entries_to_save), + /*keys_to_remove=*/std::make_unique<std::vector<std::string>>(), + base::BindOnce(&PersistentKeyValueStoreImpl::TaskCompleteBool, + GetWeakPtr(), std::move(task))); + break; + } + case TaskType::kDelete: { + auto keys_to_remove = std::make_unique<std::vector<std::string>>(); + keys_to_remove->push_back(task.key); + database_->UpdateEntries( + std::make_unique<std::vector<std::pair<std::string, Entry>>>(), + std::move(keys_to_remove), + base::BindOnce(&PersistentKeyValueStoreImpl::TaskCompleteBool, + GetWeakPtr(), std::move(task))); + break; + } + case TaskType::kClearAll: { + auto filter = [](const std::string& key) { return true; }; + database_->UpdateEntriesWithRemoveFilter( + std::make_unique< + std::vector<std::pair<std::string, feedkvstore::Entry>>>(), + base::BindRepeating(filter), + base::BindOnce(&PersistentKeyValueStoreImpl::TaskCompleteBool, + GetWeakPtr(), std::move(task))); + break; + } + case TaskType::kEvictOldEntries: { + EvictTask::Start( + GetWeakPtr(), + base::BindOnce(&PersistentKeyValueStoreImpl::TaskCompleteBool, + GetWeakPtr(), std::move(task))); + break; + } + } +} + +void PersistentKeyValueStoreImpl::GetDone( + Task task, + bool ok, + std::unique_ptr<feedkvstore::Entry> get_entry) { + Result result; + if (ok && get_entry) { + result.success = true; + result.get_result = std::move(get_entry->value()); + } else { + result.success = ok; + } + TaskComplete(std::move(task), std::move(result)); +} + +void PersistentKeyValueStoreImpl::TaskComplete(Task complete_task, + Result result) { + if (complete_task.done_callback) { + std::move(complete_task.done_callback).Run(std::move(result)); + } + if (queued_tasks_.empty()) { + running_task_ = false; + return; + } + Task new_task = std::move(queued_tasks_.front()); + queued_tasks_.pop(); + StartTask(std::move(new_task)); +} + +void PersistentKeyValueStoreImpl::TaskCompleteBool(Task complete_task, + bool ok) { + Result result; + result.success = ok; + return TaskComplete(std::move(complete_task), std::move(result)); +} + +} // namespace feed
diff --git a/components/feed/core/v2/persistent_key_value_store_impl.h b/components/feed/core/v2/persistent_key_value_store_impl.h new file mode 100644 index 0000000..520b760 --- /dev/null +++ b/components/feed/core/v2/persistent_key_value_store_impl.h
@@ -0,0 +1,115 @@ +// Copyright 2020 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 COMPONENTS_FEED_CORE_V2_PERSISTENT_KEY_VALUE_STORE_IMPL_H_ +#define COMPONENTS_FEED_CORE_V2_PERSISTENT_KEY_VALUE_STORE_IMPL_H_ + +#include <list> +#include <memory> +#include <string> + +#include "base/callback.h" +#include "base/memory/weak_ptr.h" +#include "base/optional.h" +#include "components/feed/core/v2/public/persistent_key_value_store.h" +#include "components/leveldb_proto/public/proto_database.h" +#include "components/leveldb_proto/public/proto_database_provider.h" +#include "components/offline_pages/task/task_queue.h" + +namespace feedkvstore { +class Entry; +} +namespace feed { +namespace internal { +constexpr int kMaxEntriesInMemory = 50; +} // namespace internal + +// A generic persistent key-value cache. Has a maximum size determined by +// `feed::Config`. Once size of all values exceed the maximum, older keys +// are eventually evicted. Key age is determined only by the last call to +// `Put()`. +class PersistentKeyValueStoreImpl : public PersistentKeyValueStore { + public: + using Result = PersistentKeyValueStore::Result; + using ResultCallback = base::OnceCallback<void(Result)>; + + explicit PersistentKeyValueStoreImpl( + std::unique_ptr<leveldb_proto::ProtoDatabase<feedkvstore::Entry>> + database); + ~PersistentKeyValueStoreImpl() override; + PersistentKeyValueStoreImpl(const PersistentKeyValueStoreImpl&) = delete; + PersistentKeyValueStoreImpl& operator=(const PersistentKeyValueStoreImpl&) = + delete; + + // PersistentKeyValueStore methods. + + // Erase all data in the store. + void ClearAll(ResultCallback callback) override; + // Write/overwrite a key/value pair. + void Put(const std::string& key, + const std::string& value, + ResultCallback callback) override; + // Get a value by key. + void Get(const std::string& key, ResultCallback callback) override; + // Delete a value by key. + void Delete(const std::string& key, ResultCallback callback) override; + + // Evict old stored entries until total size of all values in the database + // is less than max_db_size_bytes. + void EvictOldEntries(ResultCallback callback); + + leveldb_proto::ProtoDatabase<feedkvstore::Entry>* GetDatabase() { + return database_.get(); + } + + base::WeakPtr<PersistentKeyValueStoreImpl> GetWeakPtr() { + return weak_ptr_factory_.GetWeakPtr(); + } + + bool IsTaskRunningForTesting() const { return running_task_; } + + private: + enum class TaskType { kGet, kPut, kDelete, kClearAll, kEvictOldEntries }; + // Represents any operation on the database. Allows us to easily perform lazy + // initialization, and serialize db operations. + struct Task { + Task(); + Task(TaskType type, ResultCallback callback); + Task(TaskType type, std::string key, ResultCallback callback); + Task(Task&&) noexcept; + Task(const Task&) = delete; + Task& operator=(const Task&) = delete; + ~Task(); + + TaskType type; + // Key for kGet, kPut, and kDelete. + std::string key; + // Value for kPut. + std::string put_value; + ResultCallback done_callback; + }; + + void AddTask(Task task); + // Implementation functions for potentially queueable actions. + void StartTask(Task task); + + void GetDone(Task task, bool ok, std::unique_ptr<feedkvstore::Entry> entry); + void OnDatabaseInitialized(leveldb_proto::Enums::InitStatus status); + void TaskComplete(Task task, Result result); + void TaskCompleteBool(Task task, bool ok); + + bool IsInitialized() const; + + bool running_task_ = false; + base::queue<Task> queued_tasks_; + bool triggered_initialize_ = false; + leveldb_proto::Enums::InitStatus database_status_ = + leveldb_proto::Enums::InitStatus::kNotInitialized; + std::unique_ptr<leveldb_proto::ProtoDatabase<feedkvstore::Entry>> database_; + base::WeakPtrFactory<PersistentKeyValueStoreImpl> weak_ptr_factory_{this}; +}; + +} // namespace feed + +#endif // COMPONENTS_FEED_CORE_V2_PERSISTENT_KEY_VALUE_STORE_IMPL_H_
diff --git a/components/feed/core/v2/persistent_key_value_store_impl_unittest.cc b/components/feed/core/v2/persistent_key_value_store_impl_unittest.cc new file mode 100644 index 0000000..2f9b3a4 --- /dev/null +++ b/components/feed/core/v2/persistent_key_value_store_impl_unittest.cc
@@ -0,0 +1,411 @@ +// Copyright 2020 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 "components/feed/core/v2/persistent_key_value_store_impl.h" + +#include <map> +#include <set> +#include <utility> + +#include "base/hash/hash.h" +#include "base/run_loop.h" +#include "base/strings/string_number_conversions.h" +#include "base/test/bind.h" +#include "base/test/task_environment.h" +#include "components/feed/core/proto/v2/keyvalue_store.pb.h" +#include "components/feed/core/v2/config.h" +#include "components/feed/core/v2/public/persistent_key_value_store.h" +#include "components/feed/core/v2/test/callback_receiver.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace feed { +namespace { +using ::feed::internal::kMaxEntriesInMemory; + +int hash_int(int v) { + return static_cast<int>(base::PersistentHash(base::NumberToString(v))); +} + +class PersistentKeyValueStoreTest : public testing::Test { + public: + void SetUp() override { + // Disable automatic cleanup for deterministic testing. + Config config = GetFeedConfig(); + config.persistent_kv_store_cleanup_interval_in_written_bytes = 0; + SetFeedConfigForTesting(config); + MakeStore(); + } + + void TearDown() override { + if (store_) { + ASSERT_FALSE(store_->IsTaskRunningForTesting()); + } + // ProtoDatabase requires PostTask to clean up. + store_.reset(); + base::RunLoop().RunUntilIdle(); + } + + protected: + void MakeStore() { + store_ = std::make_unique<PersistentKeyValueStoreImpl>( + leveldb_proto::ProtoDatabaseProvider::GetUniqueDB<feedkvstore::Entry>( + leveldb_proto::ProtoDbType::FEED_STREAM_DATABASE, + /*db_dir=*/{}, task_environment_.GetMainThreadTaskRunner())); + } + + void SetMaxSizeBeforeEviction(int size_in_bytes) { + Config config = GetFeedConfig(); + config.persistent_kv_store_maximum_size_before_eviction = size_in_bytes; + SetFeedConfigForTesting(config); + } + + void Put(const std::string& key, const std::string& value) { + CallbackReceiver<PersistentKeyValueStore::Result> callback; + store_->Put(key, value, callback.Bind()); + ASSERT_TRUE(callback.RunAndGetResult().success); + } + + std::string Get(const std::string& key) { + CallbackReceiver<PersistentKeyValueStore::Result> callback; + store_->Get(key, callback.Bind()); + return callback.RunAndGetResult().get_result.value_or("<not-found>"); + } + + std::map<std::string, std::string> GetAllEntries() { + // Make sure any queued tasks are complete. + base::RunLoop().RunUntilIdle(); + std::map<std::string, std::string> result; + auto callback = + [&](bool ok, + std::unique_ptr<std::map<std::string, feedkvstore::Entry>> data) { + CHECK(ok); + for (auto& entry : *data) { + result.emplace(entry.first, entry.second.value()); + } + }; + store_->GetDatabase()->LoadKeysAndEntries( + base::BindLambdaForTesting(callback)); + + base::RunLoop().RunUntilIdle(); + return result; + } + + base::test::TaskEnvironment task_environment_{ + base::test::TaskEnvironment::TimeSource::MOCK_TIME}; + std::unique_ptr<PersistentKeyValueStoreImpl> store_; +}; + +TEST_F(PersistentKeyValueStoreTest, Put) { + CallbackReceiver<PersistentKeyValueStore::Result> callback; + store_->Put("x", "y", callback.Bind()); + + ASSERT_TRUE(callback.RunAndGetResult().success); + EXPECT_EQ((std::map<std::string, std::string>{{"x", "y"}}), GetAllEntries()); +} + +TEST_F(PersistentKeyValueStoreTest, GetEmptyKey) { + CallbackReceiver<PersistentKeyValueStore::Result> callback; + store_->Get("", callback.Bind()); + + EXPECT_TRUE(callback.RunAndGetResult().success); + EXPECT_FALSE(callback.GetResult()->get_result); +} + +TEST_F(PersistentKeyValueStoreTest, GetKeyNotPresent) { + CallbackReceiver<PersistentKeyValueStore::Result> callback; + store_->Get("x", callback.Bind()); + + EXPECT_TRUE(callback.RunAndGetResult().success); + EXPECT_FALSE(callback.GetResult()->get_result); +} + +TEST_F(PersistentKeyValueStoreTest, GetKeyPresent) { + Put("x", "y"); + + CallbackReceiver<PersistentKeyValueStore::Result> callback; + store_->Get("x", callback.Bind()); + EXPECT_TRUE(callback.RunAndGetResult().success); + EXPECT_EQ("y", callback.RunAndGetResult().get_result); +} + +TEST_F(PersistentKeyValueStoreTest, Delete) { + Put("x", "y"); + + CallbackReceiver<PersistentKeyValueStore::Result> callback; + store_->Delete("x", callback.Bind()); + EXPECT_TRUE(callback.RunAndGetResult().success); + EXPECT_EQ("<not-found>", Get("x")); +} + +TEST_F(PersistentKeyValueStoreTest, DeleteNotPresent) { + Put("x", "y"); + + CallbackReceiver<PersistentKeyValueStore::Result> callback; + store_->Delete("y", callback.Bind()); + EXPECT_TRUE(callback.RunAndGetResult().success); + EXPECT_EQ("y", Get("x")); +} + +TEST_F(PersistentKeyValueStoreTest, ClearAll) { + Put("x", "y"); + Put("a", "b"); + + CallbackReceiver<PersistentKeyValueStore::Result> callback; + store_->ClearAll(callback.Bind()); + EXPECT_TRUE(callback.RunAndGetResult().success); + + EXPECT_EQ((std::map<std::string, std::string>{}), GetAllEntries()); +} + +TEST_F(PersistentKeyValueStoreTest, EvictOldEntriesOnEmptyDatabaseDoesntCrash) { + CallbackReceiver<PersistentKeyValueStore::Result> callback; + store_->EvictOldEntries(callback.Bind()); + EXPECT_TRUE(callback.RunAndGetResult().success); +} + +TEST_F(PersistentKeyValueStoreTest, EvictOldEntriesBelowSizeLimit) { + Put("x", "12345"); + + // Set config db size limit to equal size of 'x'. + SetMaxSizeBeforeEviction(5); + CallbackReceiver<PersistentKeyValueStore::Result> callback; + store_->EvictOldEntries(callback.Bind()); + EXPECT_TRUE(callback.RunAndGetResult().success); + + EXPECT_EQ((std::map<std::string, std::string>{{"x", "12345"}}), + GetAllEntries()); +} + +TEST_F(PersistentKeyValueStoreTest, EvictOldEntriesAboveSizeLimit) { + Put("x", "12345"); + + // Set config db size limit to just below size of 'x'. + SetMaxSizeBeforeEviction(4); + CallbackReceiver<PersistentKeyValueStore::Result> callback; + store_->EvictOldEntries(callback.Bind()); + EXPECT_TRUE(callback.RunAndGetResult().success); + + EXPECT_EQ((std::map<std::string, std::string>{}), GetAllEntries()); +} + +TEST_F(PersistentKeyValueStoreTest, PutAndGetAreQueuedWhileEvicting) { + SetMaxSizeBeforeEviction(0); + std::vector<std::string> calls; + auto record_call = base::BindLambdaForTesting( + [&](std::string label, PersistentKeyValueStore::Result) { + calls.push_back(label); + }); + store_->Put("x", "12345", base::BindOnce(record_call, "put1")); + store_->EvictOldEntries(base::BindOnce(record_call, "evict")); + store_->Put("y", "123456", base::BindOnce(record_call, "put2")); + std::string get_result = Get("y"); + + EXPECT_EQ(std::vector<std::string>({"put1", "evict", "put2"}), calls); + EXPECT_EQ((std::map<std::string, std::string>{ + {"y", "123456"}, + }), + GetAllEntries()); + EXPECT_EQ("123456", get_result); +} + +TEST_F(PersistentKeyValueStoreTest, EvictOldEntriesDeletesOldEntriesFirst) { + Put("1", "x"); + task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(1)); + Put("2", "x"); + + SetMaxSizeBeforeEviction(1); + store_->EvictOldEntries(base::DoNothing()); + + EXPECT_EQ((std::map<std::string, std::string>{{"2", "x"}}), GetAllEntries()); +} + +TEST_F(PersistentKeyValueStoreTest, + EvictOldEntriesDeletesOldEntriesFirstReverseKeys) { + Put("2", "x"); + task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(1)); + Put("1", "x"); + + SetMaxSizeBeforeEviction(1); + store_->EvictOldEntries(base::DoNothing()); + + EXPECT_EQ((std::map<std::string, std::string>{{"1", "x"}}), GetAllEntries()); +} + +TEST_F(PersistentKeyValueStoreTest, EvictOldEntriesDeleteFutureEntriesFirst) { + // Insert two entries manually. The second entry has a modification time in + // the future, so it will be evicted preferentially. + { + // Trigger and wait for db initialization. + Get("foo"); + + auto entries_to_save = std::make_unique< + leveldb_proto::ProtoDatabase<feedkvstore::Entry>::KeyEntryVector>(); + { + feedkvstore::Entry new_entry; + new_entry.set_value("1"); + new_entry.set_modification_time( + (base::Time::Now().ToDeltaSinceWindowsEpoch()).InMilliseconds()); + entries_to_save->emplace_back("key1", std::move(new_entry)); + } + { + feedkvstore::Entry new_entry; + new_entry.set_value("2"); + new_entry.set_modification_time( + (base::Time::Now().ToDeltaSinceWindowsEpoch() + + base::TimeDelta::FromMinutes(1)) + .InMilliseconds()); + entries_to_save->emplace_back("key2", std::move(new_entry)); + } + + CallbackReceiver<bool> callback; + store_->GetDatabase()->UpdateEntries( + std::move(entries_to_save), + /*keys_to_remove=*/std::make_unique<std::vector<std::string>>(), + callback.Bind()); + ASSERT_TRUE(callback.RunAndGetResult()); + } + + SetMaxSizeBeforeEviction(1); + store_->EvictOldEntries(base::DoNothing()); + + EXPECT_EQ((std::map<std::string, std::string>{{"key1", "1"}}), + GetAllEntries()); +} + +TEST_F(PersistentKeyValueStoreTest, EvictOldEntriesManyEntries) { + const int kFinalEntryCount = kMaxEntriesInMemory * 2; + const int kInitialEntryCount = kFinalEntryCount + kMaxEntriesInMemory / 2; + + for (int i = 0; i < kInitialEntryCount; ++i) { + // Make key order different than insertion order. + int key = hash_int(i); + Put(base::NumberToString(key), "x"); + task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(1)); + } + + SetMaxSizeBeforeEviction(kFinalEntryCount); + store_->EvictOldEntries(base::DoNothing()); + + std::map<std::string, std::string> want_entries; + for (int i = kInitialEntryCount - kFinalEntryCount; i < kInitialEntryCount; + ++i) { + want_entries[base::NumberToString(hash_int(i))] = "x"; + } + EXPECT_EQ(want_entries, GetAllEntries()); +} + +TEST_F(PersistentKeyValueStoreTest, EvictOldEntriesExactlyMaxEntriesInMemory) { + for (int i = 0; i < kMaxEntriesInMemory; ++i) { + // Make key order different than insertion order. + int key = hash_int(i); + Put(base::NumberToString(key), "x"); + task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(1)); + } + + SetMaxSizeBeforeEviction(kMaxEntriesInMemory - 1); + store_->EvictOldEntries(base::DoNothing()); + + std::map<std::string, std::string> want_entries; + for (int i = 1; i < kMaxEntriesInMemory; ++i) { + want_entries[base::NumberToString(hash_int(i))] = "x"; + } + EXPECT_EQ(want_entries, GetAllEntries()); +} + +TEST_F(PersistentKeyValueStoreTest, EvictOldEntriesMaxEntriesInMemoryPlusOne) { + for (int i = 0; i < kMaxEntriesInMemory + 1; ++i) { + // Make key order different than insertion order. + int key = hash_int(i); + Put(base::NumberToString(key), "x"); + task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(1)); + } + + SetMaxSizeBeforeEviction(kMaxEntriesInMemory + 1 - 1); + store_->EvictOldEntries(base::DoNothing()); + + std::map<std::string, std::string> want_entries; + for (int i = 1; i < kMaxEntriesInMemory + 1; ++i) { + want_entries[base::NumberToString(hash_int(i))] = "x"; + } + EXPECT_EQ(want_entries, GetAllEntries()); +} + +void CallAfterNPostTasks(int post_task_count, base::OnceClosure done) { + if (post_task_count == 0) { + std::move(done).Run(); + } else { + base::SequencedTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::BindOnce(base::BindOnce(&CallAfterNPostTasks, post_task_count - 1, + std::move(done)))); + } +} + +// Test that `EvictOldEntries()` completes without crashing, even when the +// store is deleted between posted tasks. +TEST_F(PersistentKeyValueStoreTest, DeleteStoreWhileEvictOldEntriesIsRunning) { + SetMaxSizeBeforeEviction(kMaxEntriesInMemory + 1); + + constexpr int kMaxPostTasks = 32; // Today, must be at least 16. + for (int post_tasks_before_delete = 0; + post_tasks_before_delete < kMaxPostTasks; ++post_tasks_before_delete) { + MakeStore(); + for (int i = 0; i < kMaxEntriesInMemory + 1; ++i) { + Put(base::NumberToString(i), "x"); + task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(1)); + } + // Call EvictOldEntries(), and then eventually delete the store while + // EvictOldEntries() is running. If EvictOldEntries() completes first, + // then exit the loop because we've tried all possible orderings. + base::RunLoop run_loop; + bool evict_complete = false, delete_complete = false; + bool evict_complete_first = false; + auto complete_func = [&](bool is_evict_call) { + evict_complete |= is_evict_call; + delete_complete |= !is_evict_call; + if (evict_complete && delete_complete) { + evict_complete_first = !is_evict_call; + run_loop.QuitClosure().Run(); + } + }; + store_->EvictOldEntries(base::BindLambdaForTesting( + [&](PersistentKeyValueStore::Result) { complete_func(true); })); + CallAfterNPostTasks(post_tasks_before_delete, + base::BindLambdaForTesting([&]() { + store_.reset(); + complete_func(false); + })); + run_loop.RunUntilIdle(); + if (evict_complete_first) { + ASSERT_GT(post_tasks_before_delete, 2) + << "EvictOldEntries completed with fewer post tasks than expected"; + return; + } + } + ASSERT_TRUE(false) + << "EvictOldEntries didn't complete after kMaxPostTasks post tasks?"; +} + +TEST_F(PersistentKeyValueStoreTest, DataStoreCleansOldDataAutomatically) { + // Simulate use of the store by inserting 10 byte entries. On average, we + // should perform eviction on every 10 Put() calls -- with a 1/10 chance on + // each call. We have a negligible probability of ~1.0e-46 of failing to run + // eviction after 1000 iterations. + Config config = GetFeedConfig(); + config.persistent_kv_store_cleanup_interval_in_written_bytes = 100; + config.persistent_kv_store_maximum_size_before_eviction = 10; + SetFeedConfigForTesting(config); + MakeStore(); + + for (int i = 0;; ++i) { + ASSERT_LT(i, 1000); + Put(base::NumberToString(i), "1234567890"); + task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(1)); + if (Get("0") == "<not-found>") + break; + } +} + +} // namespace +} // namespace feed
diff --git a/components/feed/core/v2/public/feed_service.cc b/components/feed/core/v2/public/feed_service.cc index 135f2313..4c14bfd 100644 --- a/components/feed/core/v2/public/feed_service.cc +++ b/components/feed/core/v2/public/feed_service.cc
@@ -15,6 +15,7 @@ #include "components/feed/core/v2/feed_stream.h" #include "components/feed/core/v2/image_fetcher.h" #include "components/feed/core/v2/metrics_reporter.h" +#include "components/feed/core/v2/persistent_key_value_store_impl.h" #include "components/feed/core/v2/refresh_task_scheduler.h" #include "components/feed/feed_feature_list.h" #include "components/history/core/browser/history_service.h" @@ -181,6 +182,8 @@ PrefService* profile_prefs, PrefService* local_state, std::unique_ptr<leveldb_proto::ProtoDatabase<feedstore::Record>> database, + std::unique_ptr<leveldb_proto::ProtoDatabase<feedkvstore::Entry>> + key_value_store_database, signin::IdentityManager* identity_manager, history::HistoryService* history_service, offline_pages::PrefetchService* prefetch_service, @@ -200,12 +203,14 @@ profile_prefs); image_fetcher_ = std::make_unique<ImageFetcher>(url_loader_factory); store_ = std::make_unique<FeedStore>(std::move(database)); + persistent_key_value_store_ = std::make_unique<PersistentKeyValueStoreImpl>( + std::move(key_value_store_database)); stream_ = std::make_unique<FeedStream>( refresh_task_scheduler_.get(), metrics_reporter_.get(), stream_delegate_.get(), profile_prefs, feed_network_.get(), - image_fetcher_.get(), store_.get(), prefetch_service, offline_page_model, - chrome_info); + image_fetcher_.get(), store_.get(), persistent_key_value_store_.get(), + prefetch_service, offline_page_model, chrome_info); history_observer_ = std::make_unique<HistoryObserverImpl>( history_service, static_cast<FeedStream*>(stream_.get()),
diff --git a/components/feed/core/v2/public/feed_service.h b/components/feed/core/v2/public/feed_service.h index d8c1f2a..2890d65 100644 --- a/components/feed/core/v2/public/feed_service.h +++ b/components/feed/core/v2/public/feed_service.h
@@ -31,6 +31,9 @@ namespace feedstore { class Record; } // namespace feedstore +namespace feedkvstore { +class Entry; +} // namespace feedkvstore namespace network { class SharedURLLoaderFactory; } // namespace network @@ -48,6 +51,7 @@ class FeedNetwork; class FeedStore; class FeedStream; +class PersistentKeyValueStoreImpl; class ImageFetcher; namespace internal { @@ -82,6 +86,8 @@ PrefService* profile_prefs, PrefService* local_state, std::unique_ptr<leveldb_proto::ProtoDatabase<feedstore::Record>> database, + std::unique_ptr<leveldb_proto::ProtoDatabase<feedkvstore::Entry>> + key_value_store_database, signin::IdentityManager* identity_manager, history::HistoryService* history_service, offline_pages::PrefetchService* prefetch_service, @@ -123,6 +129,7 @@ std::unique_ptr<FeedNetwork> feed_network_; std::unique_ptr<ImageFetcher> image_fetcher_; std::unique_ptr<FeedStore> store_; + std::unique_ptr<PersistentKeyValueStoreImpl> persistent_key_value_store_; std::unique_ptr<RefreshTaskScheduler> refresh_task_scheduler_; std::unique_ptr<HistoryObserverImpl> history_observer_; std::unique_ptr<IdentityManagerObserverImpl> identity_manager_observer_;
diff --git a/components/feed/core/v2/public/feed_stream_api.h b/components/feed/core/v2/public/feed_stream_api.h index b33d9e8..c531bed2 100644 --- a/components/feed/core/v2/public/feed_stream_api.h +++ b/components/feed/core/v2/public/feed_stream_api.h
@@ -23,6 +23,7 @@ } // namespace feedstore namespace feed { +class PersistentKeyValueStore; // This is the public access point for interacting with the Feed stream // contents. @@ -93,6 +94,8 @@ // |id| doesn't match an active fetch, nothing happens. virtual void CancelImageFetch(ImageFetchId id) = 0; + virtual PersistentKeyValueStore* GetPersistentKeyValueStore() = 0; + // Apply |operations| to the stream model. Does nothing if the model is not // yet loaded. virtual void ExecuteOperations(
diff --git a/components/feed/core/v2/public/persistent_key_value_store.cc b/components/feed/core/v2/public/persistent_key_value_store.cc new file mode 100644 index 0000000..ba15023 --- /dev/null +++ b/components/feed/core/v2/public/persistent_key_value_store.cc
@@ -0,0 +1,15 @@ +// Copyright 2020 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 "components/feed/core/v2/public/persistent_key_value_store.h" + +namespace feed { + +PersistentKeyValueStore::Result::Result() = default; +PersistentKeyValueStore::Result::Result(Result&&) = default; +PersistentKeyValueStore::Result& PersistentKeyValueStore::Result::operator=( + Result&&) = default; +PersistentKeyValueStore::Result::~Result() = default; + +} // namespace feed
diff --git a/components/feed/core/v2/public/persistent_key_value_store.h b/components/feed/core/v2/public/persistent_key_value_store.h new file mode 100644 index 0000000..070d21e8 --- /dev/null +++ b/components/feed/core/v2/public/persistent_key_value_store.h
@@ -0,0 +1,57 @@ +// Copyright 2020 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 COMPONENTS_FEED_CORE_V2_PUBLIC_PERSISTENT_KEY_VALUE_STORE_H_ +#define COMPONENTS_FEED_CORE_V2_PUBLIC_PERSISTENT_KEY_VALUE_STORE_H_ + +#include <memory> +#include <string> + +#include "base/callback.h" +#include "base/optional.h" + +namespace feed { + +// A generic persistent key-value cache. Has a maximum size determined by +// `feed::Config`. Once size of all values exceed the maximum, older keys +// are eventually evicted. Key age is determined only by the last call to +// `Put()`. +class PersistentKeyValueStore { + public: + struct Result { + Result(); + Result(Result&&); + Result& operator=(Result&&); + ~Result(); + // Whether the operation succeeded. Failure may be due to a low level + // database error, or a missing key/value pair. + bool success = false; + // For `Get()` operations, the value of the key if it exists. + base::Optional<std::string> get_result; + }; + + using ResultCallback = base::OnceCallback<void(Result)>; + + PersistentKeyValueStore() = default; + virtual ~PersistentKeyValueStore() = default; + PersistentKeyValueStore(const PersistentKeyValueStore&) = delete; + PersistentKeyValueStore& operator=(const PersistentKeyValueStore&) = delete; + + // Erase all data in the store. + virtual void ClearAll(ResultCallback callback) = 0; + // Write/overwrite a key/value pair. + virtual void Put(const std::string& key, + const std::string& value, + ResultCallback callback) = 0; + // Get a value by key. + virtual void Get(const std::string& key, ResultCallback callback) = 0; + // Delete a value by key. + virtual void Delete(const std::string& key, ResultCallback callback) = 0; + + private: +}; + +} // namespace feed + +#endif // COMPONENTS_FEED_CORE_V2_PUBLIC_PERSISTENT_KEY_VALUE_STORE_H_
diff --git a/components/feed/core/v2/tasks/clear_all_task.cc b/components/feed/core/v2/tasks/clear_all_task.cc index ddcf65d1..45fb2c7 100644 --- a/components/feed/core/v2/tasks/clear_all_task.cc +++ b/components/feed/core/v2/tasks/clear_all_task.cc
@@ -9,6 +9,7 @@ #include "components/feed/core/v2/feed_store.h" #include "components/feed/core/v2/feed_stream.h" +#include "components/feed/core/v2/public/persistent_key_value_store.h" namespace feed { @@ -17,6 +18,7 @@ void ClearAllTask::Run() { stream_->UnloadModel(); + stream_->GetPersistentKeyValueStore()->ClearAll(base::DoNothing()); stream_->GetStore()->ClearAll( base::BindOnce(&ClearAllTask::StoreClearComplete, GetWeakPtr())); }
diff --git a/components/feed/core/v2/test/callback_receiver.cc b/components/feed/core/v2/test/callback_receiver.cc new file mode 100644 index 0000000..a9621ee --- /dev/null +++ b/components/feed/core/v2/test/callback_receiver.cc
@@ -0,0 +1,28 @@ +// Copyright 2020 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 "components/feed/core/v2/test/callback_receiver.h" + +namespace feed { +namespace internal { +void CallbackReceiverBase::RunUntilCalled() { + if (called_) + return; + if (run_loop_) { + run_loop_->Run(); + } else { + base::RunLoop run_loop; + run_loop_ = &run_loop; + run_loop.Run(); + run_loop_ = nullptr; + } +} +void CallbackReceiverBase::Done() { + called_ = true; + if (run_loop_) + run_loop_->Quit(); +} + +} // namespace internal +} // namespace feed
diff --git a/components/feed/core/v2/test/callback_receiver.h b/components/feed/core/v2/test/callback_receiver.h index 1cd9fc6..3b2c4549 100644 --- a/components/feed/core/v2/test/callback_receiver.h +++ b/components/feed/core/v2/test/callback_receiver.h
@@ -5,6 +5,7 @@ #ifndef COMPONENTS_FEED_CORE_V2_TEST_CALLBACK_RECEIVER_H_ #define COMPONENTS_FEED_CORE_V2_TEST_CALLBACK_RECEIVER_H_ +#include <memory> #include <tuple> #include <utility> @@ -21,23 +22,41 @@ return base::nullopt; } +class CallbackReceiverBase { + public: + explicit CallbackReceiverBase(base::RunLoop* run_loop = nullptr) + : run_loop_(run_loop) {} + + void Clear() { called_ = false; } + bool called() const { return called_; } + void RunUntilCalled(); + void Done(); + + private: + bool called_ = false; + base::RunLoop* run_loop_; +}; + } // namespace internal template <typename... T> -class CallbackReceiver { +class CallbackReceiver : public internal::CallbackReceiverBase { public: explicit CallbackReceiver(base::RunLoop* run_loop = nullptr) - : run_loop_(run_loop) {} + : CallbackReceiverBase(run_loop) {} + void Done(T... results) { results_ = std::make_tuple(std::move(results)...); - if (run_loop_) - run_loop_->Quit(); + CallbackReceiverBase::Done(); } base::OnceCallback<void(T...)> Bind() { return base::BindOnce(&CallbackReceiver::Done, base::Unretained(this)); } - void Clear() { results_ = std::make_tuple(internal::Nullopt<T>()...); } + void Clear() { + CallbackReceiverBase::Clear(); + results_ = std::make_tuple(internal::Nullopt<T>()...); + } // Get a result by its position in the arguments to Done(). // Call GetResult() for the first argument or GetResult<I>(). @@ -47,6 +66,12 @@ return std::get<I>(results_); } + template <size_t I = 0> + typename std::tuple_element<I, std::tuple<T...>>::type& RunAndGetResult() { + RunUntilCalled(); + return std::get<I>(results_).value(); + } + // Get a result by its type. Won't compile if there is more than one matching // type. template <class C> @@ -56,7 +81,17 @@ private: std::tuple<base::Optional<T>...> results_; - base::RunLoop* run_loop_; +}; + +template <> +class CallbackReceiver<> : public internal::CallbackReceiverBase { + public: + explicit CallbackReceiver(base::RunLoop* run_loop = nullptr) + : CallbackReceiverBase(run_loop) {} + + base::OnceClosure Bind() { + return base::BindOnce(&CallbackReceiverBase::Done, base::Unretained(this)); + } }; } // namespace feed
diff --git a/components/feed/core/v2/test/callback_receiver_unittest.cc b/components/feed/core/v2/test/callback_receiver_unittest.cc index 301cec7..c3a3e85 100644 --- a/components/feed/core/v2/test/callback_receiver_unittest.cc +++ b/components/feed/core/v2/test/callback_receiver_unittest.cc
@@ -5,6 +5,9 @@ #include "components/feed/core/v2/test/callback_receiver.h" #include "base/optional.h" +#include "base/test/bind.h" +#include "base/test/task_environment.h" +#include "base/threading/sequenced_task_runner_handle.h" #include "testing/gtest/include/gtest/gtest.h" namespace feed { @@ -41,4 +44,25 @@ EXPECT_EQ(cr.GetResult<1>(), base::nullopt); } +TEST(CallbackReceiverTest, RunAndGetResult) { + base::test::TaskEnvironment task_environment{ + base::test::TaskEnvironment::TimeSource::MOCK_TIME}; + + CallbackReceiver<int> cr1; + base::SequencedTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(cr1.Bind(), 42)); + EXPECT_EQ(42, cr1.RunAndGetResult()); +} + +TEST(CallbackReceiverTest, RunAndGetResultExternalRunLoop) { + base::test::TaskEnvironment task_environment{ + base::test::TaskEnvironment::TimeSource::MOCK_TIME}; + + base::RunLoop run_loop; + CallbackReceiver<int> cr1(&run_loop); + base::SequencedTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(cr1.Bind(), 42)); + EXPECT_EQ(42, cr1.RunAndGetResult()); +} + } // namespace feed
diff --git a/components/full_restore/full_restore_save_handler.cc b/components/full_restore/full_restore_save_handler.cc index 0c45667..30686585 100644 --- a/components/full_restore/full_restore_save_handler.cc +++ b/components/full_restore/full_restore_save_handler.cc
@@ -54,7 +54,7 @@ observed_windows_.AddObservation(window); } -void FullRestoreSaveHandler::OnWindowDestroying(aura::Window* window) { +void FullRestoreSaveHandler::OnWindowDestroyed(aura::Window* window) { // TODO(crbug.com/1146900): Handle ARC app windows. DCHECK(observed_windows_.IsObservingSource(window));
diff --git a/components/full_restore/full_restore_save_handler.h b/components/full_restore/full_restore_save_handler.h index d1a81bd..b0f3ebd1 100644 --- a/components/full_restore/full_restore_save_handler.h +++ b/components/full_restore/full_restore_save_handler.h
@@ -52,7 +52,7 @@ void OnWindowInitialized(aura::Window* window) override; // aura::WindowObserver: - void OnWindowDestroying(aura::Window* window) override; + void OnWindowDestroyed(aura::Window* window) override; // Save |app_launch_info| to the full restore file in |profile_path|. void SaveAppLaunchInfo(const base::FilePath& profile_path,
diff --git a/components/history/core/browser/history_backend.cc b/components/history/core/browser/history_backend.cc index 7d43755..4ded644 100644 --- a/components/history/core/browser/history_backend.cc +++ b/components/history/core/browser/history_backend.cc
@@ -462,6 +462,24 @@ UpdateVisitDuration(visit_id, end_ts); } +void HistoryBackend::SetFlocAllowed(ContextID context_id, + int nav_entry_id, + const GURL& url) { + TRACE_EVENT0("browser", "HistoryBackend::SetFlocAllowed"); + + if (!db_) + return; + + VisitID visit_id = tracker_.GetLastVisit(context_id, nav_entry_id, url); + + VisitRow visit_row; + if (db_->GetRowForVisit(visit_id, &visit_row)) { + visit_row.floc_allowed = true; + db_->UpdateVisitRow(visit_row); + ScheduleCommit(); + } +} + void HistoryBackend::UpdateVisitDuration(VisitID visit_id, const Time end_ts) { if (!db_) return;
diff --git a/components/history/core/browser/history_backend.h b/components/history/core/browser/history_backend.h index 3c36058c..3af2191f 100644 --- a/components/history/core/browser/history_backend.h +++ b/components/history/core/browser/history_backend.h
@@ -242,6 +242,7 @@ int nav_entry_id, const GURL& url, base::Time end_ts); + void SetFlocAllowed(ContextID context_id, int nav_entry_id, const GURL& url); // Querying ------------------------------------------------------------------
diff --git a/components/history/core/browser/history_backend_unittest.cc b/components/history/core/browser/history_backend_unittest.cc index 3165787..eb3cd99e 100644 --- a/components/history/core/browser/history_backend_unittest.cc +++ b/components/history/core/browser/history_backend_unittest.cc
@@ -1465,6 +1465,36 @@ EXPECT_EQ(history::SOURCE_SYNCED, visit_sources.begin()->second); } +TEST_F(HistoryBackendTest, SetFlocAllowed) { + ASSERT_TRUE(backend_.get()); + + GURL url("http://test-set-floc-allowed.com"); + ContextID context_id = reinterpret_cast<ContextID>(1); + int nav_entry_id = 1; + + HistoryAddPageArgs request(url, base::Time::Now(), context_id, nav_entry_id, + GURL(), history::RedirectList(), + ui::PAGE_TRANSITION_TYPED, false, + history::SOURCE_BROWSED, false, true, false); + backend_->AddPage(request); + + VisitVector visits; + URLRow row; + URLID id = backend_->db()->GetRowForURL(url, &row); + ASSERT_TRUE(backend_->db()->GetVisitsForURL(id, &visits)); + ASSERT_EQ(1U, visits.size()); + VisitRow visit = visits[0]; + EXPECT_FALSE(visit.floc_allowed); + + backend_->SetFlocAllowed(context_id, nav_entry_id, url); + + id = backend_->db()->GetRowForURL(url, &row); + ASSERT_TRUE(backend_->db()->GetVisitsForURL(id, &visits)); + ASSERT_EQ(1U, visits.size()); + visit = visits[0]; + EXPECT_TRUE(visit.floc_allowed); +} + TEST_F(HistoryBackendTest, AddVisitsSource) { ASSERT_TRUE(backend_.get());
diff --git a/components/history/core/browser/history_service.cc b/components/history/core/browser/history_service.cc index 1cb3f16..64c35f25 100644 --- a/components/history/core/browser/history_service.cc +++ b/components/history/core/browser/history_service.cc
@@ -413,6 +413,17 @@ context_id, nav_entry_id, url, end_ts)); } +void HistoryService::SetFlocAllowed(ContextID context_id, + int nav_entry_id, + const GURL& url) { + TRACE_EVENT0("browser", "HistoryService::SetFlocAllowed"); + DCHECK(backend_task_runner_) << "History service being called after cleanup"; + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + ScheduleTask(PRIORITY_NORMAL, + base::BindOnce(&HistoryBackend::SetFlocAllowed, history_backend_, + context_id, nav_entry_id, url)); +} + void HistoryService::AddPageWithDetails(const GURL& url, const base::string16& title, int visit_count,
diff --git a/components/history/core/browser/history_service.h b/components/history/core/browser/history_service.h index 0411226..9efc3fa 100644 --- a/components/history/core/browser/history_service.h +++ b/components/history/core/browser/history_service.h
@@ -165,6 +165,8 @@ // // |floc_allowed| indicates whether this URL visit can be included in FLoC // computation. See VisitRow::floc_allowed for details. + // TODO(yaoxia): Remove the floc_allowed param from this API as well as from + // HistoryAddPageArgs. This bit will never be set at this point. // // TODO(avi): This is no longer true. 'page id' was removed years ago, and // their uses replaced by globally-unique nav_entry_ids. Is ContextID still @@ -214,6 +216,11 @@ const GURL& url, base::Time end_ts); + // Updates the history database by setting the floc allowed bit. The page can + // be identified by the combination of the context id, the navigation entry id + // and the url. No-op if the page is not found. + void SetFlocAllowed(ContextID context_id, int nav_entry_id, const GURL& url); + // Querying ------------------------------------------------------------------ // Returns the information about the requested URL. If the URL is found,
diff --git a/components/leveldb_proto/public/shared_proto_database_client_list.cc b/components/leveldb_proto/public/shared_proto_database_client_list.cc index eae251d..c2d3f632 100644 --- a/components/leveldb_proto/public/shared_proto_database_client_list.cc +++ b/components/leveldb_proto/public/shared_proto_database_client_list.cc
@@ -88,6 +88,8 @@ return "NearbySharePublicCertificateDatabase"; case ProtoDbType::VIDEO_TUTORIALS_DATABASE: return "VideoTutorialsDatabase"; + case ProtoDbType::FEED_KEY_VALUE_DATABASE: + return "FeedKeyValueDatabase"; case ProtoDbType::LAST: NOTREACHED(); return std::string();
diff --git a/components/leveldb_proto/public/shared_proto_database_client_list.h b/components/leveldb_proto/public/shared_proto_database_client_list.h index 57d6886..55e2f9a77 100644 --- a/components/leveldb_proto/public/shared_proto_database_client_list.h +++ b/components/leveldb_proto/public/shared_proto_database_client_list.h
@@ -18,7 +18,8 @@ // The enum values are used to index into the shared database. Do not rearrange // or reuse the integer values. Add new database types at the end of the enum, // and update the string mapping in ProtoDbTypeToString(). Also update the -// suffix LevelDBClients in histograms.xml to match the strings for the types. +// suffix LevelDBClients in histogram_suffixes_list.xml to match the strings for +// the types. enum class ProtoDbType { TEST_DATABASE0 = 0, TEST_DATABASE1 = 1, @@ -53,6 +54,7 @@ UPBOARDING_QUERY_TILE_STORE = 28, NEARBY_SHARE_PUBLIC_CERTIFICATE_DATABASE = 29, VIDEO_TUTORIALS_DATABASE = 30, + FEED_KEY_VALUE_DATABASE = 31, LAST, }; @@ -68,6 +70,7 @@ ProtoDbType::UPBOARDING_QUERY_TILE_STORE, ProtoDbType::NEARBY_SHARE_PUBLIC_CERTIFICATE_DATABASE, ProtoDbType::VIDEO_TUTORIALS_DATABASE, + ProtoDbType::FEED_KEY_VALUE_DATABASE, ProtoDbType::LAST, // Marks the end of list. };
diff --git a/components/offline_pages/content/renovations/BUILD.gn b/components/offline_pages/content/renovations/BUILD.gn deleted file mode 100644 index 955803e1..0000000 --- a/components/offline_pages/content/renovations/BUILD.gn +++ /dev/null
@@ -1,19 +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. - -if (is_android) { - import("//build/config/android/rules.gni") -} - -source_set("renovations") { - sources = [ - "render_frame_script_injector.cc", - "render_frame_script_injector.h", - ] - - deps = [ - "//components/offline_pages/core/renovations", - "//content/public/browser", - ] -}
diff --git a/components/offline_pages/content/renovations/DEPS b/components/offline_pages/content/renovations/DEPS deleted file mode 100644 index c24130e..0000000 --- a/components/offline_pages/content/renovations/DEPS +++ /dev/null
@@ -1,4 +0,0 @@ -include_rules = [ - "+content/public/browser", - "+content/public/common", -]
diff --git a/components/offline_pages/content/renovations/render_frame_script_injector.cc b/components/offline_pages/content/renovations/render_frame_script_injector.cc deleted file mode 100644 index cc90769..0000000 --- a/components/offline_pages/content/renovations/render_frame_script_injector.cc +++ /dev/null
@@ -1,37 +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. - -#include "components/offline_pages/content/renovations/render_frame_script_injector.h" - -#include <utility> - -#include "base/bind.h" -#include "base/callback.h" -#include "base/check.h" -#include "base/values.h" -#include "content/public/browser/render_frame_host.h" -#include "content/public/common/isolated_world_ids.h" - -namespace offline_pages { - -RenderFrameScriptInjector::RenderFrameScriptInjector( - content::RenderFrameHost* render_frame_host, - int32_t isolated_world_id) - : render_frame_host_(render_frame_host), - isolated_world_id_(isolated_world_id) { - DCHECK(render_frame_host_); - DCHECK(isolated_world_id_ > content::ISOLATED_WORLD_ID_GLOBAL && - isolated_world_id_ < content::ISOLATED_WORLD_ID_MAX); -} - -void RenderFrameScriptInjector::Inject(base::string16 script, - ResultCallback callback) { - // |render_frame_host_| should still be alive if the - // caller is using this class correctly. - DCHECK(render_frame_host_); - render_frame_host_->ExecuteJavaScriptInIsolatedWorld( - script, std::move(callback), isolated_world_id_); -} - -} // namespace offline_pages
diff --git a/components/offline_pages/content/renovations/render_frame_script_injector.h b/components/offline_pages/content/renovations/render_frame_script_injector.h deleted file mode 100644 index e572ee1c..0000000 --- a/components/offline_pages/content/renovations/render_frame_script_injector.h +++ /dev/null
@@ -1,37 +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. - -#ifndef COMPONENTS_OFFLINE_PAGES_CONTENT_RENOVATIONS_RENDER_FRAME_SCRIPT_INJECTOR_H_ -#define COMPONENTS_OFFLINE_PAGES_CONTENT_RENOVATIONS_RENDER_FRAME_SCRIPT_INJECTOR_H_ - -#include "components/offline_pages/core/renovations/script_injector.h" - -namespace content { -class RenderFrameHost; -} - -namespace offline_pages { - -// ScriptInjector for running scripts in a RenderFrame within a given isolated -// world. -class RenderFrameScriptInjector : public ScriptInjector { - public: - ~RenderFrameScriptInjector() override = default; - - // The |render_frame_host| is expected to outlive this - // RenderFrameScriptInjector instance. - RenderFrameScriptInjector(content::RenderFrameHost* render_frame_host, - int32_t isolated_world_id); - - // ScriptInjector implementation. - void Inject(base::string16 script, ResultCallback callback) override; - - private: - content::RenderFrameHost* render_frame_host_; - int32_t isolated_world_id_; -}; - -} // namespace offline_pages - -#endif // COMPONENTS_OFFLINE_PAGES_CONTENT_RENOVATIONS_RENDER_FRAME_SCRIPT_INJECTOR_H_
diff --git a/components/offline_pages/content/renovations/test/DEPS b/components/offline_pages/content/renovations/test/DEPS deleted file mode 100644 index 6bfde01..0000000 --- a/components/offline_pages/content/renovations/test/DEPS +++ /dev/null
@@ -1,6 +0,0 @@ -include_rules = [ - "+content/public/test", - "+content/shell/browser", - "+net/test/embedded_test_server", - "+ui/base/resource/resource_bundle.h", -]
diff --git a/components/offline_pages/content/renovations/test/page_renovator_browsertest.cc b/components/offline_pages/content/renovations/test/page_renovator_browsertest.cc deleted file mode 100644 index 67f49e2..0000000 --- a/components/offline_pages/content/renovations/test/page_renovator_browsertest.cc +++ /dev/null
@@ -1,248 +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. - -#include "components/offline_pages/core/renovations/page_renovator.h" - -#include <memory> -#include <utility> -#include <vector> - -#include "base/bind.h" -#include "base/files/file_path.h" -#include "base/path_service.h" -#include "base/run_loop.h" -#include "base/strings/utf_string_conversions.h" -#include "base/values.h" -#include "build/build_config.h" -#include "components/offline_pages/content/renovations/render_frame_script_injector.h" -#include "components/offline_pages/core/renovations/page_renovation_loader.h" -#include "content/public/browser/browser_task_traits.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/web_contents.h" -#include "content/public/common/isolated_world_ids.h" -#include "content/public/test/browser_test.h" -#include "content/public/test/content_browser_test.h" -#include "content/public/test/content_browser_test_utils.h" -#include "content/public/test/test_utils.h" -#include "content/shell/browser/shell.h" -#include "net/test/embedded_test_server/embedded_test_server.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "ui/base/resource/resource_bundle.h" -#include "url/gurl.h" - -namespace offline_pages { - -namespace { - -const char kDocRoot[] = "components/test/data/offline_pages"; - -// For testing real renovations. -const char kWikipediaTestPagePath[] = "/wikipedia_renovation_test_page.html"; - -const char kCheckUnfoldBlockScript[] = - "document.getElementById('block1').classList.contains('open-block') && " - "document.getElementById('block2').classList.contains('open-block')"; -const char kCheckUnfoldHeadingScript[] = - "document.getElementById('heading1').classList.contains('open-block') && " - "document.getElementById('heading2').classList.contains('open-block')"; - -// For running against the test renovations. -const char kTestPagePath[] = "/renovator_test_page.html"; -const char kTestRenovationScript[] = - R"*(function foo() { - var node = document.getElementById('foo'); - node.innerHTML = 'Good'; - } - function bar() { - var node = document.getElementById('bar'); - node.parentNode.removeChild(node); - } - function always() { - var node = document.getElementById('always'); - node.parentNode.removeChild(node); - } - var mapRenovations = {'foo':foo, 'bar':bar, 'always':always}; - function run_renovations(idlist) { - for (var id of idlist) { - mapRenovations[id](); - } - })*"; - -// Scripts to check whether each renovation ran in the test page. -const char kCheckFooScript[] = - "document.getElementById('foo').innerHTML == 'Good'"; -const char kCheckBarScript[] = "document.getElementById('bar') == null"; -const char kCheckAlwaysScript[] = "document.getElementById('always') == null"; - -// Renovation that should only run on pages from URL foo.bar -class FooPageRenovation : public PageRenovation { - public: - bool ShouldRun(const GURL& url) const override { - return url.host() == "foo.bar"; - } - std::string GetID() const override { return "foo"; } -}; - -// Renovation that should only run on pages from URL bar.qux -class BarPageRenovation : public PageRenovation { - public: - bool ShouldRun(const GURL& url) const override { - return url.host() == "bar.qux"; - } - std::string GetID() const override { return "bar"; } -}; - -// Renovation that should run on every page. -class AlwaysRenovation : public PageRenovation { - public: - bool ShouldRun(const GURL& url) const override { return true; } - std::string GetID() const override { return "always"; } -}; - -} // namespace - -class PageRenovatorBrowserTest : public content::ContentBrowserTest { - public: - void SetUpOnMainThread() override; - - // Navigates the content shell to the path indicated. This path is - // relative to the Chromium source root. - void Navigate(const std::string& test_page_path); - - // These functions initialize the PageRenovator and dependencies - // with either testing renovations defined above, or with production - // renovations. |fake_url| is the URL passed to the PageRenovator - // and determines which renovations should be run. - // - // Only one of these should be called, and |Navigate| should be called - // beforehand. - void InitializeWithTestingRenovations(const GURL& fake_url); - void InitializeWithRealRenovations(const GURL& fake_url); - - void QuitRunLoop(); - - protected: - net::EmbeddedTestServer test_server_; - content::RenderFrameHost* render_frame_; - std::unique_ptr<PageRenovationLoader> page_renovation_loader_; - std::unique_ptr<PageRenovator> page_renovator_; - - std::unique_ptr<base::RunLoop> run_loop_; -}; - -void PageRenovatorBrowserTest::SetUpOnMainThread() { - // Add resources pack to resource bundle so PageRenovationLoader can - // load our renovation script. - base::FilePath pak_dir; -#if defined(OS_ANDROID) - base::PathService::Get(base::DIR_ANDROID_APP_DATA, &pak_dir); - pak_dir = pak_dir.Append(FILE_PATH_LITERAL("paks")); -#else - base::PathService::Get(base::DIR_MODULE, &pak_dir); -#endif // OS_ANDROID - base::FilePath pak_file = - pak_dir.Append(FILE_PATH_LITERAL("components_tests_resources.pak")); - ui::ResourceBundle::GetSharedInstance().AddDataPackFromPath( - pak_file, ui::SCALE_FACTOR_NONE); - - // Serve our test HTML. - test_server_.ServeFilesFromSourceDirectory(kDocRoot); - ASSERT_TRUE(test_server_.Start()); - - run_loop_.reset(new base::RunLoop); -} - -void PageRenovatorBrowserTest::Navigate(const std::string& test_page_path) { - GURL url = test_server_.GetURL(test_page_path); - EXPECT_TRUE(content::NavigateToURL(shell(), url)); - render_frame_ = shell()->web_contents()->GetMainFrame(); -} - -void PageRenovatorBrowserTest::InitializeWithTestingRenovations( - const GURL& fake_url) { - ASSERT_TRUE(render_frame_) << "Navigate should have been called."; - - std::vector<std::unique_ptr<PageRenovation>> renovations; - renovations.push_back(std::make_unique<FooPageRenovation>()); - renovations.push_back(std::make_unique<BarPageRenovation>()); - renovations.push_back(std::make_unique<AlwaysRenovation>()); - - page_renovation_loader_.reset(new PageRenovationLoader); - page_renovation_loader_->SetSourceForTest( - base::ASCIIToUTF16(kTestRenovationScript)); - page_renovation_loader_->SetRenovationsForTest(std::move(renovations)); - - auto script_injector = std::make_unique<RenderFrameScriptInjector>( - render_frame_, content::ISOLATED_WORLD_ID_CONTENT_END); - page_renovator_.reset(new PageRenovator( - page_renovation_loader_.get(), std::move(script_injector), fake_url)); -} - -void PageRenovatorBrowserTest::InitializeWithRealRenovations( - const GURL& fake_url) { - ASSERT_TRUE(render_frame_) << "Navigate should have been called."; - - page_renovation_loader_.reset(new PageRenovationLoader); - - auto script_injector = std::make_unique<RenderFrameScriptInjector>( - render_frame_, content::ISOLATED_WORLD_ID_CONTENT_END); - page_renovator_.reset(new PageRenovator( - page_renovation_loader_.get(), std::move(script_injector), fake_url)); -} - -void PageRenovatorBrowserTest::QuitRunLoop() { - content::GetUIThreadTaskRunner({})->PostTask( - FROM_HERE, content::GetDeferredQuitTaskForRunLoop(run_loop_.get())); -} - -#if defined(OS_WIN) -#define MAYBE_CorrectRenovationsRun DISABLED_CorrectRenovationsRun -#else -#define MAYBE_CorrectRenovationsRun CorrectRenovationsRun -#endif -IN_PROC_BROWSER_TEST_F(PageRenovatorBrowserTest, MAYBE_CorrectRenovationsRun) { - Navigate(kTestPagePath); - InitializeWithTestingRenovations(GURL("http://foo.bar/")); - // This should run FooPageRenovation and AlwaysRenovation, but not - // BarPageRenovation. - page_renovator_->RunRenovations(base::BindOnce( - &PageRenovatorBrowserTest::QuitRunLoop, base::Unretained(this))); - content::RunThisRunLoop(run_loop_.get()); - - // Check that correct modifications were made to the page. - base::Value fooResult = - content::ExecuteScriptAndGetValue(render_frame_, kCheckFooScript); - base::Value barResult = - content::ExecuteScriptAndGetValue(render_frame_, kCheckBarScript); - base::Value alwaysResult = - content::ExecuteScriptAndGetValue(render_frame_, kCheckAlwaysScript); - - EXPECT_TRUE(fooResult.GetBool()); - EXPECT_FALSE(barResult.GetBool()); - EXPECT_TRUE(alwaysResult.GetBool()); -} - -#if defined(OS_WIN) -#define MAYBE_WikipediaRenovationRuns DISABLED_WikipediaRenovationRuns -#else -#define MAYBE_WikipediaRenovationRuns WikipediaRenovationRuns -#endif -IN_PROC_BROWSER_TEST_F(PageRenovatorBrowserTest, - MAYBE_WikipediaRenovationRuns) { - Navigate(kWikipediaTestPagePath); - InitializeWithRealRenovations(GURL("http://en.m.wikipedia.org/")); - page_renovator_->RunRenovations(base::BindOnce( - &PageRenovatorBrowserTest::QuitRunLoop, base::Unretained(this))); - content::RunThisRunLoop(run_loop_.get()); - - base::Value unfoldBlockResult = - content::ExecuteScriptAndGetValue(render_frame_, kCheckUnfoldBlockScript); - base::Value unfoldHeadingResult = content::ExecuteScriptAndGetValue( - render_frame_, kCheckUnfoldHeadingScript); - - EXPECT_TRUE(unfoldBlockResult.GetBool()); - EXPECT_TRUE(unfoldHeadingResult.GetBool()); -} - -} // namespace offline_pages
diff --git a/components/offline_pages/core/BUILD.gn b/components/offline_pages/core/BUILD.gn index 5ff892f..e674e792 100644 --- a/components/offline_pages/core/BUILD.gn +++ b/components/offline_pages/core/BUILD.gn
@@ -180,7 +180,6 @@ ":switches", ":test_support", "prefetch:unit_tests", - "renovations:unit_tests", "//base", "//base/test:test_support", "//components/offline_pages/task:test_support",
diff --git a/components/offline_pages/core/background_snapshot_controller.cc b/components/offline_pages/core/background_snapshot_controller.cc index b13ee560..6488af9 100644 --- a/components/offline_pages/core/background_snapshot_controller.cc +++ b/components/offline_pages/core/background_snapshot_controller.cc
@@ -35,8 +35,8 @@ state_(State::READY), delay_after_document_on_load_completed_ms_( kDelayAfterDocumentOnLoadCompletedMsBackground), - delay_after_renovations_completed_ms_(kDelayAfterRenovationsCompletedMs), - renovations_enabled_(renovations_enabled) { + delay_after_renovations_completed_ms_(kDelayAfterRenovationsCompletedMs) { + DCHECK(!renovations_enabled); if (offline_pages::ShouldUseTestingSnapshotDelay()) { delay_after_document_on_load_completed_ms_ = kDelayForTests; delay_after_renovations_completed_ms_ = kDelayForTests; @@ -56,23 +56,9 @@ } void BackgroundSnapshotController::RenovationsCompleted() { - if (renovations_enabled_) { - task_runner_->PostDelayedTask( - FROM_HERE, - base::BindOnce( - &BackgroundSnapshotController::MaybeStartSnapshotThenStop, - weak_ptr_factory_.GetWeakPtr()), - base::TimeDelta::FromMilliseconds( - delay_after_renovations_completed_ms_)); - } } void BackgroundSnapshotController::DocumentOnLoadCompletedInMainFrame() { - if (renovations_enabled_) { - // Run renovations. After renovations complete, a snapshot will be - // triggered after a delay. - client_->RunRenovations(); - } else { // Post a delayed task to snapshot and then stop this controller. task_runner_->PostDelayedTask( FROM_HERE, @@ -81,7 +67,6 @@ weak_ptr_factory_.GetWeakPtr()), base::TimeDelta::FromMilliseconds( delay_after_document_on_load_completed_ms_)); - } } void BackgroundSnapshotController::MaybeStartSnapshot() {
diff --git a/components/offline_pages/core/background_snapshot_controller.h b/components/offline_pages/core/background_snapshot_controller.h index cdf0836b..d46ec9c29e 100644 --- a/components/offline_pages/core/background_snapshot_controller.h +++ b/components/offline_pages/core/background_snapshot_controller.h
@@ -47,11 +47,6 @@ // Invoked at a good moment to start a snapshot. virtual void StartSnapshot() = 0; - // Invoked when the page is sufficiently loaded for running - // renovations. The client should call the RenovationsCompleted() - // when they finish. - virtual void RunRenovations() = 0; - protected: virtual ~Client() {} }; @@ -90,7 +85,6 @@ BackgroundSnapshotController::State state_; int64_t delay_after_document_on_load_completed_ms_; int64_t delay_after_renovations_completed_ms_; - bool renovations_enabled_; base::WeakPtrFactory<BackgroundSnapshotController> weak_ptr_factory_{this};
diff --git a/components/offline_pages/core/background_snapshot_controller_unittest.cc b/components/offline_pages/core/background_snapshot_controller_unittest.cc index 91c579b..f30b829 100644 --- a/components/offline_pages/core/background_snapshot_controller_unittest.cc +++ b/components/offline_pages/core/background_snapshot_controller_unittest.cc
@@ -30,7 +30,6 @@ // BackgroundSnapshotController::Client void StartSnapshot() override; - void RunRenovations() override; // Utility methods. // Runs until all of the tasks that are not delayed are gone from the task @@ -68,10 +67,6 @@ snapshot_count_++; } -void BackgroundSnapshotControllerTest::RunRenovations() { - controller_->RenovationsCompleted(); -} - void BackgroundSnapshotControllerTest::PumpLoop() { task_runner_->RunUntilIdle(); }
diff --git a/components/offline_pages/core/offline_page_feature.cc b/components/offline_pages/core/offline_page_feature.cc index 27591b9..38a3858 100644 --- a/components/offline_pages/core/offline_page_feature.cc +++ b/components/offline_pages/core/offline_page_feature.cc
@@ -29,15 +29,6 @@ const base::Feature kOfflinePagesLivePageSharingFeature{ "OfflinePagesLivePageSharing", base::FEATURE_DISABLED_BY_DEFAULT}; -const base::Feature kOfflinePagesLoadSignalCollectingFeature{ - "OfflinePagesLoadSignalCollecting", base::FEATURE_DISABLED_BY_DEFAULT}; - -const base::Feature kOfflinePagesRenovationsFeature{ - "OfflinePagesRenovations", base::FEATURE_DISABLED_BY_DEFAULT}; - -const base::Feature kOfflinePagesResourceBasedSnapshotFeature{ - "OfflinePagesResourceBasedSnapshot", base::FEATURE_DISABLED_BY_DEFAULT}; - const base::Feature kPrefetchingOfflinePagesFeature{ "OfflinePagesPrefetching", base::FEATURE_ENABLED_BY_DEFAULT}; @@ -86,19 +77,6 @@ return base::FeatureList::IsEnabled(kPrefetchingOfflinePagesFeature); } -bool IsOfflinePagesLoadSignalCollectingEnabled() { - return base::FeatureList::IsEnabled(kOfflinePagesLoadSignalCollectingFeature); -} - -bool IsOfflinePagesRenovationsEnabled() { - return base::FeatureList::IsEnabled(kOfflinePagesRenovationsFeature); -} - -bool IsOfflinePagesResourceBasedSnapshotEnabled() { - return base::FeatureList::IsEnabled( - kOfflinePagesResourceBasedSnapshotFeature); -} - bool ShouldUseTestingSnapshotDelay() { base::CommandLine* cl = base::CommandLine::ForCurrentProcess(); return cl->HasSwitch(kOfflinePagesUseTestingSnapshotDelay);
diff --git a/components/offline_pages/core/offline_page_feature.h b/components/offline_pages/core/offline_page_feature.h index adf9ab7..6295a79b 100644 --- a/components/offline_pages/core/offline_page_feature.h +++ b/components/offline_pages/core/offline_page_feature.h
@@ -15,10 +15,7 @@ extern const base::Feature kOfflinePagesLivePageSharingFeature; extern const base::Feature kBackgroundLoaderForDownloadsFeature; extern const base::Feature kPrefetchingOfflinePagesFeature; -extern const base::Feature kOfflinePagesLoadSignalCollectingFeature; extern const base::Feature kOfflinePagesCTV2Feature; -extern const base::Feature kOfflinePagesRenovationsFeature; -extern const base::Feature kOfflinePagesResourceBasedSnapshotFeature; extern const base::Feature kOfflinePagesDescriptivePendingStatusFeature; extern const base::Feature kOfflinePagesInDownloadHomeOpenInCctFeature; extern const base::Feature kOfflinePagesDescriptiveFailStatusFeature; @@ -45,18 +42,6 @@ // Returns true if prefetching offline pages is enabled. bool IsPrefetchingOfflinePagesEnabled(); -// Returns true if we enable load timing signals to be collected. -bool IsOfflinePagesLoadSignalCollectingEnabled(); - -// Returns true if we should use the "page renovation" framework in -// the BackgroundLoaderOffliner. -bool IsOfflinePagesRenovationsEnabled(); - -// Returns true if we should use the "Resource percentage signal" for taking -// snapshots instead of a time delay after the document is loaded in the main -// frame. -bool IsOfflinePagesResourceBasedSnapshotEnabled(); - // Returns true if a command line for test has been set that shortens the // snapshot delay. bool ShouldUseTestingSnapshotDelay();
diff --git a/components/offline_pages/core/offline_page_feature_unittest.cc b/components/offline_pages/core/offline_page_feature_unittest.cc index cdaf1f0..35362d268 100644 --- a/components/offline_pages/core/offline_page_feature_unittest.cc +++ b/components/offline_pages/core/offline_page_feature_unittest.cc
@@ -31,17 +31,6 @@ EXPECT_TRUE(offline_pages::IsOfflinePagesLivePageSharingEnabled()); } -TEST(OfflinePageFeatureTest, OfflinePagesLoadSignalCollecting) { - // Disabled by default. - EXPECT_FALSE(offline_pages::IsOfflinePagesLoadSignalCollectingEnabled()); - - // Check if helper method works correctly when the features is enabled. - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature( - kOfflinePagesLoadSignalCollectingFeature); - EXPECT_TRUE(offline_pages::IsOfflinePagesLoadSignalCollectingEnabled()); -} - TEST(OfflinePageFeatureTest, OfflinePagesPrefetching) { // Enabled by default. EXPECT_TRUE(offline_pages::IsPrefetchingOfflinePagesEnabled());
diff --git a/components/offline_pages/core/renovations/BUILD.gn b/components/offline_pages/core/renovations/BUILD.gn deleted file mode 100644 index f7712136..0000000 --- a/components/offline_pages/core/renovations/BUILD.gn +++ /dev/null
@@ -1,43 +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. - -if (is_android) { - import("//build/config/android/rules.gni") -} - -static_library("renovations") { - sources = [ - "page_renovation.h", - "page_renovation_loader.cc", - "page_renovation_loader.h", - "page_renovator.cc", - "page_renovator.h", - "script_injector.h", - ] - - deps = [ - "//base", - "//components/offline_pages/core", - "//components/resources:components_resources", - "//ui/base", - "//url", - ] -} - -source_set("unit_tests") { - testonly = true - sources = [ - "page_renovation_loader_unittest.cc", - "page_renovator_unittest.cc", - ] - - deps = [ - ":renovations", - "//base", - "//base/test:test_support", - "//testing/gmock", - "//testing/gtest", - "//url", - ] -}
diff --git a/components/offline_pages/core/renovations/DEPS b/components/offline_pages/core/renovations/DEPS deleted file mode 100644 index 65f9de2..0000000 --- a/components/offline_pages/core/renovations/DEPS +++ /dev/null
@@ -1,4 +0,0 @@ -include_rules = [ - "+components/grit/components_resources.h", - "+ui/base/resource", -]
diff --git a/components/offline_pages/core/renovations/page_renovation.h b/components/offline_pages/core/renovations/page_renovation.h deleted file mode 100644 index 6a8696f70..0000000 --- a/components/offline_pages/core/renovations/page_renovation.h +++ /dev/null
@@ -1,29 +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. - -#ifndef COMPONENTS_OFFLINE_PAGES_CORE_PAGE_RENOVATION_H_ -#define COMPONENTS_OFFLINE_PAGES_CORE_PAGE_RENOVATION_H_ - -#include <string> - -#include "url/gurl.h" - -namespace offline_pages { - -// Objects implementing this interface represent individual renovations -// that can be run in a page pre-snapshot. -class PageRenovation { - public: - virtual ~PageRenovation() {} - - // Returns |true| if this renovation should run in the page from |url|. - virtual bool ShouldRun(const GURL& url) const = 0; - // Returns an ID that identifies this renovation's script. This ID - // can be passed to the PageRenovationLoader. - virtual std::string GetID() const = 0; -}; - -} // namespace offline_pages - -#endif // COMPONENTS_OFFLINE_PAGES_CORE_PAGE_RENOVATION_H_
diff --git a/components/offline_pages/core/renovations/page_renovation_loader.cc b/components/offline_pages/core/renovations/page_renovation_loader.cc deleted file mode 100644 index 5e766f4..0000000 --- a/components/offline_pages/core/renovations/page_renovation_loader.cc +++ /dev/null
@@ -1,108 +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. - -#include "components/offline_pages/core/renovations/page_renovation_loader.h" - -#include <algorithm> -#include <string> -#include <utility> - -#include "base/check_op.h" -#include "base/strings/utf_string_conversions.h" -#include "components/grit/components_resources.h" -#include "ui/base/resource/resource_bundle.h" - -namespace offline_pages { - -namespace { - -// Helper function used in WikipediaPageRenovation::ShouldRun. -bool EndsWith(const std::string& host, const std::string& suffix) { - if (suffix.size() > host.size()) - return false; - - return std::equal(suffix.rbegin(), suffix.rend(), host.rbegin()); -} - -// Concrete PageRenovation instances -class WikipediaPageRenovation : public PageRenovation { - public: - bool ShouldRun(const GURL& url) const override { - return EndsWith(url.host(), "m.wikipedia.org"); - } - - std::string GetID() const override { return "wikipedia"; } -}; - -// Construct list of implemented renovations -std::vector<std::unique_ptr<PageRenovation>> MakeRenovationList() { - std::vector<std::unique_ptr<PageRenovation>> list; - list.emplace_back(new WikipediaPageRenovation); - return list; -} - -} // namespace - -PageRenovationLoader::PageRenovationLoader() - : renovations_(MakeRenovationList()), is_loaded_(false) {} - -PageRenovationLoader::~PageRenovationLoader() {} - -bool PageRenovationLoader::GetRenovationScript( - const std::vector<std::string>& renovation_ids, - base::string16* script) { - if (!LoadSource()) { - return false; - } - - // The loaded script contains a function called run_renovations - // which takes an array of renovation names and runs all the - // associated renovation code. Create call to run_renovations - // function in JavaScript file. - std::string jsCall = "\nrun_renovations(["; - for (const std::string& renovation_id : renovation_ids) { - jsCall += "\""; - jsCall += renovation_id; - jsCall += "\","; - } - jsCall += "]);"; - - // Append run_renovations call to combined_source_, which contains - // the definition of run_renovations. - *script = combined_source_; - *script += base::UTF8ToUTF16(jsCall); - - return true; -} - -bool PageRenovationLoader::LoadSource() { - // We only need to load the script from storage once. - if (is_loaded_) { - return true; - } - - // Our script file is stored in the resource bundle. Get this script. - ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); - combined_source_ = base::UTF8ToUTF16( - rb.LoadDataResourceString(IDR_OFFLINE_PAGES_RENOVATIONS_JS)); - - // If built correctly, IDR_OFFLINE_PAGES_RENOVATIONS_JS should - // always exist in the resource pack and loading should never fail. - DCHECK_GT(combined_source_.size(), 0U); - - is_loaded_ = true; - return true; -} - -void PageRenovationLoader::SetSourceForTest(base::string16 combined_source) { - combined_source_ = std::move(combined_source); - is_loaded_ = true; -} - -void PageRenovationLoader::SetRenovationsForTest( - std::vector<std::unique_ptr<PageRenovation>> renovations) { - renovations_ = std::move(renovations); -} - -} // namespace offline_pages
diff --git a/components/offline_pages/core/renovations/page_renovation_loader.h b/components/offline_pages/core/renovations/page_renovation_loader.h deleted file mode 100644 index bfdfd9dc..0000000 --- a/components/offline_pages/core/renovations/page_renovation_loader.h +++ /dev/null
@@ -1,59 +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. - -#ifndef COMPONENTS_OFFLINE_PAGES_CORE_RENOVATIONS_PAGE_RENOVATION_LOADER_H_ -#define COMPONENTS_OFFLINE_PAGES_CORE_RENOVATIONS_PAGE_RENOVATION_LOADER_H_ - -#include <memory> -#include <string> -#include <vector> - -#include "base/macros.h" -#include "base/strings/string16.h" -#include "components/offline_pages/core/renovations/page_renovation.h" - -namespace offline_pages { - -// Class for preparing page renovation scripts. Handles loading -// JavaScript from storage and creating script to run particular -// renovations. -class PageRenovationLoader { - public: - PageRenovationLoader(); - ~PageRenovationLoader(); - - // Takes a list of renovation IDs and outputs a script to be run in - // page. Returns whether loading was successful. The script is a - // string16 to match the rest of Chrome. - bool GetRenovationScript(const std::vector<std::string>& renovation_ids, - base::string16* script); - - // Returns the list of known renovations. - const std::vector<std::unique_ptr<PageRenovation>>& renovations() { - return renovations_; - } - - // Methods for testing. - void SetSourceForTest(base::string16 combined_source); - void SetRenovationsForTest( - std::vector<std::unique_ptr<PageRenovation>> renovations); - - private: - // Called to load JavaScript source from storage. - bool LoadSource(); - - // List of registered page renovations - std::vector<std::unique_ptr<PageRenovation>> renovations_; - - // Whether JavaScript source has been loaded. - bool is_loaded_; - // Contains JavaScript source. - base::string16 combined_source_; - - DISALLOW_COPY_AND_ASSIGN(PageRenovationLoader); -}; - -} // namespace offline_pages - -#endif // COMPONENTS_OFFLINE_PAGES_CORE_RENOVATIONS_PAGE_RENOVATION_LOADER_H_
diff --git a/components/offline_pages/core/renovations/page_renovation_loader_unittest.cc b/components/offline_pages/core/renovations/page_renovation_loader_unittest.cc deleted file mode 100644 index 66ad606..0000000 --- a/components/offline_pages/core/renovations/page_renovation_loader_unittest.cc +++ /dev/null
@@ -1,76 +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. - -#include "components/offline_pages/core/renovations/page_renovation_loader.h" - -#include <memory> - -#include "base/strings/string16.h" -#include "base/strings/utf_string_conversions.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace offline_pages { - -namespace { -const char kTestRenovationKey1[] = "abc_renovation"; -const char kTestRenovationKey2[] = "xyz_renovation"; -const char kTestRenovationScript[] = - "\nrun_renovations([\"abc_renovation\",\"xyz_renovation\",]);"; -} // namespace - -class PageRenovationLoaderTest : public testing::Test { - public: - void SetUp() override; - void TearDown() override; - - protected: - std::unique_ptr<PageRenovationLoader> page_renovation_loader_; -}; - -void PageRenovationLoaderTest::SetUp() { - page_renovation_loader_.reset(new PageRenovationLoader); - page_renovation_loader_->SetSourceForTest(base::string16()); -} - -void PageRenovationLoaderTest::TearDown() { - page_renovation_loader_.reset(); -} - -TEST_F(PageRenovationLoaderTest, NoRenovations) { - std::vector<std::string> renovation_keys; - // Pass empty list - base::string16 script; - EXPECT_TRUE( - page_renovation_loader_->GetRenovationScript(renovation_keys, &script)); - - EXPECT_EQ(script, base::UTF8ToUTF16("\nrun_renovations([]);")); -} - -TEST_F(PageRenovationLoaderTest, TestRenovations) { - std::vector<std::string> renovation_keys; - renovation_keys.push_back(kTestRenovationKey1); - renovation_keys.push_back(kTestRenovationKey2); - - base::string16 script; - EXPECT_TRUE( - page_renovation_loader_->GetRenovationScript(renovation_keys, &script)); - - EXPECT_EQ(script, base::UTF8ToUTF16(kTestRenovationScript)); -} - -TEST_F(PageRenovationLoaderTest, ReturnsSameScript) { - std::vector<std::string> renovation_keys; - renovation_keys.push_back(kTestRenovationKey1); - renovation_keys.push_back(kTestRenovationKey2); - - base::string16 script1, script2; - EXPECT_TRUE( - page_renovation_loader_->GetRenovationScript(renovation_keys, &script1)); - EXPECT_TRUE( - page_renovation_loader_->GetRenovationScript(renovation_keys, &script2)); - - EXPECT_EQ(script1, script2); -} - -} // namespace offline_pages
diff --git a/components/offline_pages/core/renovations/page_renovator.cc b/components/offline_pages/core/renovations/page_renovator.cc deleted file mode 100644 index 95219330..0000000 --- a/components/offline_pages/core/renovations/page_renovator.cc +++ /dev/null
@@ -1,56 +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. - -#include "components/offline_pages/core/renovations/page_renovator.h" - -#include <utility> - -#include "base/bind.h" -#include "base/callback.h" -#include "base/check.h" -#include "base/values.h" - -namespace offline_pages { - -PageRenovator::PageRenovator(PageRenovationLoader* renovation_loader, - std::unique_ptr<ScriptInjector> script_injector, - const GURL& request_url) - : renovation_loader_(renovation_loader), - script_injector_(std::move(script_injector)) { - DCHECK(renovation_loader); - - PrepareScript(request_url); -} - -PageRenovator::~PageRenovator() {} - -void PageRenovator::RunRenovations(CompletionCallback callback) { - // Prepare callback and inject combined script. - base::OnceCallback<void(base::Value)> cb = base::BindOnce( - [](base::OnceClosure callback, base::Value) { - if (callback) - std::move(callback).Run(); - }, - std::move(callback)); - - script_injector_->Inject(script_, std::move(cb)); -} - -void PageRenovator::PrepareScript(const GURL& url) { - std::vector<std::string> renovation_keys; - - // Pick which renovations to run. - for (const std::unique_ptr<PageRenovation>& renovation : - renovation_loader_->renovations()) { - if (renovation->ShouldRun(url)) { - renovation_keys.push_back(renovation->GetID()); - } - } - - // Store combined renovation script. TODO(crbug.com/736933): handle - // failed GetRenovationScript call. - renovation_loader_->GetRenovationScript(renovation_keys, &script_); -} - -} // namespace offline_pages
diff --git a/components/offline_pages/core/renovations/page_renovator.h b/components/offline_pages/core/renovations/page_renovator.h deleted file mode 100644 index f26137a..0000000 --- a/components/offline_pages/core/renovations/page_renovator.h +++ /dev/null
@@ -1,51 +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. - -#ifndef COMPONENTS_OFFLINE_PAGES_CORE_RENOVATIONS_PAGE_RENOVATOR_H_ -#define COMPONENTS_OFFLINE_PAGES_CORE_RENOVATIONS_PAGE_RENOVATOR_H_ - -#include <memory> - -#include "base/callback.h" -#include "base/memory/weak_ptr.h" -#include "base/strings/string16.h" -#include "base/time/time.h" -#include "components/offline_pages/core/renovations/page_renovation_loader.h" -#include "components/offline_pages/core/renovations/script_injector.h" -#include "components/offline_pages/core/snapshot_controller.h" - -namespace offline_pages { - -// This class runs renovations in a page being offlined. Upon -// construction, it determines which renovations to run. The user -// should then call RunRenovations when the page is sufficiently -// loaded. When complete (if ever) the passed CompletionCallback will -// be called. -class PageRenovator { - public: - using CompletionCallback = base::OnceClosure; - - // |renovation_loader| should be owned by the user and is expected to - // outlive this PageRenovator instance. - PageRenovator(PageRenovationLoader* renovation_loader, - std::unique_ptr<ScriptInjector> script_injector, - const GURL& request_url); - ~PageRenovator(); - - // Run renovation scripts and call callback when they complete. - void RunRenovations(CompletionCallback callback); - - private: - // This method is used in the constructor to determine which - // renovations to run and populate |script_| with the renovations. - void PrepareScript(const GURL& url); - - PageRenovationLoader* renovation_loader_; - std::unique_ptr<ScriptInjector> script_injector_; - base::string16 script_; -}; - -} // namespace offline_pages - -#endif // COMPONENTS_OFFLINE_PAGES_CORE_RENOVATIONS_PAGE_RENOVATOR_H_
diff --git a/components/offline_pages/core/renovations/page_renovator_unittest.cc b/components/offline_pages/core/renovations/page_renovator_unittest.cc deleted file mode 100644 index 78502c4..0000000 --- a/components/offline_pages/core/renovations/page_renovator_unittest.cc +++ /dev/null
@@ -1,89 +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. - -#include "components/offline_pages/core/renovations/page_renovator.h" - -#include <memory> -#include <utility> -#include <vector> - -#include "base/bind.h" -#include "base/callback_helpers.h" -#include "base/test/mock_callback.h" -#include "base/values.h" -#include "components/offline_pages/core/renovations/script_injector.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "url/gurl.h" - -namespace offline_pages { - -class PageRenovatorTest : public testing::Test { - public: - PageRenovatorTest(); - ~PageRenovatorTest() override; - - protected: - // ScriptInjector for testing PageRenovator. When Inject is called, - // it sets |script_injector_inject_called_| in the fixture to true, - // then calls the callback. - class FakeScriptInjector : public ScriptInjector { - public: - FakeScriptInjector(PageRenovatorTest* fixture); - ~FakeScriptInjector() override = default; - - void Inject(base::string16 script, ResultCallback callback) override; - - private: - PageRenovatorTest* fixture_; - }; - - // Creates a PageRenovator with simple defaults for testing. - void CreatePageRenovator(const GURL& url); - - PageRenovationLoader page_renovation_loader_; - bool script_injector_inject_called_ = false; - - // PageRenovator under test. - std::unique_ptr<PageRenovator> page_renovator_; -}; - -PageRenovatorTest::FakeScriptInjector::FakeScriptInjector( - PageRenovatorTest* fixture) - : fixture_(fixture) {} - -void PageRenovatorTest::FakeScriptInjector::Inject(base::string16 script, - ResultCallback callback) { - if (callback) - std::move(callback).Run(base::Value()); - fixture_->script_injector_inject_called_ = true; -} - -PageRenovatorTest::PageRenovatorTest() { - // Set PageRenovationLoader to have empty script and Renovation list. - page_renovation_loader_.SetSourceForTest(base::string16()); - page_renovation_loader_.SetRenovationsForTest( - std::vector<std::unique_ptr<PageRenovation>>()); - - page_renovator_ = std::make_unique<PageRenovator>( - &page_renovation_loader_, std::make_unique<FakeScriptInjector>(this), - GURL("example.com")); -} - -PageRenovatorTest::~PageRenovatorTest() {} - -TEST_F(PageRenovatorTest, InjectsScript) { - EXPECT_FALSE(script_injector_inject_called_); - page_renovator_->RunRenovations(base::NullCallback()); - EXPECT_TRUE(script_injector_inject_called_); -} - -TEST_F(PageRenovatorTest, CallsCallback) { - base::MockCallback<base::OnceClosure> mock_callback; - EXPECT_CALL(mock_callback, Run()).Times(1); - - page_renovator_->RunRenovations(mock_callback.Get()); -} - -} // namespace offline_pages
diff --git a/components/offline_pages/core/renovations/script_injector.h b/components/offline_pages/core/renovations/script_injector.h deleted file mode 100644 index 5f628b4..0000000 --- a/components/offline_pages/core/renovations/script_injector.h +++ /dev/null
@@ -1,33 +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. - -#ifndef COMPONENTS_OFFLINE_PAGES_CORE_RENOVATIONS_SCRIPT_INJECTOR_H_ -#define COMPONENTS_OFFLINE_PAGES_CORE_RENOVATIONS_SCRIPT_INJECTOR_H_ - -#include "base/callback_forward.h" -#include "base/strings/string16.h" - -namespace base { -class Value; -} // namespace base - -namespace offline_pages { - -// Interface for injecting and running scripts in some -// context. Inject() takes a string of JavaScript, injects it into the -// context, then calls the ResultCallback with the expression value. -class ScriptInjector { - public: - using ResultCallback = base::OnceCallback<void(base::Value)>; - - virtual ~ScriptInjector() = default; - - // Takes a string of JavaScript, injects it into the context, then - // calls the ResultCallback with the expression value. - virtual void Inject(base::string16 script, ResultCallback callback) = 0; -}; - -} // namespace offline_pages - -#endif // COMPONENTS_OFFLINE_PAGES_CORE_RENOVATIONS_SCRIPT_INJECTOR_H_
diff --git a/components/omnibox/browser/autocomplete_input.cc b/components/omnibox/browser/autocomplete_input.cc index 9f4fe574..13a4872 100644 --- a/components/omnibox/browser/autocomplete_input.cc +++ b/components/omnibox/browser/autocomplete_input.cc
@@ -153,7 +153,9 @@ if (should_use_https_as_default_scheme_ && type_ == metrics::OmniboxInputType::URL && scheme_ == base::ASCIIToUTF16(url::kHttpScheme) && - !base::StartsWith(text_, scheme_, base::CompareCase::INSENSITIVE_ASCII)) { + !base::StartsWith(text_, scheme_, base::CompareCase::INSENSITIVE_ASCII) && + !url::HostIsIPAddress(base::UTF16ToUTF8(text)) && + !net::IsHostnameNonUnique(base::UTF16ToUTF8(text))) { // Use HTTPS as the default scheme for URLs that are typed without a scheme. // Inputs of type UNKNOWN can still be valid URLs, but these will be mainly // intranet hosts which we don't to upgrade to HTTPS so we only check the
diff --git a/components/omnibox/browser/autocomplete_input_unittest.cc b/components/omnibox/browser/autocomplete_input_unittest.cc index cd973b6..46a9bf33 100644 --- a/components/omnibox/browser/autocomplete_input_unittest.cc +++ b/components/omnibox/browser/autocomplete_input_unittest.cc
@@ -384,6 +384,10 @@ {ASCIIToUTF16("example.com"), GURL("https://example.com"), true}, // Non-URL inputs shouldn't be upgraded. {ASCIIToUTF16("example query"), GURL(), false}, + // IP addresses shouldn't be upgraded. + {ASCIIToUTF16("127.0.0.1"), GURL("http://127.0.0.1"), false}, + // Non-unique hostnames shouldn't be upgraded. + {ASCIIToUTF16("site.test"), GURL("http://site.test"), false}, // Fully typed URLs shouldn't be upgraded. {ASCIIToUTF16("http://example.com"), GURL("http://example.com"), false}, {ASCIIToUTF16("HTTP://EXAMPLE.COM"), GURL("http://example.com"), false},
diff --git a/components/optimization_guide/core/BUILD.gn b/components/optimization_guide/core/BUILD.gn index ddd71c2b..1f274dce 100644 --- a/components/optimization_guide/core/BUILD.gn +++ b/components/optimization_guide/core/BUILD.gn
@@ -36,9 +36,6 @@ "optimization_guide_features.h", "optimization_guide_prefs.cc", "optimization_guide_prefs.h", - "optimization_guide_service.cc", - "optimization_guide_service.h", - "optimization_guide_service_observer.h", "optimization_guide_session_statistic.cc", "optimization_guide_session_statistic.h", "optimization_guide_store.cc", @@ -47,6 +44,9 @@ "optimization_guide_switches.h", "optimization_guide_util.cc", "optimization_guide_util.h", + "optimization_hints_component_observer.h", + "optimization_hints_component_update_listener.cc", + "optimization_hints_component_update_listener.h", "optimization_metadata.cc", "optimization_metadata.h", "optimization_target_model_observer.h", @@ -95,7 +95,6 @@ "//base", "//components/leveldb_proto", "//components/optimization_guide/proto:optimization_guide_proto", - "//content/public/browser", "//testing/gtest", ] } @@ -112,10 +111,10 @@ "hints_processing_util_unittest.cc", "optimization_filter_unittest.cc", "optimization_guide_features_unittest.cc", - "optimization_guide_service_unittest.cc", "optimization_guide_session_statistic_unittest.cc", "optimization_guide_store_unittest.cc", "optimization_guide_switches_unittest.cc", + "optimization_hints_component_update_listener_unittest.cc", "optimization_metadata_unittest.cc", "prediction_model_fetcher_unittest.cc", "prediction_model_unittest.cc",
diff --git a/components/optimization_guide/core/optimization_guide_service.cc b/components/optimization_guide/core/optimization_guide_service.cc deleted file mode 100644 index 1b546d7..0000000 --- a/components/optimization_guide/core/optimization_guide_service.cc +++ /dev/null
@@ -1,69 +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. - -#include "components/optimization_guide/core/optimization_guide_service.h" - -#include "base/bind.h" -#include "base/metrics/histogram_functions.h" -#include "base/task/post_task.h" - -namespace optimization_guide { - -OptimizationGuideService::OptimizationGuideService( - const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread_task_runner) - : ui_thread_task_runner_(ui_thread_task_runner) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); -} - -OptimizationGuideService::~OptimizationGuideService() {} - -void OptimizationGuideService::AddObserver( - OptimizationGuideServiceObserver* observer) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - observers_.AddObserver(observer); - if (hints_component_info_) { - observer->OnHintsComponentAvailable(*hints_component_info_); - } -} - -void OptimizationGuideService::RemoveObserver( - OptimizationGuideServiceObserver* observer) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - observers_.RemoveObserver(observer); -} - -void OptimizationGuideService::MaybeUpdateHintsComponent( - const HintsComponentInfo& info) { - ui_thread_task_runner_->PostTask( - FROM_HERE, - base::BindOnce( - &OptimizationGuideService::MaybeUpdateHintsComponentOnUIThread, - weak_ptr_factory_.GetWeakPtr(), info)); -} - -void OptimizationGuideService::MaybeUpdateHintsComponentOnUIThread( - const HintsComponentInfo& info) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK(info.version.IsValid()); - DCHECK(!info.path.empty()); - - // Do not update the component if the version isn't newer. This differs from - // the check in ComponentInstaller::InstallHelper(), because this rejects - // version equality, whereas InstallHelper() accepts it. - if (hints_component_info_ && - hints_component_info_->version.CompareTo(info.version) >= 0) { - return; - } - - base::UmaHistogramSparse( - "OptimizationGuide.OptimizationHintsComponent.MajorVersion", - info.version.components()[0]); - - hints_component_info_.emplace(info.version, info.path); - for (auto& observer : observers_) { - observer.OnHintsComponentAvailable(*hints_component_info_); - } -} - -} // namespace optimization_guide
diff --git a/components/optimization_guide/core/optimization_guide_service.h b/components/optimization_guide/core/optimization_guide_service.h deleted file mode 100644 index b4bf92d1..0000000 --- a/components/optimization_guide/core/optimization_guide_service.h +++ /dev/null
@@ -1,71 +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. - -#ifndef COMPONENTS_OPTIMIZATION_GUIDE_CORE_OPTIMIZATION_GUIDE_SERVICE_H_ -#define COMPONENTS_OPTIMIZATION_GUIDE_CORE_OPTIMIZATION_GUIDE_SERVICE_H_ - -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "base/observer_list.h" -#include "base/optional.h" -#include "base/sequence_checker.h" -#include "base/single_thread_task_runner.h" -#include "components/optimization_guide/core/hints_component_info.h" -#include "components/optimization_guide/core/optimization_guide_service_observer.h" - -namespace optimization_guide { - -// Tracks the info for the current Optimization Hints component and notifies -// observers of newly available hints components downloaded from the Component -// Updater. -class OptimizationGuideService { - public: - explicit OptimizationGuideService( - const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread_task_runner); - - virtual ~OptimizationGuideService(); - - // Adds the observer and synchronously dispatches the current - // HintsComponentInfo to it if one is already available. - // - // Virtual so it can be mocked out in tests. - virtual void AddObserver(OptimizationGuideServiceObserver* observer); - // Virtual so it can be mocked out in tests. - virtual void RemoveObserver(OptimizationGuideServiceObserver* observer); - - // Forwards the update hints component request on to the UI thread, where the - // actual work occurs. - // - // Virtual so it can be mocked out in tests. - virtual void MaybeUpdateHintsComponent(const HintsComponentInfo& info); - - // If the hints component version in |info| is greater than that in - // |hints_component_info_|, updates |hints_component_info_| and dispatches it - // to all observers. In the case where the version is not greater, it does - // nothing. - void MaybeUpdateHintsComponentOnUIThread(const HintsComponentInfo& info); - - private: - // Runner for indexing tasks. - SEQUENCE_CHECKER(sequence_checker_); - - // Runner for UI Thread tasks. - scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner_; - - // Observers receiving notifications on hints being processed. - base::ObserverList<OptimizationGuideServiceObserver>::Unchecked observers_; - - // The current HintsComponentInfo available to observers. This is unset until - // the first time MaybeUpdateHintsComponent() is called. - base::Optional<HintsComponentInfo> hints_component_info_; - - // Used to get |weak_ptr_| to self. - base::WeakPtrFactory<OptimizationGuideService> weak_ptr_factory_{this}; - - DISALLOW_COPY_AND_ASSIGN(OptimizationGuideService); -}; - -} // namespace optimization_guide - -#endif // COMPONENTS_OPTIMIZATION_GUIDE_CORE_OPTIMIZATION_GUIDE_SERVICE_H_
diff --git a/components/optimization_guide/core/optimization_guide_service_observer.h b/components/optimization_guide/core/optimization_guide_service_observer.h deleted file mode 100644 index 72b06d9..0000000 --- a/components/optimization_guide/core/optimization_guide_service_observer.h +++ /dev/null
@@ -1,29 +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. - -#ifndef COMPONENTS_OPTIMIZATION_GUIDE_CORE_OPTIMIZATION_GUIDE_SERVICE_OBSERVER_H_ -#define COMPONENTS_OPTIMIZATION_GUIDE_CORE_OPTIMIZATION_GUIDE_SERVICE_OBSERVER_H_ - -namespace optimization_guide { - -struct HintsComponentInfo; - -// Interface for objects that wish to be notified of changes in the Optimization -// Guide Service. -// -// All calls will be made on the UI thread. -class OptimizationGuideServiceObserver { - public: - // Called when a new hints component is available for processing. While this - // is called on the UI thread, it is recommended that processing of the new - // component via ProcessHintsComponent() occur on a background thread. - virtual void OnHintsComponentAvailable(const HintsComponentInfo& info) = 0; - - protected: - virtual ~OptimizationGuideServiceObserver() {} -}; - -} // namespace optimization_guide - -#endif // COMPONENTS_OPTIMIZATION_GUIDE_CORE_OPTIMIZATION_GUIDE_SERVICE_OBSERVER_H_
diff --git a/components/optimization_guide/core/optimization_hints_component_observer.h b/components/optimization_guide/core/optimization_hints_component_observer.h new file mode 100644 index 0000000..5394b74 --- /dev/null +++ b/components/optimization_guide/core/optimization_hints_component_observer.h
@@ -0,0 +1,29 @@ +// 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. + +#ifndef COMPONENTS_OPTIMIZATION_GUIDE_CORE_OPTIMIZATION_HINTS_COMPONENT_OBSERVER_H_ +#define COMPONENTS_OPTIMIZATION_GUIDE_CORE_OPTIMIZATION_HINTS_COMPONENT_OBSERVER_H_ + +namespace optimization_guide { + +struct HintsComponentInfo; + +// Interface for objects that wish to be notified of changes to the Optimization +// Hints Component. +// +// All calls will be made on the UI thread. +class OptimizationHintsComponentObserver { + public: + // Called when a new hints component is available for processing. While this + // is called on the UI thread, it is recommended that processing of the new + // component occur on a background thread. + virtual void OnHintsComponentAvailable(const HintsComponentInfo& info) = 0; + + protected: + virtual ~OptimizationHintsComponentObserver() = default; +}; + +} // namespace optimization_guide + +#endif // COMPONENTS_OPTIMIZATION_GUIDE_CORE_OPTIMIZATION_HINTS_COMPONENT_OBSERVER_H_
diff --git a/components/optimization_guide/core/optimization_hints_component_update_listener.cc b/components/optimization_guide/core/optimization_hints_component_update_listener.cc new file mode 100644 index 0000000..3c2b04d1 --- /dev/null +++ b/components/optimization_guide/core/optimization_hints_component_update_listener.cc
@@ -0,0 +1,67 @@ +// 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. + +#include "components/optimization_guide/core/optimization_hints_component_update_listener.h" + +#include "base/metrics/histogram_functions.h" + +namespace optimization_guide { + +// static +OptimizationHintsComponentUpdateListener* +OptimizationHintsComponentUpdateListener::GetInstance() { + static base::NoDestructor<OptimizationHintsComponentUpdateListener> service; + return service.get(); +} + +OptimizationHintsComponentUpdateListener:: + OptimizationHintsComponentUpdateListener() = default; +OptimizationHintsComponentUpdateListener:: + ~OptimizationHintsComponentUpdateListener() = default; + +void OptimizationHintsComponentUpdateListener::AddObserver( + OptimizationHintsComponentObserver* observer) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + observers_.AddObserver(observer); + + if (hints_component_info_) { + observer->OnHintsComponentAvailable(*hints_component_info_); + } +} + +void OptimizationHintsComponentUpdateListener::RemoveObserver( + OptimizationHintsComponentObserver* observer) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + observers_.RemoveObserver(observer); +} + +void OptimizationHintsComponentUpdateListener::MaybeUpdateHintsComponent( + const HintsComponentInfo& info) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(info.version.IsValid()); + DCHECK(!info.path.empty()); + + // Do not update the component if the version isn't newer. This differs from + // the check in ComponentInstaller::InstallHelper(), because this rejects + // version equality, whereas InstallHelper() accepts it. + if (hints_component_info_ && + hints_component_info_->version.CompareTo(info.version) >= 0) { + return; + } + + base::UmaHistogramSparse( + "OptimizationGuide.OptimizationHintsComponent.MajorVersion", + info.version.components()[0]); + + hints_component_info_.emplace(info.version, info.path); + for (auto& observer : observers_) { + observer.OnHintsComponentAvailable(*hints_component_info_); + } +} + +void OptimizationHintsComponentUpdateListener::ResetStateForTesting() { + hints_component_info_ = base::nullopt; +} + +} // namespace optimization_guide
diff --git a/components/optimization_guide/core/optimization_hints_component_update_listener.h b/components/optimization_guide/core/optimization_hints_component_update_listener.h new file mode 100644 index 0000000..0cf4be6 --- /dev/null +++ b/components/optimization_guide/core/optimization_hints_component_update_listener.h
@@ -0,0 +1,70 @@ +// 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. + +#ifndef COMPONENTS_OPTIMIZATION_GUIDE_CORE_OPTIMIZATION_HINTS_COMPONENT_UPDATE_LISTENER_H_ +#define COMPONENTS_OPTIMIZATION_GUIDE_CORE_OPTIMIZATION_HINTS_COMPONENT_UPDATE_LISTENER_H_ + +#include "base/no_destructor.h" +#include "base/observer_list.h" +#include "base/optional.h" +#include "base/sequence_checker.h" +#include "components/optimization_guide/core/hints_component_info.h" +#include "components/optimization_guide/core/optimization_hints_component_observer.h" + +namespace optimization_guide { + +// Tracks the info for the current Optimization Hints component and notifies +// observers of newly available hints components downloaded from the Component +// Updater. +class OptimizationHintsComponentUpdateListener { + public: + static OptimizationHintsComponentUpdateListener* GetInstance(); + + OptimizationHintsComponentUpdateListener( + const OptimizationHintsComponentUpdateListener&) = delete; + OptimizationHintsComponentUpdateListener& operator=( + const OptimizationHintsComponentUpdateListener&) = delete; + + // Adds the observer and synchronously dispatches the current + // HintsComponentInfo to it if one is already available. + // + // Virtual so it can be mocked out in tests. + virtual void AddObserver(OptimizationHintsComponentObserver* observer); + // Virtual so it can be mocked out in tests. + virtual void RemoveObserver(OptimizationHintsComponentObserver* observer); + + // If the hints component version in |info| is greater than that in + // |hints_component_info_|, updates |hints_component_info_| and dispatches it + // to all observers. In the case where the version is not greater, it does + // nothing. + void MaybeUpdateHintsComponent(const HintsComponentInfo& info); + + // Currently received HintsComponentInfo. + base::Optional<HintsComponentInfo> hints_component_info() { + return hints_component_info_; + } + + private: + OptimizationHintsComponentUpdateListener(); + ~OptimizationHintsComponentUpdateListener(); + + friend class base::NoDestructor<OptimizationHintsComponentUpdateListener>; + friend class OptimizationHintsComponentUpdateListenerTest; + + void ResetStateForTesting(); + + // Runner for indexing tasks. + SEQUENCE_CHECKER(sequence_checker_); + + // Observers receiving notifications on hints being processed. + base::ObserverList<OptimizationHintsComponentObserver>::Unchecked observers_; + + // The current HintsComponentInfo available to observers. This is unset until + // the first time MaybeUpdateHintsComponent() is called. + base::Optional<HintsComponentInfo> hints_component_info_; +}; + +} // namespace optimization_guide + +#endif // COMPONENTS_OPTIMIZATION_GUIDE_CORE_OPTIMIZATION_HINTS_COMPONENT_UPDATE_LISTENER_H_
diff --git a/components/optimization_guide/core/optimization_guide_service_unittest.cc b/components/optimization_guide/core/optimization_hints_component_update_listener_unittest.cc similarity index 82% rename from components/optimization_guide/core/optimization_guide_service_unittest.cc rename to components/optimization_guide/core/optimization_hints_component_update_listener_unittest.cc index 6e00e68..50a4bf3 100644 --- a/components/optimization_guide/core/optimization_guide_service_unittest.cc +++ b/components/optimization_guide/core/optimization_hints_component_update_listener_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/optimization_guide/core/optimization_guide_service.h" +#include "components/optimization_guide/core/optimization_hints_component_update_listener.h" #include <memory> #include <string> @@ -11,6 +11,7 @@ #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" #include "base/macros.h" +#include "base/memory/ptr_util.h" #include "base/run_loop.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/task_environment.h" @@ -23,7 +24,7 @@ const base::FilePath::CharType kFileName1[] = FILE_PATH_LITERAL("somefile1.pb"); const base::FilePath::CharType kFileName2[] = FILE_PATH_LITERAL("somefile2.pb"); -class TestObserver : public OptimizationGuideServiceObserver { +class TestObserver : public OptimizationHintsComponentObserver { public: TestObserver() : hints_component_notification_count_(0), @@ -55,34 +56,37 @@ DISALLOW_COPY_AND_ASSIGN(TestObserver); }; -class OptimizationGuideServiceTest : public testing::Test { +class OptimizationHintsComponentUpdateListenerTest : public testing::Test { public: - OptimizationGuideServiceTest() {} - - ~OptimizationGuideServiceTest() override {} + OptimizationHintsComponentUpdateListenerTest() = default; + ~OptimizationHintsComponentUpdateListenerTest() override = default; void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); - optimization_guide_service_ = std::make_unique<OptimizationGuideService>( - task_environment_.GetMainThreadTaskRunner()); + + OptimizationHintsComponentUpdateListener::GetInstance() + ->ResetStateForTesting(); observer_ = std::make_unique<TestObserver>(); } - OptimizationGuideService* optimization_guide_service() { - return optimization_guide_service_.get(); - } + void TearDown() override { RemoveObserver(); } TestObserver* observer() { return observer_.get(); } - void AddObserver() { optimization_guide_service_->AddObserver(observer()); } + void AddObserver() { + OptimizationHintsComponentUpdateListener::GetInstance()->AddObserver( + observer()); + } void RemoveObserver() { - optimization_guide_service_->RemoveObserver(observer()); + OptimizationHintsComponentUpdateListener::GetInstance()->RemoveObserver( + observer()); } void MaybeUpdateHintsComponent(const HintsComponentInfo& info) { - optimization_guide_service_->MaybeUpdateHintsComponent(info); + OptimizationHintsComponentUpdateListener::GetInstance() + ->MaybeUpdateHintsComponent(info); task_environment_.RunUntilIdle(); base::RunLoop().RunUntilIdle(); } @@ -93,13 +97,13 @@ base::test::TaskEnvironment task_environment_; base::ScopedTempDir temp_dir_; - std::unique_ptr<OptimizationGuideService> optimization_guide_service_; std::unique_ptr<TestObserver> observer_; - DISALLOW_COPY_AND_ASSIGN(OptimizationGuideServiceTest); + DISALLOW_COPY_AND_ASSIGN(OptimizationHintsComponentUpdateListenerTest); }; -TEST_F(OptimizationGuideServiceTest, ProcessHintsIssuesNotification) { +TEST_F(OptimizationHintsComponentUpdateListenerTest, + ProcessHintsIssuesNotification) { base::HistogramTester histogram_tester; AddObserver(); @@ -116,7 +120,8 @@ "OptimizationGuide.OptimizationHintsComponent.MajorVersion", 1, 1); } -TEST_F(OptimizationGuideServiceTest, ProcessHintsNewVersionProcessed) { +TEST_F(OptimizationHintsComponentUpdateListenerTest, + ProcessHintsNewVersionProcessed) { base::HistogramTester histogram_tester; AddObserver(); @@ -141,7 +146,8 @@ "OptimizationGuide.OptimizationHintsComponent.MajorVersion", 2, 1); } -TEST_F(OptimizationGuideServiceTest, ProcessHintsPastVersionIgnored) { +TEST_F(OptimizationHintsComponentUpdateListenerTest, + ProcessHintsPastVersionIgnored) { base::HistogramTester histogram_tester; AddObserver(); @@ -163,7 +169,8 @@ "OptimizationGuide.OptimizationHintsComponent.MajorVersion", 2, 1); } -TEST_F(OptimizationGuideServiceTest, ProcessHintsSameVersionIgnored) { +TEST_F(OptimizationHintsComponentUpdateListenerTest, + ProcessHintsSameVersionIgnored) { base::HistogramTester histogram_tester; AddObserver(); @@ -183,7 +190,7 @@ "OptimizationGuide.OptimizationHintsComponent.MajorVersion", 2, 1); } -TEST_F(OptimizationGuideServiceTest, +TEST_F(OptimizationHintsComponentUpdateListenerTest, UnregisteredObserverDoesNotReceiveNotification) { base::HistogramTester histogram_tester; @@ -203,7 +210,7 @@ "OptimizationGuide.OptimizationHintsComponent.MajorVersion", 1, 1); } -TEST_F(OptimizationGuideServiceTest, +TEST_F(OptimizationHintsComponentUpdateListenerTest, RegisteredObserverReceivesNotificationForCurrentComponent) { base::HistogramTester histogram_tester;
diff --git a/components/optimization_guide/core/test_hints_component_creator.cc b/components/optimization_guide/core/test_hints_component_creator.cc index 359d5a9..46ca36dd 100644 --- a/components/optimization_guide/core/test_hints_component_creator.cc +++ b/components/optimization_guide/core/test_hints_component_creator.cc
@@ -12,6 +12,7 @@ #include "base/threading/thread_restrictions.h" #include "base/version.h" #include "components/optimization_guide/core/bloom_filter.h" +#include "components/optimization_guide/core/optimization_hints_component_update_listener.h" #include "testing/gtest/include/gtest/gtest.h" namespace {
diff --git a/components/optimization_guide/core/test_hints_component_creator.h b/components/optimization_guide/core/test_hints_component_creator.h index 8f24b9f..97a3141 100644 --- a/components/optimization_guide/core/test_hints_component_creator.h +++ b/components/optimization_guide/core/test_hints_component_creator.h
@@ -11,10 +11,12 @@ #include "base/files/file_path.h" #include "base/files/scoped_temp_dir.h" #include "base/macros.h" -#include "components/optimization_guide/core/optimization_guide_service.h" #include "components/optimization_guide/proto/hints.pb.h" namespace optimization_guide { + +struct HintsComponentInfo; + namespace testing { // Helper class to create test OptimizationHints components for testing.
diff --git a/components/permissions/android/java/src/org/chromium/components/permissions/PermissionDialogController.java b/components/permissions/android/java/src/org/chromium/components/permissions/PermissionDialogController.java index 3865d538..20bb219e 100644 --- a/components/permissions/android/java/src/org/chromium/components/permissions/PermissionDialogController.java +++ b/components/permissions/android/java/src/org/chromium/components/permissions/PermissionDialogController.java
@@ -13,6 +13,7 @@ import org.chromium.base.BuildInfo; import org.chromium.base.ContextUtils; import org.chromium.base.annotations.CalledByNative; +import org.chromium.components.content_settings.ContentSettingValues; import org.chromium.ui.modaldialog.DialogDismissalCause; import org.chromium.ui.modaldialog.ModalDialogManager; import org.chromium.ui.modaldialog.ModalDialogProperties; @@ -52,6 +53,10 @@ private PermissionDialogDelegate mDialogDelegate; private ModalDialogManager mModalDialogManager; + // Array with ints of type {@link ContentSettingsType}. + private int[] mLastPermissions; + private @ContentSettingValues int mLastResult; + // As the PermissionRequestManager handles queueing for a tab and only shows prompts for active // tabs, we typically only have one request. This class only handles multiple requests at once // when either: @@ -90,6 +95,22 @@ } /** + * Returns whether this PropertyModel is for the permission dialog. + * @param model The PropertyModel to be checked. + */ + public static boolean isPermissionDialogModel(PropertyModel model) { + return model.get(ModalDialogProperties.CONTROLLER) instanceof PermissionDialogController; + } + + public int[] getLastDialogPermissions() { + return mLastPermissions.clone(); + } + + public @ContentSettingValues int getLastDialogResult() { + return mLastResult; + } + + /** * Queues a modal permission dialog for display. If there are currently no dialogs on screen, it * will be displayed immediately. Otherwise, it will be displayed as soon as the user responds * to the current dialog. @@ -115,7 +136,7 @@ mState = State.NOT_SHOWING; } else { mDialogDelegate.onAccept(); - destroyDelegate(); + destroyDelegate(ContentSettingValues.ALLOW); } scheduleDisplay(); } @@ -129,7 +150,7 @@ mState = State.NOT_SHOWING; } else { mDialogDelegate.onDismiss(); - destroyDelegate(); + destroyDelegate(ContentSettingValues.BLOCK); } scheduleDisplay(); } @@ -152,7 +173,7 @@ // TODO(timloh): This probably doesn't work, as this happens synchronously when creating // the PermissionPromptAndroid, so the PermissionRequestManager won't be ready yet. mDialogDelegate.onDismiss(); - destroyDelegate(); + destroyDelegate(ContentSettingValues.DEFAULT); return; } @@ -260,7 +281,7 @@ assert mState == State.PROMPT_OPEN; mDialogDelegate.onDismiss(); } - destroyDelegate(); + destroyDelegate(ContentSettingValues.BLOCK); scheduleDisplay(); } } @@ -284,7 +305,11 @@ } } - private void destroyDelegate() { + private void destroyDelegate(@ContentSettingValues int result) { + if (result != ContentSettingValues.DEFAULT) { + mLastPermissions = mDialogDelegate.getContentSettingsTypes(); + mLastResult = result; + } mDialogDelegate.destroy(); mDialogDelegate = null; mState = State.NOT_SHOWING;
diff --git a/components/policy/core/common/cloud/cloud_policy_client.cc b/components/policy/core/common/cloud/cloud_policy_client.cc index 0d7f437..d363034f 100644 --- a/components/policy/core/common/cloud/cloud_policy_client.cc +++ b/components/policy/core/common/cloud/cloud_policy_client.cc
@@ -596,6 +596,7 @@ void CloudPolicyClient::UploadSecurityEventReport( content::BrowserContext* context, + bool include_device_info, base::Value report, StatusCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -603,7 +604,7 @@ CreateNewRealtimeReportingJob( std::move(report), service()->configuration()->GetReportingConnectorServerUrl(context), - add_connector_url_params_, std::move(callback)); + include_device_info, add_connector_url_params_, std::move(callback)); } void CloudPolicyClient::UploadEncryptedReport( @@ -636,7 +637,8 @@ app_install_report_request_job_ = CreateNewRealtimeReportingJob( std::move(report), service()->configuration()->GetRealtimeReportingServerUrl(), - /* add_connector_url_params=*/false, std::move(callback)); + /* include_device_info */ true, /* add_connector_url_params=*/false, + std::move(callback)); DCHECK(app_install_report_request_job_); } @@ -657,6 +659,7 @@ extension_install_report_request_job_ = CreateNewRealtimeReportingJob( std::move(report), service()->configuration()->GetRealtimeReportingServerUrl(), + /* include_device_info */ true, /* add_connector_url_params=*/false, std::move(callback)); DCHECK(extension_install_report_request_job_); } @@ -702,11 +705,12 @@ DeviceManagementService::Job* CloudPolicyClient::CreateNewRealtimeReportingJob( base::Value report, const std::string& server_url, + bool include_device_info, bool add_connector_url_params, StatusCallback callback) { std::unique_ptr<RealtimeReportingJobConfiguration> config = std::make_unique<RealtimeReportingJobConfiguration>( - this, server_url, add_connector_url_params, + this, server_url, include_device_info, add_connector_url_params, base::BindOnce(&CloudPolicyClient::OnRealtimeReportUploadCompleted, weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
diff --git a/components/policy/core/common/cloud/cloud_policy_client.h b/components/policy/core/common/cloud/cloud_policy_client.h index c58f544e..ddc61135 100644 --- a/components/policy/core/common/cloud/cloud_policy_client.h +++ b/components/policy/core/common/cloud/cloud_policy_client.h
@@ -313,8 +313,11 @@ // Uploads a report containing enterprise connectors real-time security // events for |context|. As above, the client must be in a registered state. - // The |callback| will be called when the operation completes. + // If |include_device_info| is true, information specific to the device such + // as the device name, user, id and OS will be included in the report. The + // |callback| will be called when the operation completes. virtual void UploadSecurityEventReport(content::BrowserContext* context, + bool include_device_info, base::Value report, StatusCallback callback); @@ -792,12 +795,15 @@ private: // Creates a new real-time reporting job and appends it to |request_jobs_|. // The job will send its report to the |server_url| endpoint. If + // |include_device_info| is true, information specific to the device such as + // the device name, user, id and OS will be included in the report. If // |add_connector_url_params| is true then URL paramaters specific to // enterprise connectors are added to the request uploading the report. // |callback| is invoked once the report is uploaded. DeviceManagementService::Job* CreateNewRealtimeReportingJob( base::Value report, const std::string& server_url, + bool include_device_info, bool add_connector_url_params, StatusCallback callback);
diff --git a/components/policy/core/common/cloud/cloud_policy_client_unittest.cc b/components/policy/core/common/cloud/cloud_policy_client_unittest.cc index eb2b034..85e9b5d 100644 --- a/components/policy/core/common/cloud/cloud_policy_client_unittest.cc +++ b/components/policy/core/common/cloud/cloud_policy_client_unittest.cc
@@ -1477,7 +1477,19 @@ #if defined(OS_WIN) || defined(OS_APPLE) || defined(OS_LINUX) || \ defined(OS_CHROMEOS) -TEST_F(CloudPolicyClientTest, UploadSecurityEventReport) { + +class CloudPolicyClientUploadSecurityEventTest + : public CloudPolicyClientTest, + public testing::WithParamInterface<bool> { + public: + bool include_device_info() const { return GetParam(); } +}; + +INSTANTIATE_TEST_SUITE_P(, + CloudPolicyClientUploadSecurityEventTest, + testing::Bool()); + +TEST_P(CloudPolicyClientUploadSecurityEventTest, Test) { RegisterClient(); ExpectAndCaptureJSONJob(/*response=*/"{}"); @@ -1486,7 +1498,8 @@ base::BindOnce(&MockStatusCallbackObserver::OnCallbackComplete, base::Unretained(&callback_observer_)); - client_->UploadSecurityEventReport(nullptr, MakeDefaultRealtimeReport(), + client_->UploadSecurityEventReport(nullptr, include_device_info(), + MakeDefaultRealtimeReport(), std::move(callback)); base::RunLoop().RunUntilIdle(); EXPECT_EQ( @@ -1498,33 +1511,54 @@ base::Optional<base::Value> payload = base::JSONReader::Read(job_payload_); ASSERT_TRUE(payload); - EXPECT_EQ(kDMToken, *payload->FindStringPath( - ReportingJobConfigurationBase:: - DeviceDictionaryBuilder::GetDMTokenPath())); - EXPECT_EQ(client_id_, *payload->FindStringPath( - ReportingJobConfigurationBase:: - DeviceDictionaryBuilder::GetClientIdPath())); - EXPECT_EQ(policy::GetOSUsername(), - *payload->FindStringPath( - ReportingJobConfigurationBase::BrowserDictionaryBuilder:: - GetMachineUserPath())); + ASSERT_FALSE(policy::GetDeviceName().empty()); EXPECT_EQ(version_info::GetVersionNumber(), *payload->FindStringPath( ReportingJobConfigurationBase::BrowserDictionaryBuilder:: GetChromeVersionPath())); - EXPECT_EQ(policy::GetOSPlatform(), - *payload->FindStringPath( - ReportingJobConfigurationBase::DeviceDictionaryBuilder:: - GetOSPlatformPath())); - EXPECT_EQ(policy::GetOSVersion(), - *payload->FindStringPath( - ReportingJobConfigurationBase::DeviceDictionaryBuilder:: - GetOSVersionPath())); - EXPECT_FALSE(policy::GetDeviceName().empty()); - EXPECT_EQ( - policy::GetDeviceName(), - *payload->FindStringPath(ReportingJobConfigurationBase:: - DeviceDictionaryBuilder::GetNamePath())); + + if (include_device_info()) { + EXPECT_EQ(kDMToken, *payload->FindStringPath( + ReportingJobConfigurationBase:: + DeviceDictionaryBuilder::GetDMTokenPath())); + EXPECT_EQ(client_id_, *payload->FindStringPath( + ReportingJobConfigurationBase:: + DeviceDictionaryBuilder::GetClientIdPath())); + EXPECT_EQ(policy::GetOSUsername(), + *payload->FindStringPath( + ReportingJobConfigurationBase::BrowserDictionaryBuilder:: + GetMachineUserPath())); + EXPECT_EQ(policy::GetOSPlatform(), + *payload->FindStringPath( + ReportingJobConfigurationBase::DeviceDictionaryBuilder:: + GetOSPlatformPath())); + EXPECT_EQ(policy::GetOSVersion(), + *payload->FindStringPath( + ReportingJobConfigurationBase::DeviceDictionaryBuilder:: + GetOSVersionPath())); + EXPECT_EQ( + policy::GetDeviceName(), + *payload->FindStringPath(ReportingJobConfigurationBase:: + DeviceDictionaryBuilder::GetNamePath())); + } else { + EXPECT_FALSE( + payload->FindStringPath(ReportingJobConfigurationBase:: + DeviceDictionaryBuilder::GetDMTokenPath())); + EXPECT_FALSE(payload->FindStringPath( + ReportingJobConfigurationBase::DeviceDictionaryBuilder:: + GetClientIdPath())); + EXPECT_FALSE(payload->FindStringPath( + ReportingJobConfigurationBase::BrowserDictionaryBuilder:: + GetMachineUserPath())); + EXPECT_FALSE(payload->FindStringPath( + ReportingJobConfigurationBase::DeviceDictionaryBuilder:: + GetOSPlatformPath())); + EXPECT_FALSE(payload->FindStringPath( + ReportingJobConfigurationBase::DeviceDictionaryBuilder:: + GetOSVersionPath())); + EXPECT_FALSE(payload->FindStringPath( + ReportingJobConfigurationBase::DeviceDictionaryBuilder::GetNamePath())); + } base::Value* events = payload->FindPath(RealtimeReportingJobConfiguration::kEventListKey); @@ -1535,7 +1569,7 @@ TEST_F(CloudPolicyClientTest, RealtimeReportMerge) { auto config = std::make_unique<RealtimeReportingJobConfiguration>( client_.get(), service_.configuration()->GetRealtimeReportingServerUrl(), - /*add_connector_url_params=*/false, + /*include_device_info*/ true, /*add_connector_url_params=*/false, RealtimeReportingJobConfiguration::UploadCompleteCallback()); // Add one report to the config.
diff --git a/components/policy/core/common/cloud/encrypted_reporting_job_configuration.cc b/components/policy/core/common/cloud/encrypted_reporting_job_configuration.cc index 2668f5c..69062241 100644 --- a/components/policy/core/common/cloud/encrypted_reporting_job_configuration.cc +++ b/components/policy/core/common/cloud/encrypted_reporting_job_configuration.cc
@@ -31,6 +31,7 @@ client->GetURLLoaderFactory(), client, server_url, + /*include_device_info*/ true, std::move(complete_cb)) { // Merge it into the base class payload. payload_.MergeDictionary(&merging_payload);
diff --git a/components/policy/core/common/cloud/mock_cloud_policy_client.h b/components/policy/core/common/cloud/mock_cloud_policy_client.h index f730be1..1c62296 100644 --- a/components/policy/core/common/cloud/mock_cloud_policy_client.h +++ b/components/policy/core/common/cloud/mock_cloud_policy_client.h
@@ -101,12 +101,14 @@ StatusCallback&)); void UploadSecurityEventReport(content::BrowserContext* context, + bool include_device_info, base::Value value, StatusCallback callback) override { - UploadSecurityEventReport_(context, value, callback); + UploadSecurityEventReport_(context, include_device_info, value, callback); } - MOCK_METHOD3(UploadSecurityEventReport_, + MOCK_METHOD4(UploadSecurityEventReport_, void(content::BrowserContext* context, + bool include_device_info, base::Value&, StatusCallback&));
diff --git a/components/policy/core/common/cloud/realtime_reporting_job_configuration.cc b/components/policy/core/common/cloud/realtime_reporting_job_configuration.cc index 8f15111..e2926254 100644 --- a/components/policy/core/common/cloud/realtime_reporting_job_configuration.cc +++ b/components/policy/core/common/cloud/realtime_reporting_job_configuration.cc
@@ -42,12 +42,14 @@ RealtimeReportingJobConfiguration::RealtimeReportingJobConfiguration( CloudPolicyClient* client, const std::string& server_url, + bool include_device_info, bool add_connector_url_params, UploadCompleteCallback callback) : ReportingJobConfigurationBase(TYPE_UPLOAD_REAL_TIME_REPORT, client->GetURLLoaderFactory(), client, server_url, + include_device_info, std::move(callback)) { InitializePayloadInternal(client, add_connector_url_params); }
diff --git a/components/policy/core/common/cloud/realtime_reporting_job_configuration.h b/components/policy/core/common/cloud/realtime_reporting_job_configuration.h index d15e0ae..89fa973 100644 --- a/components/policy/core/common/cloud/realtime_reporting_job_configuration.h +++ b/components/policy/core/common/cloud/realtime_reporting_job_configuration.h
@@ -46,6 +46,7 @@ // parameters will be used. RealtimeReportingJobConfiguration(CloudPolicyClient* client, const std::string& server_url, + bool include_device_info, bool add_connector_url_params, UploadCompleteCallback callback);
diff --git a/components/policy/core/common/cloud/realtime_reporting_job_configuration_unittest.cc b/components/policy/core/common/cloud/realtime_reporting_job_configuration_unittest.cc index 036ff5d..9022f4d 100644 --- a/components/policy/core/common/cloud/realtime_reporting_job_configuration_unittest.cc +++ b/components/policy/core/common/cloud/realtime_reporting_job_configuration_unittest.cc
@@ -79,7 +79,7 @@ client_.SetDMToken(kDummyToken); configuration_ = std::make_unique<RealtimeReportingJobConfiguration>( &client_, service_.configuration()->GetRealtimeReportingServerUrl(), - /*add_connector_url_params=*/false, + /*include_device_info=*/true, /*add_connector_url_params=*/false, base::BindOnce(&MockCallbackObserver::OnURLLoadComplete, base::Unretained(&callback_observer_))); base::Value context(base::Value::Type::DICTIONARY);
diff --git a/components/policy/core/common/cloud/reporting_job_configuration_base.cc b/components/policy/core/common/cloud/reporting_job_configuration_base.cc index e37bde82..8e97e95b 100644 --- a/components/policy/core/common/cloud/reporting_job_configuration_base.cc +++ b/components/policy/core/common/cloud/reporting_job_configuration_base.cc
@@ -112,8 +112,9 @@ "chromeVersion"; // static -base::Value ReportingJobConfigurationBase::BrowserDictionaryBuilder:: - BuildBrowserDictionary() { +base::Value +ReportingJobConfigurationBase::BrowserDictionaryBuilder::BuildBrowserDictionary( + bool include_device_info) { base::Value browser_dictionary{base::Value::Type::DICTIONARY}; base::FilePath browser_id; @@ -121,7 +122,9 @@ browser_dictionary.SetStringKey(kBrowserId, browser_id.value()); } - browser_dictionary.SetStringKey(kMachineUser, GetOSUsername()); + if (include_device_info) + browser_dictionary.SetStringKey(kMachineUser, GetOSUsername()); + browser_dictionary.SetStringKey(kChromeVersion, version_info::GetVersionNumber()); return browser_dictionary; @@ -265,6 +268,7 @@ scoped_refptr<network::SharedURLLoaderFactory> factory, CloudPolicyClient* client, const std::string& server_url, + bool include_device_info, UploadCompleteCallback callback) : JobConfigurationBase(type, DMAuth::FromDMToken(client->dm_token()), @@ -274,20 +278,24 @@ callback_(std::move(callback)), server_url_(server_url) { DCHECK(GetAuth().has_dm_token()); - InitializePayload(client); + InitializePayload(client, include_device_info); } ReportingJobConfigurationBase::~ReportingJobConfigurationBase() = default; void ReportingJobConfigurationBase::InitializePayload( - CloudPolicyClient* client) { + CloudPolicyClient* client, + bool include_device_info) { AddParameter("key", google_apis::GetAPIKey()); - payload_.SetKey(DeviceDictionaryBuilder::kDeviceKey, - DeviceDictionaryBuilder::BuildDeviceDictionary( - client->dm_token(), client->client_id())); - payload_.SetKey(BrowserDictionaryBuilder::kBrowserKey, - BrowserDictionaryBuilder::BuildBrowserDictionary()); + if (include_device_info) { + payload_.SetKey(DeviceDictionaryBuilder::kDeviceKey, + DeviceDictionaryBuilder::BuildDeviceDictionary( + client->dm_token(), client->client_id())); + } + payload_.SetKey( + BrowserDictionaryBuilder::kBrowserKey, + BrowserDictionaryBuilder::BuildBrowserDictionary(include_device_info)); } } // namespace policy
diff --git a/components/policy/core/common/cloud/reporting_job_configuration_base.h b/components/policy/core/common/cloud/reporting_job_configuration_base.h index fbe67a0..8f4ad29 100644 --- a/components/policy/core/common/cloud/reporting_job_configuration_base.h +++ b/components/policy/core/common/cloud/reporting_job_configuration_base.h
@@ -81,7 +81,7 @@ // Dictionary Key Name static const char kBrowserKey[]; - static base::Value BuildBrowserDictionary(); + static base::Value BuildBrowserDictionary(bool include_device_info); static std::string GetBrowserIdPath(); static std::string GetUserAgentPath(); @@ -120,6 +120,7 @@ scoped_refptr<network::SharedURLLoaderFactory> factory, CloudPolicyClient* client, const std::string& server_url, + bool include_device_info, UploadCompleteCallback callback); ~ReportingJobConfigurationBase() override; @@ -150,8 +151,10 @@ UploadCompleteCallback callback_; private: - // Initializes request payload. - void InitializePayload(CloudPolicyClient* client); + // Initializes request payload. If |include_device_info| is false, the + // "device" and "browser.machineUser" fields (see comment at the top of the + // file) are excluded from the payload. + void InitializePayload(CloudPolicyClient* client, bool include_device_info); const std::string server_url_;
diff --git a/components/policy/proto/device_management_backend.proto b/components/policy/proto/device_management_backend.proto index cf783a3..06efd3af 100644 --- a/components/policy/proto/device_management_backend.proto +++ b/components/policy/proto/device_management_backend.proto
@@ -2965,7 +2965,7 @@ USER_TYPE_REGULAR = 1; USER_TYPE_GUEST = 2; USER_TYPE_PUBLIC_ACCOUNT = 3; - USER_TYPE_SUPERVISED = 4; + USER_TYPE_SUPERVISED_DEPRECATED = 4; USER_TYPE_KIOSK_APP = 5; USER_TYPE_CHILD = 6; USER_TYPE_ARC_KIOSK_APP = 7;
diff --git a/components/safe_browsing/core/db/v4_database.cc b/components/safe_browsing/core/db/v4_database.cc index 8a651e3b..55d96696 100644 --- a/components/safe_browsing/core/db/v4_database.cc +++ b/components/safe_browsing/core/db/v4_database.cc
@@ -297,6 +297,15 @@ store_pair->second->HasValidData(); } +int64_t V4Database::GetStoreSizeInBytes( + const ListIdentifier& identifier) const { + const auto& store_pair = store_map_->find(identifier); + if (store_pair == store_map_->end()) { + return 0; + } + return store_pair->second->file_size(); +} + void V4Database::RecordFileSizeHistograms() { int64_t db_size = 0; for (const auto& store_map_iter : *store_map_) {
diff --git a/components/safe_browsing/core/db/v4_database.h b/components/safe_browsing/core/db/v4_database.h index 77381771..cb920eb 100644 --- a/components/safe_browsing/core/db/v4_database.h +++ b/components/safe_browsing/core/db/v4_database.h
@@ -147,6 +147,10 @@ const StoresToCheck& stores_to_check, StoreAndHashPrefixes* matched_store_and_full_hashes); + // Returns the file size of the store in bytes. Returns 0 if the store is not + // found. + virtual int64_t GetStoreSizeInBytes(const ListIdentifier& store) const; + // Resets the stores in |stores_to_reset| to an empty state. This is done if // the checksum doesn't match the expected value. void ResetStores(const std::vector<ListIdentifier>& stores_to_reset);
diff --git a/components/safe_browsing/core/db/v4_local_database_manager.cc b/components/safe_browsing/core/db/v4_local_database_manager.cc index 5212275..1d7cf5d 100644 --- a/components/safe_browsing/core/db/v4_local_database_manager.cc +++ b/components/safe_browsing/core/db/v4_local_database_manager.cc
@@ -35,6 +35,13 @@ // The expiration time of the full hash stored in the artificial database. const int64_t kFullHashExpiryTimeInMinutes = 60; +// The number of bytes in a full hash entry. +const int64_t kBytesPerFullHashEntry = 32; + +// The minimum number of entries in the allowlist. If the actual size is +// smaller than this number, the allowlist is considered as unavailable. +const int kHighConfidenceAllowlistMinimumEntryCount = 100; + const ThreatSeverity kLeastSeverity = std::numeric_limits<ThreatSeverity>::max(); @@ -418,14 +425,19 @@ bool all_stores_available = AreAllStoresAvailableNow(stores_to_check); UMA_HISTOGRAM_BOOLEAN("SafeBrowsing.RT.AllStoresAvailable", all_stores_available); - if (!enabled_ || !CanCheckUrl(url) || - (!all_stores_available && - artificially_marked_store_and_hash_prefixes_.empty())) { + bool is_artificial_prefix_empty = + artificially_marked_store_and_hash_prefixes_.empty(); + bool is_allowlist_too_small = + IsStoreTooSmall(GetUrlHighConfidenceAllowlistId(), kBytesPerFullHashEntry, + kHighConfidenceAllowlistMinimumEntryCount); + if (!enabled_ || (is_allowlist_too_small && is_artificial_prefix_empty) || + !CanCheckUrl(url) || + (!all_stores_available && is_artificial_prefix_empty)) { // NOTE(vakh): If Safe Browsing isn't enabled yet, or if the URL isn't a - // navigation URL, or if the allowlist isn't ready yet, return MATCH. - // The full URL check won't be performed, but hash-based check will still - // be done. If any artificial matches are present, consider the allowlist - // as ready. + // navigation URL, or if the allowlist isn't ready yet, or if the allowlist + // is too small, return MATCH. The full URL check won't be performed, but + // hash-based check will still be done. If any artificial matches are + // present, consider the allowlist as ready. return AsyncMatch::MATCH; } @@ -1030,6 +1042,20 @@ return (result == StoreAvailabilityResult::AVAILABLE); } +int64_t V4LocalDatabaseManager::GetStoreEntryCount(const ListIdentifier& store, + int bytes_per_entry) const { + if (!enabled_ || !v4_database_) { + return 0; + } + return v4_database_->GetStoreSizeInBytes(store) / bytes_per_entry; +} + +bool V4LocalDatabaseManager::IsStoreTooSmall(const ListIdentifier& store, + int bytes_per_entry, + int min_entry_count) const { + return GetStoreEntryCount(store, bytes_per_entry) < min_entry_count; +} + bool V4LocalDatabaseManager::AreAnyStoresAvailableNow( const StoresToCheck& stores_to_check) const { return enabled_ && v4_database_ &&
diff --git a/components/safe_browsing/core/db/v4_local_database_manager.h b/components/safe_browsing/core/db/v4_local_database_manager.h index 0a37f20b..b55897e 100644 --- a/components/safe_browsing/core/db/v4_local_database_manager.h +++ b/components/safe_browsing/core/db/v4_local_database_manager.h
@@ -329,6 +329,16 @@ // these stores. bool AreAllStoresAvailableNow(const StoresToCheck& stores_to_check) const; + // Return the number of entries in the store. If the database isn't enabled or + // the database is not found, return 0. + int64_t GetStoreEntryCount(const ListIdentifier& store, + int bytes_per_entry) const; + + // Return whether the size of the store is smaller than expected. + bool IsStoreTooSmall(const ListIdentifier& store, + int bytes_per_entry, + int min_entry_count) const; + // Return true if we're enabled and have loaded real data for any of // these stores. bool AreAnyStoresAvailableNow(const StoresToCheck& stores_to_check) const;
diff --git a/components/safe_browsing/core/db/v4_local_database_manager_unittest.cc b/components/safe_browsing/core/db/v4_local_database_manager_unittest.cc index b8d8d75a..5534f937 100644 --- a/components/safe_browsing/core/db/v4_local_database_manager_unittest.cc +++ b/components/safe_browsing/core/db/v4_local_database_manager_unittest.cc
@@ -44,6 +44,8 @@ return full_hashes[0]; } +const int kDefaultStoreFileSizeInBytes = 320000; + // Use this if you want GetFullHashes() to always return prescribed results. class FakeGetHashProtocolManager : public V4GetHashProtocolManager { public: @@ -108,7 +110,8 @@ std::unique_ptr<StoreMap> store_map, const StoreAndHashPrefixes& store_and_hash_prefixes, NewDatabaseReadyCallback new_db_callback, - bool stores_available) { + bool stores_available, + int64_t store_file_size) { // Mimics V4Database::Create const scoped_refptr<base::SingleThreadTaskRunner>& callback_task_runner = base::ThreadTaskRunnerHandle::Get(); @@ -117,7 +120,7 @@ base::BindOnce(&FakeV4Database::CreateOnTaskRunner, db_task_runner, std::move(store_map), store_and_hash_prefixes, callback_task_runner, std::move(new_db_callback), - stores_available)); + stores_available, store_file_size)); } // V4Database implementation @@ -136,6 +139,11 @@ } } + // V4Database implementation + int64_t GetStoreSizeInBytes(const ListIdentifier& store) const override { + return store_file_size_; + } + bool AreAllStoresAvailable( const StoresToCheck& stores_to_check) const override { return stores_available_; @@ -153,11 +161,12 @@ const StoreAndHashPrefixes& store_and_hash_prefixes, const scoped_refptr<base::SingleThreadTaskRunner>& callback_task_runner, NewDatabaseReadyCallback new_db_callback, - bool stores_available) { + bool stores_available, + int64_t store_file_size) { // Mimics the semantics of V4Database::CreateOnTaskRunner - std::unique_ptr<FakeV4Database> fake_v4_database( - new FakeV4Database(db_task_runner, std::move(store_map), - store_and_hash_prefixes, stores_available)); + std::unique_ptr<FakeV4Database> fake_v4_database(new FakeV4Database( + db_task_runner, std::move(store_map), store_and_hash_prefixes, + stores_available, store_file_size)); callback_task_runner->PostTask(FROM_HERE, base::BindOnce(std::move(new_db_callback), std::move(fake_v4_database))); @@ -166,13 +175,16 @@ FakeV4Database(const scoped_refptr<base::SequencedTaskRunner>& db_task_runner, std::unique_ptr<StoreMap> store_map, const StoreAndHashPrefixes& store_and_hash_prefixes, - bool stores_available) + bool stores_available, + int64_t store_file_size) : V4Database(db_task_runner, std::move(store_map)), store_and_hash_prefixes_(store_and_hash_prefixes), - stores_available_(stores_available) {} + stores_available_(stores_available), + store_file_size_(store_file_size) {} const StoreAndHashPrefixes store_and_hash_prefixes_; const bool stores_available_; + int64_t store_file_size_; }; // TODO(nparker): This might be simpler with a mock and EXPECT calls. @@ -371,8 +383,10 @@ v4_local_database_manager_->PopulateArtificialDatabase(); } - void ReplaceV4Database(const StoreAndHashPrefixes& store_and_hash_prefixes, - bool stores_available = false) { + void ReplaceV4Database( + const StoreAndHashPrefixes& store_and_hash_prefixes, + bool stores_available = false, + int64_t store_file_size = kDefaultStoreFileSizeInBytes) { // Disable the V4LocalDatabaseManager first so that if the callback to // verify checksum has been scheduled, then it doesn't do anything when it // is called back. @@ -387,9 +401,9 @@ NewDatabaseReadyCallback db_ready_callback = base::BindOnce(&V4LocalDatabaseManager::DatabaseReadyForChecks, base::Unretained(v4_local_database_manager_.get())); - FakeV4Database::Create(task_runner_, std::make_unique<StoreMap>(), - store_and_hash_prefixes, - std::move(db_ready_callback), stores_available); + FakeV4Database::Create( + task_runner_, std::make_unique<StoreMap>(), store_and_hash_prefixes, + std::move(db_ready_callback), stores_available, store_file_size); WaitForTasksOnTaskRunner(); } @@ -664,7 +678,8 @@ StoreAndHashPrefixes store_and_hash_prefixes; store_and_hash_prefixes.emplace_back(GetUrlHighConfidenceAllowlistId(), safe_hash_prefix); - ReplaceV4Database(store_and_hash_prefixes, /* stores_available= */ true); + ReplaceV4Database(store_and_hash_prefixes, /* stores_available= */ true, + /* store_file_size= */ 10000); // Setup the allowlist client to verify the callback. TestAllowlistClient client( @@ -706,7 +721,8 @@ StoreAndHashPrefixes store_and_hash_prefixes; store_and_hash_prefixes.emplace_back(GetUrlHighConfidenceAllowlistId(), safe_hash_prefix); - ReplaceV4Database(store_and_hash_prefixes, /* stores_available= */ true); + ReplaceV4Database(store_and_hash_prefixes, /* stores_available= */ true, + /* store_file_size= */ 100000); // Setup the allowlist client to verify the callback. TestAllowlistClient client( @@ -745,7 +761,8 @@ StoreAndHashPrefixes store_and_hash_prefixes; store_and_hash_prefixes.emplace_back(GetUrlHighConfidenceAllowlistId(), safe_full_hash); - ReplaceV4Database(store_and_hash_prefixes, /* stores_available= */ true); + ReplaceV4Database(store_and_hash_prefixes, /* stores_available= */ true, + /* store_file_size= */ 100000); // Setup the allowlist client to verify the callback isn't called. TestAllowlistClient client( @@ -777,7 +794,8 @@ // Add a full hash that won't match the URL we check. StoreAndHashPrefixes store_and_hash_prefixes; store_and_hash_prefixes.emplace_back(GetUrlMalwareId(), safe_full_hash); - ReplaceV4Database(store_and_hash_prefixes, /* stores_available= */ true); + ReplaceV4Database(store_and_hash_prefixes, /* stores_available= */ true, + /* store_file_size= */ 100000); // Setup the allowlist client to verify the callback isn't called. TestAllowlistClient client( @@ -804,7 +822,39 @@ // Setup local database as unavailable. StoreAndHashPrefixes store_and_hash_prefixes; - ReplaceV4Database(store_and_hash_prefixes, /* stores_available= */ false); + ReplaceV4Database(store_and_hash_prefixes, /* stores_available= */ false, + /* store_file_size= */ 100000); + + // Setup the allowlist client to verify the callback isn't called. + TestAllowlistClient client( + /* match_expected= */ false, + /* expected_sb_threat_type= */ SB_THREAT_TYPE_HIGH_CONFIDENCE_ALLOWLIST); + + const GURL url_check("https://example.com/safe"); + EXPECT_EQ(AsyncMatch::MATCH, + v4_local_database_manager_->CheckUrlForHighConfidenceAllowlist( + url_check, &client)); + + WaitForTasksOnTaskRunner(); + EXPECT_FALSE(client.callback_called()); +} + +// When allowlist is available but the size is too small, all URLS should be +// considered MATCH. +TEST_F(V4LocalDatabaseManagerTest, TestCheckUrlForHCAllowlistSmallSize) { + base::test::ScopedFeatureList feature_list; + feature_list.InitWithFeatures({safe_browsing::kRealTimeUrlLookupEnabled}, {}); + + // Setup to receive full-hash misses. We won't make URL requests. + ScopedFakeGetHashProtocolManagerFactory pin(FullHashInfos({})); + ResetLocalDatabaseManager(); + WaitForTasksOnTaskRunner(); + + // Setup the size of the allowlist to be smaller than the threshold. (10 + // entries) + StoreAndHashPrefixes store_and_hash_prefixes; + ReplaceV4Database(store_and_hash_prefixes, /* stores_available= */ true, + /* store_file_size= */ 32 * 10); // Setup the allowlist client to verify the callback isn't called. TestAllowlistClient client(
diff --git a/components/safe_browsing/core/db/v4_store.h b/components/safe_browsing/core/db/v4_store.h index 86e1f46..670d01f 100644 --- a/components/safe_browsing/core/db/v4_store.h +++ b/components/safe_browsing/core/db/v4_store.h
@@ -193,6 +193,8 @@ const base::FilePath& store_path() const { return store_path_; } + int64_t file_size() const { return file_size_; } + void ApplyUpdate(std::unique_ptr<ListUpdateResponse> response, const scoped_refptr<base::SingleThreadTaskRunner>& runner, UpdatedStoreReadyCallback callback);
diff --git a/components/safe_browsing/core/db/v4_test_util.cc b/components/safe_browsing/core/db/v4_test_util.cc index 00ec5e1..8f208b61 100644 --- a/components/safe_browsing/core/db/v4_test_util.cc +++ b/components/safe_browsing/core/db/v4_test_util.cc
@@ -20,6 +20,7 @@ const char kClient[] = "unittest"; const char kAppVer[] = "1.0"; const char kKeyParam[] = "test_key_param"; +const int kDefaultStoreFileSizeInBytes = 320000; } // namespace @@ -74,6 +75,10 @@ test_store->MarkPrefixAsBad(prefix); } +int64_t TestV4Database::GetStoreSizeInBytes(const ListIdentifier& store) const { + return kDefaultStoreFileSizeInBytes; +} + TestV4StoreFactory::TestV4StoreFactory() = default; TestV4StoreFactory::~TestV4StoreFactory() = default;
diff --git a/components/safe_browsing/core/db/v4_test_util.h b/components/safe_browsing/core/db/v4_test_util.h index d59145c..dcf025b7 100644 --- a/components/safe_browsing/core/db/v4_test_util.h +++ b/components/safe_browsing/core/db/v4_test_util.h
@@ -59,6 +59,9 @@ std::unique_ptr<StoreMap> store_map); void MarkPrefixAsBad(ListIdentifier list_id, HashPrefix prefix); + + // V4Database implementation + int64_t GetStoreSizeInBytes(const ListIdentifier& store) const override; }; class TestV4DatabaseFactory : public V4DatabaseFactory {
diff --git a/components/search_engines/template_url.cc b/components/search_engines/template_url.cc index c683c02..9ff237c 100644 --- a/components/search_engines/template_url.cc +++ b/components/search_engines/template_url.cc
@@ -1365,6 +1365,8 @@ !engine->safe_for_autoreplace(), // Prefer engines created by Play API. engine->created_from_play_api(), + // Favor prepopulated engines over other auto-generated engines. + engine->prepopulate_id() > 0, // More recently modified engines or created engines win. engine->last_modified(), engine->date_created(), // TODO(tommycli): This should be a tie-breaker than provides a total
diff --git a/components/search_engines/template_url_service.h b/components/search_engines/template_url_service.h index 8f43e43e..8c8213c 100644 --- a/components/search_engines/template_url_service.h +++ b/components/search_engines/template_url_service.h
@@ -459,7 +459,7 @@ FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, AddOmniboxExtensionKeyword); FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, ExtensionsWithSameKeywords); FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, - CheckEnginesWithSameKeywords); + KeywordConflictNonReplaceableEngines); FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, LastVisitedTimeUpdate); FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, RepairPrepopulatedSearchEngines);
diff --git a/components/signin/internal/identity_manager/primary_account_manager.cc b/components/signin/internal/identity_manager/primary_account_manager.cc index 7b95c04..5c3b9c12 100644 --- a/components/signin/internal/identity_manager/primary_account_manager.cc +++ b/components/signin/internal/identity_manager/primary_account_manager.cc
@@ -47,8 +47,6 @@ // static void PrimaryAccountManager::RegisterProfilePrefs(PrefRegistrySimple* registry) { - registry->RegisterStringPref(prefs::kGoogleServicesHostedDomain, - std::string()); registry->RegisterStringPref(prefs::kGoogleServicesLastAccountId, std::string()); registry->RegisterStringPref(prefs::kGoogleServicesLastUsername, @@ -336,7 +334,6 @@ } PrimaryAccountChangeEvent::State previous_state = GetPrimaryAccountState(); - client_->GetPrefs()->ClearPref(prefs::kGoogleServicesHostedDomain); // Revoke all tokens before sending signed_out notification, because there // may be components that don't listen for token service events when the
diff --git a/components/signin/public/base/signin_metrics.cc b/components/signin/public/base/signin_metrics.cc index adcfc19..842139c7 100644 --- a/components/signin/public/base/signin_metrics.cc +++ b/components/signin/public/base/signin_metrics.cc
@@ -893,10 +893,13 @@ base::RecordAction( base::UserMetricsAction("Signin_Impression_FromKaleidoscope")); break; + case AccessPoint::ACCESS_POINT_USER_MANAGER: + base::RecordAction( + base::UserMetricsAction("Signin_Impression_FromUserManager")); + break; case AccessPoint::ACCESS_POINT_CONTENT_AREA: case AccessPoint::ACCESS_POINT_EXTENSIONS: case AccessPoint::ACCESS_POINT_SUPERVISED_USER: - case AccessPoint::ACCESS_POINT_USER_MANAGER: case AccessPoint::ACCESS_POINT_UNKNOWN: case AccessPoint::ACCESS_POINT_MACHINE_LOGON: case AccessPoint::ACCESS_POINT_SYNC_ERROR_CARD:
diff --git a/components/signin/public/base/signin_pref_names.cc b/components/signin/public/base/signin_pref_names.cc index 3860caf..bba71b0 100644 --- a/components/signin/public/base/signin_pref_names.cc +++ b/components/signin/public/base/signin_pref_names.cc
@@ -49,10 +49,6 @@ const char kGoogleServicesConsentedToSync[] = "google.services.consented_to_sync"; -// The profile's hosted domain; empty if unset; kNoHostedDomainFound if there -// is none. -const char kGoogleServicesHostedDomain[] = "google.services.hosted_domain"; - // Similar to kGoogleServicesLastUsername, this is the corresponding version of // kGoogleServicesAccountId that is not cleared on signout. const char kGoogleServicesLastAccountId[] = "google.services.last_account_id";
diff --git a/components/signin/public/base/signin_pref_names.h b/components/signin/public/base/signin_pref_names.h index 59015f7..3230e853 100644 --- a/components/signin/public/base/signin_pref_names.h +++ b/components/signin/public/base/signin_pref_names.h
@@ -20,7 +20,6 @@ extern const char kGaiaCookiePeriodicReportTime[]; extern const char kGoogleServicesAccountId[]; extern const char kGoogleServicesConsentedToSync[]; -extern const char kGoogleServicesHostedDomain[]; extern const char kGoogleServicesLastAccountId[]; extern const char kGoogleServicesLastUsername[]; extern const char kGoogleServicesSigninScopedDeviceId[];
diff --git a/components/site_engagement/content/BUILD.gn b/components/site_engagement/content/BUILD.gn index 8e82a6d..2f3dcf24 100644 --- a/components/site_engagement/content/BUILD.gn +++ b/components/site_engagement/content/BUILD.gn
@@ -7,18 +7,42 @@ "engagement_type.h", "site_engagement_metrics.cc", "site_engagement_metrics.h", + "site_engagement_observer.cc", + "site_engagement_observer.h", "site_engagement_score.cc", "site_engagement_score.h", + "site_engagement_service.cc", + "site_engagement_service.h", ] + deps = [ "//base", + "//components/browsing_data/core", "//components/content_settings/core/browser", "//components/content_settings/core/common", + "//components/permissions", + "//components/prefs", "//components/security_state/core", + "//components/site_engagement/core", "//components/site_engagement/core/mojom:mojo_bindings", + "//components/user_prefs", "//components/variations", + "//content/public/browser", "//third_party/blink/public/mojom:mojom_platform_headers", + "//url", ] + + if (is_android) { + sources += [ + "android/site_engagement_service_android.cc", + "android/site_engagement_service_android.h", + ] + + deps += [ + "//components/embedder_support/android:browser_context", + "//components/site_engagement/content/android:jni_headers", + ] + } } source_set("unit_tests") {
diff --git a/components/site_engagement/content/DEPS b/components/site_engagement/content/DEPS index 7f2ff9e..4c2117ef 100644 --- a/components/site_engagement/content/DEPS +++ b/components/site_engagement/content/DEPS
@@ -1,5 +1,12 @@ include_rules = [ + "+components/browsing_data", "+components/content_settings/core", + "+components/keyed_service", + "+components/permissions", + "+components/prefs", + "+components/user_prefs", "+components/variations", + "+content/public/browser", "+third_party/blink/public/mojom", + "+ui/base", ]
diff --git a/components/site_engagement/content/android/BUILD.gn b/components/site_engagement/content/android/BUILD.gn new file mode 100644 index 0000000..76930b1 --- /dev/null +++ b/components/site_engagement/content/android/BUILD.gn
@@ -0,0 +1,19 @@ +# Copyright 2020 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("//build/config/android/rules.gni") + +android_library("java") { + sources = [ "java/src/org/chromium/components/site_engagement/SiteEngagementService.java" ] + deps = [ + "//base:base_java", + "//base:jni_java", + "//components/embedder_support/android:browser_context_java", + ] + annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ] +} + +generate_jni("jni_headers") { + sources = [ "java/src/org/chromium/components/site_engagement/SiteEngagementService.java" ] +}
diff --git a/components/site_engagement/content/android/DEPS b/components/site_engagement/content/android/DEPS new file mode 100644 index 0000000..735adf49 --- /dev/null +++ b/components/site_engagement/content/android/DEPS
@@ -0,0 +1,3 @@ +include_rules = [ + "+components/embedder_support/android", +]
diff --git a/chrome/browser/engagement/android/java/src/org/chromium/chrome/browser/engagement/SiteEngagementService.java b/components/site_engagement/content/android/java/src/org/chromium/components/site_engagement/SiteEngagementService.java similarity index 98% rename from chrome/browser/engagement/android/java/src/org/chromium/chrome/browser/engagement/SiteEngagementService.java rename to components/site_engagement/content/android/java/src/org/chromium/components/site_engagement/SiteEngagementService.java index b01b334..a95b87f 100644 --- a/chrome/browser/engagement/android/java/src/org/chromium/chrome/browser/engagement/SiteEngagementService.java +++ b/components/site_engagement/content/android/java/src/org/chromium/components/site_engagement/SiteEngagementService.java
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -package org.chromium.chrome.browser.engagement; +package org.chromium.components.site_engagement; import org.chromium.base.ThreadUtils; import org.chromium.base.annotations.CalledByNative;
diff --git a/chrome/browser/engagement/site_engagement_service_android.cc b/components/site_engagement/content/android/site_engagement_service_android.cc similarity index 90% rename from chrome/browser/engagement/site_engagement_service_android.cc rename to components/site_engagement/content/android/site_engagement_service_android.cc index e28b1c9..3d954ca 100644 --- a/chrome/browser/engagement/site_engagement_service_android.cc +++ b/components/site_engagement/content/android/site_engagement_service_android.cc
@@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/engagement/site_engagement_service_android.h" +#include "components/site_engagement/content/android/site_engagement_service_android.h" #include "base/android/jni_android.h" #include "base/android/jni_string.h" -#include "chrome/browser/engagement/android/jni_headers/SiteEngagementService_jni.h" -#include "chrome/browser/engagement/site_engagement_service.h" #include "components/embedder_support/android/browser_context/browser_context_handle.h" +#include "components/site_engagement/content/android/jni_headers/SiteEngagementService_jni.h" #include "components/site_engagement/content/site_engagement_score.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "url/gurl.h" namespace site_engagement {
diff --git a/chrome/browser/engagement/site_engagement_service_android.h b/components/site_engagement/content/android/site_engagement_service_android.h similarity index 86% rename from chrome/browser/engagement/site_engagement_service_android.h rename to components/site_engagement/content/android/site_engagement_service_android.h index 491ef8e7..653594e6 100644 --- a/chrome/browser/engagement/site_engagement_service_android.h +++ b/components/site_engagement/content/android/site_engagement_service_android.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_ENGAGEMENT_SITE_ENGAGEMENT_SERVICE_ANDROID_H_ -#define CHROME_BROWSER_ENGAGEMENT_SITE_ENGAGEMENT_SERVICE_ANDROID_H_ +#ifndef COMPONENTS_SITE_ENGAGEMENT_CONTENT_ANDROID_SITE_ENGAGEMENT_SERVICE_ANDROID_H_ +#define COMPONENTS_SITE_ENGAGEMENT_CONTENT_ANDROID_SITE_ENGAGEMENT_SERVICE_ANDROID_H_ #include "base/android/scoped_java_ref.h" @@ -49,4 +49,4 @@ } // namespace site_engagement -#endif // CHROME_BROWSER_ENGAGEMENT_SITE_ENGAGEMENT_SERVICE_ANDROID_H_ +#endif // COMPONENTS_SITE_ENGAGEMENT_CONTENT_ANDROID_SITE_ENGAGEMENT_SERVICE_ANDROID_H_
diff --git a/chrome/browser/engagement/site_engagement_observer.cc b/components/site_engagement/content/site_engagement_observer.cc similarity index 85% rename from chrome/browser/engagement/site_engagement_observer.cc rename to components/site_engagement/content/site_engagement_observer.cc index c8ae53e..2e2a4e6b 100644 --- a/chrome/browser/engagement/site_engagement_observer.cc +++ b/components/site_engagement/content/site_engagement_observer.cc
@@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/engagement/site_engagement_observer.h" +#include "components/site_engagement/content/site_engagement_observer.h" -#include "chrome/browser/engagement/site_engagement_service.h" +#include "components/site_engagement/content/site_engagement_service.h" namespace site_engagement {
diff --git a/chrome/browser/engagement/site_engagement_observer.h b/components/site_engagement/content/site_engagement_observer.h similarity index 88% rename from chrome/browser/engagement/site_engagement_observer.h rename to components/site_engagement/content/site_engagement_observer.h index a5ff3c44..f4a1024 100644 --- a/chrome/browser/engagement/site_engagement_observer.h +++ b/components/site_engagement/content/site_engagement_observer.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_ENGAGEMENT_SITE_ENGAGEMENT_OBSERVER_H_ -#define CHROME_BROWSER_ENGAGEMENT_SITE_ENGAGEMENT_OBSERVER_H_ +#ifndef COMPONENTS_SITE_ENGAGEMENT_CONTENT_SITE_ENGAGEMENT_OBSERVER_H_ +#define COMPONENTS_SITE_ENGAGEMENT_CONTENT_SITE_ENGAGEMENT_OBSERVER_H_ #include "base/gtest_prod_util.h" #include "base/macros.h" @@ -56,4 +56,4 @@ } // namespace site_engagement -#endif // CHROME_BROWSER_ENGAGEMENT_SITE_ENGAGEMENT_OBSERVER_H_ +#endif // COMPONENTS_SITE_ENGAGEMENT_CONTENT_SITE_ENGAGEMENT_OBSERVER_H_
diff --git a/chrome/browser/engagement/site_engagement_service.cc b/components/site_engagement/content/site_engagement_service.cc similarity index 97% rename from chrome/browser/engagement/site_engagement_service.cc rename to components/site_engagement/content/site_engagement_service.cc index e4fd43a..84b3583 100644 --- a/chrome/browser/engagement/site_engagement_service.cc +++ b/components/site_engagement/content/site_engagement_service.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/engagement/site_engagement_service.h" +#include "components/site_engagement/content/site_engagement_service.h" #include <stddef.h> @@ -18,8 +18,6 @@ #include "base/time/default_clock.h" #include "base/time/time.h" #include "base/values.h" -#include "chrome/browser/engagement/site_engagement_observer.h" -#include "chrome/common/pref_names.h" #include "components/browsing_data/core/browsing_data_utils.h" #include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/content_settings/core/common/content_settings_pattern.h" @@ -27,7 +25,9 @@ #include "components/prefs/pref_service.h" #include "components/site_engagement/content/engagement_type.h" #include "components/site_engagement/content/site_engagement_metrics.h" +#include "components/site_engagement/content/site_engagement_observer.h" #include "components/site_engagement/content/site_engagement_score.h" +#include "components/site_engagement/core/pref_names.h" #include "components/user_prefs/user_prefs.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_task_traits.h" @@ -36,7 +36,7 @@ #include "url/gurl.h" #if defined(OS_ANDROID) -#include "chrome/browser/engagement/site_engagement_service_android.h" +#include "components/site_engagement/content/android/site_engagement_service_android.h" #endif namespace site_engagement { @@ -232,8 +232,8 @@ observer.Observe(nullptr); } -blink::mojom::EngagementLevel -SiteEngagementService::GetEngagementLevel(const GURL& url) const { +blink::mojom::EngagementLevel SiteEngagementService::GetEngagementLevel( + const GURL& url) const { if (IsLastEngagementStale()) CleanupEngagementScores(true);
diff --git a/chrome/browser/engagement/site_engagement_service.h b/components/site_engagement/content/site_engagement_service.h similarity index 97% rename from chrome/browser/engagement/site_engagement_service.h rename to components/site_engagement/content/site_engagement_service.h index 143a7fb0..6dd38f34 100644 --- a/chrome/browser/engagement/site_engagement_service.h +++ b/components/site_engagement/content/site_engagement_service.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_ENGAGEMENT_SITE_ENGAGEMENT_SERVICE_H_ -#define CHROME_BROWSER_ENGAGEMENT_SITE_ENGAGEMENT_SERVICE_H_ +#ifndef COMPONENTS_SITE_ENGAGEMENT_CONTENT_SITE_ENGAGEMENT_SERVICE_H_ +#define COMPONENTS_SITE_ENGAGEMENT_CONTENT_SITE_ENGAGEMENT_SERVICE_H_ #include <memory> #include <vector> @@ -31,7 +31,7 @@ namespace content { class BrowserContext; class WebContents; -} +} // namespace content namespace web_app { class WebAppEngagementBrowserTest; @@ -348,4 +348,4 @@ } // namespace site_engagement -#endif // CHROME_BROWSER_ENGAGEMENT_SITE_ENGAGEMENT_SERVICE_H_ +#endif // COMPONENTS_SITE_ENGAGEMENT_CONTENT_SITE_ENGAGEMENT_SERVICE_H_
diff --git a/components/site_engagement/core/BUILD.gn b/components/site_engagement/core/BUILD.gn new file mode 100644 index 0000000..dbf7d35 --- /dev/null +++ b/components/site_engagement/core/BUILD.gn
@@ -0,0 +1,10 @@ +# Copyright 2020 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. + +static_library("core") { + sources = [ + "pref_names.cc", + "pref_names.h", + ] +}
diff --git a/components/site_engagement/core/pref_names.cc b/components/site_engagement/core/pref_names.cc new file mode 100644 index 0000000..3767483 --- /dev/null +++ b/components/site_engagement/core/pref_names.cc
@@ -0,0 +1,17 @@ +// Copyright 2020 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 "components/site_engagement/core/pref_names.h" + +namespace site_engagement { +namespace prefs { + +// The last time that the site engagement service recorded an engagement event +// for this profile for any URL. Recorded only during shutdown. Used to prevent +// the service from decaying engagement when a user does not use the browser at +// all for an extended period of time. +const char kSiteEngagementLastUpdateTime[] = "profile.last_engagement_time"; + +} // namespace prefs +} // namespace site_engagement
diff --git a/components/site_engagement/core/pref_names.h b/components/site_engagement/core/pref_names.h new file mode 100644 index 0000000..97a3f99 --- /dev/null +++ b/components/site_engagement/core/pref_names.h
@@ -0,0 +1,16 @@ +// Copyright 2020 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 COMPONENTS_SITE_ENGAGEMENT_CORE_PREF_NAMES_H_ +#define COMPONENTS_SITE_ENGAGEMENT_CORE_PREF_NAMES_H_ + +namespace site_engagement { +namespace prefs { + +extern const char kSiteEngagementLastUpdateTime[]; + +} // namespace prefs +} // namespace site_engagement + +#endif // COMPONENTS_SITE_ENGAGEMENT_CORE_PREF_NAMES_H_
diff --git a/components/subresource_filter/content/browser/async_document_subresource_filter.cc b/components/subresource_filter/content/browser/async_document_subresource_filter.cc index c26ed088..8bd3b367 100644 --- a/components/subresource_filter/content/browser/async_document_subresource_filter.cc +++ b/components/subresource_filter/content/browser/async_document_subresource_filter.cc
@@ -162,6 +162,20 @@ std::move(result_callback)); } +void AsyncDocumentSubresourceFilter::GetLoadPolicyForSubdocumentURLs( + const std::vector<GURL>& urls, + MultiLoadPolicyCallback result_callback) { + DCHECK(sequence_checker_.CalledOnValidSequence()); + + // TODO(pkalinnikov): Think about avoiding copying of |urls| if they are + // too big and won't be allowed anyway (e.g. data: URI). + base::PostTaskAndReplyWithResult( + task_runner_, FROM_HERE, + base::BindOnce(&AsyncDocumentSubresourceFilter::Core::GetLoadPolicies, + base::Unretained(core_.get()), urls), + std::move(result_callback)); +} + void AsyncDocumentSubresourceFilter::ReportDisallowedLoad() { if (!first_disallowed_load_callback_.is_null()) std::move(first_disallowed_load_callback_).Run(); @@ -206,6 +220,19 @@ DCHECK(sequence_checker_.CalledOnValidSequence()); } +std::vector<LoadPolicy> AsyncDocumentSubresourceFilter::Core::GetLoadPolicies( + const std::vector<GURL>& urls) { + std::vector<LoadPolicy> policies; + for (const auto& url : urls) { + auto policy = + filter() ? filter()->GetLoadPolicy( + url, url_pattern_index::proto::ELEMENT_TYPE_SUBDOCUMENT) + : LoadPolicy::ALLOW; + policies.push_back(policy); + } + return policies; +} + void AsyncDocumentSubresourceFilter::Core::SetActivationState( const mojom::ActivationState& state) { DCHECK(filter_);
diff --git a/components/subresource_filter/content/browser/async_document_subresource_filter.h b/components/subresource_filter/content/browser/async_document_subresource_filter.h index 35585c9..7580945e 100644 --- a/components/subresource_filter/content/browser/async_document_subresource_filter.h +++ b/components/subresource_filter/content/browser/async_document_subresource_filter.h
@@ -6,6 +6,8 @@ #define COMPONENTS_SUBRESOURCE_FILTER_CONTENT_BROWSER_ASYNC_DOCUMENT_SUBRESOURCE_FILTER_H_ #include <memory> +#include <string> +#include <vector> #include "base/callback.h" #include "base/macros.h" @@ -46,6 +48,8 @@ class AsyncDocumentSubresourceFilter { public: using LoadPolicyCallback = base::OnceCallback<void(LoadPolicy)>; + using MultiLoadPolicyCallback = + base::OnceCallback<void(std::vector<LoadPolicy>)>; class Core; @@ -134,6 +138,13 @@ void GetLoadPolicyForSubdocument(const GURL& subdocument_url, LoadPolicyCallback result_callback); + // Computes LoadPolicy for each URL in `urls` and returns the vector of + // policies back to the calling thread via `result_callback`. If + // MemoryMappedRuleset is not present or malformed, then + // LoadPolicy::Allow is returned for each of these URLs. + void GetLoadPolicyForSubdocumentURLs(const std::vector<GURL>& urls, + MultiLoadPolicyCallback result_callback); + // Invokes |first_disallowed_load_callback|, if necessary, and posts a task to // call DocumentSubresourceFilter::reportDisallowedCallback() on the // |task_runner|. @@ -197,6 +208,8 @@ return filter_ ? &filter_.value() : nullptr; } + std::vector<LoadPolicy> GetLoadPolicies(const std::vector<GURL>& urls); + private: friend class AsyncDocumentSubresourceFilter;
diff --git a/components/subresource_filter/content/browser/async_document_subresource_filter_unittest.cc b/components/subresource_filter/content/browser/async_document_subresource_filter_unittest.cc index abda0841..4ae2ab4 100644 --- a/components/subresource_filter/content/browser/async_document_subresource_filter_unittest.cc +++ b/components/subresource_filter/content/browser/async_document_subresource_filter_unittest.cc
@@ -62,6 +62,11 @@ } } + void RunBlockingTasks() { + if (blocking_task_runner_->HasPendingTask()) + blocking_task_runner_->RunPendingTasks(); + } + VerifiedRulesetDealer::Handle* dealer_handle() { return dealer_handle_.get(); } @@ -134,6 +139,67 @@ DISALLOW_COPY_AND_ASSIGN(LoadPolicyCallbackReceiver); }; +class MultiLoadPolicyCallbackReceiver { + public: + MultiLoadPolicyCallbackReceiver() = default; + MultiLoadPolicyCallbackReceiver( + const MultiLoadPolicyCallbackReceiver& other) = delete; + MultiLoadPolicyCallbackReceiver& operator=( + const MultiLoadPolicyCallbackReceiver& other) = delete; + ~MultiLoadPolicyCallbackReceiver() = default; + + AsyncDocumentSubresourceFilter::MultiLoadPolicyCallback GetCallback() { + return base::BindOnce(&MultiLoadPolicyCallbackReceiver::Callback, + base::Unretained(this)); + } + + int explicitly_allow_count() const { return explicitly_allow_count_; } + + int allow_count() const { return allow_count_; } + + int would_disallow_count() const { return would_disallow_count_; } + + int disallow_count() const { return disallow_count_; } + + void SetQuitClosure(base::OnceClosure quit_closure) { + DCHECK(quit_closure); + quit_closure_ = std::move(quit_closure); + } + + private: + void Callback(std::vector<LoadPolicy> policies) { + for (const auto& load_policy : policies) { + switch (load_policy) { + case LoadPolicy::EXPLICITLY_ALLOW: + explicitly_allow_count_++; + break; + case LoadPolicy::ALLOW: + allow_count_++; + break; + case LoadPolicy::WOULD_DISALLOW: + would_disallow_count_++; + break; + case LoadPolicy::DISALLOW: + disallow_count_++; + } + } + + Quit(); + } + + void Quit() { + DCHECK(!quit_closure_.is_null()); + std::move(quit_closure_).Run(); + } + + base::OnceClosure quit_closure_; + + int explicitly_allow_count_ = 0; + int allow_count_ = 0; + int would_disallow_count_ = 0; + int disallow_count_ = 0; +}; + } // namespace TEST_F(AsyncDocumentSubresourceFilterTest, ActivationStateIsReported) { @@ -237,6 +303,118 @@ load_policy_2.ExpectReceivedOnce(LoadPolicy::DISALLOW); } +TEST_F(AsyncDocumentSubresourceFilterTest, GetLoadPolicyForSubdocumentURLs) { + const struct { + mojom::ActivationLevel activation_level; + std::vector<GURL> urls; + int explicitly_allow_count; + int allow_count; + int would_disallow_count; + int disallow_count; + } kTestCases[] = {{mojom::ActivationLevel::kEnabled, + {}, + 0 /* explicitly_allow_count */, + 0 /* allow_count */, + 0 /* would_disallow_count */, + 0 /* disallow_count */}, + {mojom::ActivationLevel::kDryRun, + {}, + 0 /* explicitly_allow_count */, + 0 /* allow_count */, + 0 /* would_disallow_count */, + 0 /* disallow_count */}, + {mojom::ActivationLevel::kEnabled, + {GURL("http://alias1.com/allowed.html"), + GURL("http://alias2.com/disallowed.html")}, + 0 /* explicitly_allow_count */, + 1 /* allow_count */, + 0 /* would_disallow_count */, + 1 /* disallow_count */}, + {mojom::ActivationLevel::kDryRun, + {GURL("http://alias1.com/allowed.html"), + GURL("http://alias2.com/disallowed.html")}, + 0 /* explicitly_allow_count */, + 1 /* allow_count */, + 1 /* would_disallow_count */, + 0 /* disallow_count */}, + {mojom::ActivationLevel::kEnabled, + {GURL("http://example.alias1.com/allowed.html"), + GURL("http://example.alias2.com/allowed.html")}, + 0 /* explicitly_allow_count */, + 2 /* allow_count */, + 0 /* would_disallow_count */, + 0 /* disallow_count */}, + {mojom::ActivationLevel::kDryRun, + {GURL("http://example.alias1.com/allowed.html"), + GURL("http://example.alias2.com/allowed.html")}, + 0 /* explicitly_allow_count */, + 2 /* allow_count */, + 0 /* would_disallow_count */, + 0 /* disallow_count */}, + {mojom::ActivationLevel::kEnabled, + {GURL("http://example.alias1.com/disallowed.html"), + GURL("http://example.alias2.com/disallowed.html")}, + 0 /* explicitly_allow_count */, + 0 /* allow_count */, + 0 /* would_disallow_count */, + 2 /* disallow_count */}, + {mojom::ActivationLevel::kDryRun, + {GURL("http://example.alias1.com/disallowed.html"), + GURL("http://example.alias2.com/disallowed.html")}, + 0 /* explicitly_allow_count */, + 0 /* allow_count */, + 2 /* would_disallow_count */, + 0 /* disallow_count */}, + {mojom::ActivationLevel::kEnabled, + {GURL("http://test.alias1.com/disallowed.html"), + GURL("http://test.alias2.com/allowed.html"), + GURL("http://test.alias3.com/disallowed.html"), + GURL("http://test.alias4.com/disallowed.html")}, + 0 /* explicitly_allow_count */, + 1 /* allow_count */, + 0 /* would_disallow_count */, + 3 /* disallow_count */}, + {mojom::ActivationLevel::kDryRun, + {GURL("http://test.alias1.com/disallowed.html"), + GURL("http://test.alias2.com/allowed.html"), + GURL("http://test.alias3.com/disallowed.html"), + GURL("http://test.alias4.com/disallowed.html")}, + 0 /* explicitly_allow_count */, + 1 /* allow_count */, + 3 /* would_disallow_count */, + 0 /* disallow_count */}}; + + for (const auto& test : kTestCases) { + dealer_handle()->TryOpenAndSetRulesetFile( + ruleset().path, /*expected_checksum=*/0, base::DoNothing()); + auto ruleset_handle = CreateRulesetHandle(); + + AsyncDocumentSubresourceFilter::InitializationParams params( + GURL("http://example.com"), test.activation_level, + false /* measure_performance */); + + testing::TestActivationStateCallbackReceiver activation_state; + auto filter = std::make_unique<AsyncDocumentSubresourceFilter>( + ruleset_handle.get(), std::move(params), + activation_state.GetCallback()); + + base::RunLoop run_loop; + MultiLoadPolicyCallbackReceiver load_policy; + load_policy.SetQuitClosure(run_loop.QuitClosure()); + filter->GetLoadPolicyForSubdocumentURLs(test.urls, + load_policy.GetCallback()); + + RunBlockingTasks(); + run_loop.Run(); + + EXPECT_EQ(test.explicitly_allow_count, + load_policy.explicitly_allow_count()); + EXPECT_EQ(test.allow_count, load_policy.allow_count()); + EXPECT_EQ(test.would_disallow_count, load_policy.would_disallow_count()); + EXPECT_EQ(test.disallow_count, load_policy.disallow_count()); + } +} + TEST_F(AsyncDocumentSubresourceFilterTest, FirstDisallowedLoadIsReported) { dealer_handle()->TryOpenAndSetRulesetFile( ruleset().path, /*expected_checksum=*/0, base::DoNothing());
diff --git a/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle.cc b/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle.cc index 0e0d5fd..7bf9866b 100644 --- a/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle.cc +++ b/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle.cc
@@ -21,14 +21,54 @@ #include "content/public/browser/web_contents.h" #include "third_party/blink/public/mojom/devtools/console_message.mojom.h" +namespace features { + +// Enables or disables performing SubresourceFilter checks from the Browser +// against any aliases for the requested URL found from DNS CNAME records. +const base::Feature kSendCnameAliasesToSubresourceFilterFromBrowser{ + "SendCnameAliasesToSubresourceFilterFromBrowser", + base::FEATURE_DISABLED_BY_DEFAULT}; + +} // namespace features + namespace subresource_filter { +namespace { + +void LogCnameAliasMetrics(const CnameAliasMetricInfo& info) { + bool has_aliases = info.list_length > 0; + + UMA_HISTOGRAM_BOOLEAN("SubresourceFilter.CnameAlias.Browser.HadAliases", + has_aliases); + + if (has_aliases) { + UMA_HISTOGRAM_COUNTS_1000("SubresourceFilter.CnameAlias.Browser.ListLength", + info.list_length); + UMA_HISTOGRAM_COUNTS_1000( + "SubresourceFilter.CnameAlias.Browser.WasAdTaggedBasedOnAliasCount", + info.was_ad_tagged_based_on_alias_count); + UMA_HISTOGRAM_COUNTS_1000( + "SubresourceFilter.CnameAlias.Browser.WasBlockedBasedOnAliasCount", + info.was_blocked_based_on_alias_count); + UMA_HISTOGRAM_COUNTS_1000( + "SubresourceFilter.CnameAlias.Browser.InvalidCount", + info.invalid_count); + UMA_HISTOGRAM_COUNTS_1000( + "SubresourceFilter.CnameAlias.Browser.RedundantCount", + info.redundant_count); + } +} + +} // namespace + SubframeNavigationFilteringThrottle::SubframeNavigationFilteringThrottle( content::NavigationHandle* handle, AsyncDocumentSubresourceFilter* parent_frame_filter, Delegate* delegate) : content::NavigationThrottle(handle), parent_frame_filter_(parent_frame_filter), + alias_check_enabled_(base::FeatureList::IsEnabled( + ::features::kSendCnameAliasesToSubresourceFilterFromBrowser)), delegate_(delegate) { DCHECK(!handle->IsInMainFrame()); DCHECK(parent_frame_filter_); @@ -57,6 +97,9 @@ base::TimeDelta::FromSeconds(10), 50); break; } + + if (alias_check_enabled_) + LogCnameAliasMetrics(alias_info_); } content::NavigationThrottle::ThrottleCheckResult @@ -73,13 +116,48 @@ SubframeNavigationFilteringThrottle::WillProcessResponse() { DCHECK_NE(load_policy_, LoadPolicy::DISALLOW); - // Load policy notifications should go out by WillProcessResponse, - // defer if we are still performing any ruleset checks. If we are here, - // and there are outstanding load policy calculations, we are in dry run - // mode. + if (alias_check_enabled_) { + alias_info_.list_length = navigation_handle()->GetDnsAliases().size(); + + std::vector<GURL> alias_urls; + const GURL& base_url = navigation_handle()->GetURL(); + + for (const auto& alias : navigation_handle()->GetDnsAliases()) { + if (alias == navigation_handle()->GetURL().host_piece()) { + alias_info_.redundant_count++; + continue; + } + + GURL::Replacements replacements; + replacements.SetHostStr(alias); + GURL alias_url = base_url.ReplaceComponents(replacements); + + if (!alias_url.is_valid()) { + alias_info_.invalid_count++; + continue; + } + + alias_urls.push_back(alias_url); + } + + if (!alias_urls.empty()) { + pending_load_policy_calculations_++; + parent_frame_filter_->GetLoadPolicyForSubdocumentURLs( + alias_urls, base::BindOnce(&SubframeNavigationFilteringThrottle:: + OnCalculatedLoadPoliciesFromAliasUrls, + weak_ptr_factory_.GetWeakPtr())); + } + } + + // Load policy notifications should go out by WillProcessResponse, unless + // we received CNAME aliases in the response and alias checking is enabled. + // Defer if we are still performing any ruleset checks. If we are here, + // and there are outstanding load policy calculations, we are either in dry + // run mode or checking aliases. if (pending_load_policy_calculations_ > 0) { - DCHECK((parent_frame_filter_->activation_state().activation_level == - mojom::ActivationLevel::kDryRun)); + DCHECK(parent_frame_filter_->activation_state().activation_level == + mojom::ActivationLevel::kDryRun || + alias_info_.list_length > 0); DeferStart(DeferStage::kWillProcessResponse); return DEFER; } @@ -144,45 +222,43 @@ if (defer_stage_ == DeferStage::kNotDeferring) return; - // When we are deferred, callback is not responsible for handling navigation - // if there are still outstanding load policy calculations. - if (pending_load_policy_calculations_ > 0) { - // We defer waiting for each load policy calculations when the embedder - // document has activation enabled. - DCHECK(parent_frame_filter_->activation_state().activation_level != - mojom::ActivationLevel::kEnabled); - return; - } - - // If we are deferred and there are no pending load policy calculations, - // handle the deferred navigation. DCHECK(defer_stage_ == DeferStage::kWillProcessResponse || defer_stage_ == DeferStage::kWillStartOrRedirectRequest); - DCHECK(!last_defer_timestamp_.is_null()); - bool deferring_response = defer_stage_ == DeferStage::kWillProcessResponse; - total_defer_time_ += base::TimeTicks::Now() - last_defer_timestamp_; - defer_stage_ = DeferStage::kNotDeferring; - if (deferring_response) { - NotifyLoadPolicy(); - Resume(); + + // If we have an activation enabled and `load_policy_` is DISALLOW, we need + // to cancel the navigation. + if (parent_frame_filter_->activation_state().activation_level == + mojom::ActivationLevel::kEnabled && + load_policy_ == LoadPolicy::DISALLOW) { + CancelNavigation(); return; } - // Otherwise, we deferred at start/redirect time. Either cancel navigation - // or resume here according to load policy. - if (load_policy_ == LoadPolicy::DISALLOW) { - HandleDisallowedLoad(); - - // Because the navigation will be canceled, this is the last LoadPolicy that - // will be calculated. - NotifyLoadPolicy(); - CancelDeferredNavigation(BLOCK_REQUEST_AND_COLLAPSE); + // If there are still pending load calculations, then don't resume. + if (pending_load_policy_calculations_ > 0) return; + + ResumeNavigation(); +} + +void SubframeNavigationFilteringThrottle::OnCalculatedLoadPoliciesFromAliasUrls( + std::vector<LoadPolicy> policies) { + // We deferred to check aliases in WillProcessResponse. + DCHECK(defer_stage_ == DeferStage::kWillProcessResponse); + DCHECK(!policies.empty()); + + LoadPolicy most_restricive_alias_policy = LoadPolicy::EXPLICITLY_ALLOW; + + for (LoadPolicy policy : policies) { + most_restricive_alias_policy = + MoreRestrictiveLoadPolicy(most_restricive_alias_policy, policy); + if (policy == LoadPolicy::WOULD_DISALLOW) + alias_info_.was_ad_tagged_based_on_alias_count++; + else if (policy == LoadPolicy::DISALLOW) + alias_info_.was_blocked_based_on_alias_count++; } - // We will calculate another LoadPolicy for this navigation, so do not notify - // the manager yet. - Resume(); + OnCalculatedLoadPolicy(most_restricive_alias_policy); } void SubframeNavigationFilteringThrottle::DeferStart(DeferStage stage) { @@ -213,4 +289,40 @@ navigation_handle(), load_policy_, is_ad_subframe); } +void SubframeNavigationFilteringThrottle::UpdateDeferInfo() { + DCHECK(defer_stage_ != DeferStage::kNotDeferring); + DCHECK(!last_defer_timestamp_.is_null()); + total_defer_time_ += base::TimeTicks::Now() - last_defer_timestamp_; + defer_stage_ = DeferStage::kNotDeferring; +} + +void SubframeNavigationFilteringThrottle::CancelNavigation() { + bool defer_stage_was_will_process_response = + defer_stage_ == DeferStage::kWillProcessResponse; + + UpdateDeferInfo(); + HandleDisallowedLoad(); + NotifyLoadPolicy(); + + if (defer_stage_was_will_process_response) + CancelDeferredNavigation(CANCEL); + else + CancelDeferredNavigation(BLOCK_REQUEST_AND_COLLAPSE); +} + +void SubframeNavigationFilteringThrottle::ResumeNavigation() { + // There are no more pending load calculations. We can toggle back to not + // being deferred. + bool defer_stage_was_will_process_response = + defer_stage_ == DeferStage::kWillProcessResponse; + UpdateDeferInfo(); + + // If the defer stage was WillProcessResponse, then this is the last + // LoadPolicy that we will calculate. + if (defer_stage_was_will_process_response) + NotifyLoadPolicy(); + + Resume(); +} + } // namespace subresource_filter
diff --git a/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle.h b/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle.h index 94e2f7b..77abfff 100644 --- a/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle.h +++ b/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle.h
@@ -5,6 +5,7 @@ #ifndef COMPONENTS_SUBRESOURCE_FILTER_CONTENT_BROWSER_SUBFRAME_NAVIGATION_FILTERING_THROTTLE_H_ #define COMPONENTS_SUBRESOURCE_FILTER_CONTENT_BROWSER_SUBFRAME_NAVIGATION_FILTERING_THROTTLE_H_ +#include "base/feature_list.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/time/time.h" @@ -12,6 +13,10 @@ #include "components/subresource_filter/core/common/load_policy.h" #include "content/public/browser/navigation_throttle.h" +namespace features { +extern const base::Feature kSendCnameAliasesToSubresourceFilterFromBrowser; +} // namespace features + namespace content { class NavigationHandle; class RenderFrameHost; @@ -21,6 +26,16 @@ class AsyncDocumentSubresourceFilter; +// Struct for keeping variables used in recording CNAME alias metrics bundled +// together. +struct CnameAliasMetricInfo { + int list_length = 0; + int was_ad_tagged_based_on_alias_count = 0; + int was_blocked_based_on_alias_count = 0; + int invalid_count = 0; + int redundant_count = 0; +}; + // NavigationThrottle responsible for filtering subframe document loads, which // are considered subresource loads of their parent frame, hence are subject to // subresource filtering using the parent frame's @@ -77,11 +92,16 @@ MaybeDeferToCalculateLoadPolicy(); void OnCalculatedLoadPolicy(LoadPolicy policy); + void OnCalculatedLoadPoliciesFromAliasUrls(std::vector<LoadPolicy> policies); void HandleDisallowedLoad(); void NotifyLoadPolicy() const; void DeferStart(DeferStage stage); + void UpdateDeferInfo(); + + void CancelNavigation(); + void ResumeNavigation(); // Must outlive this class. AsyncDocumentSubresourceFilter* parent_frame_filter_; @@ -91,6 +111,9 @@ base::TimeTicks last_defer_timestamp_; base::TimeDelta total_defer_time_; + const bool alias_check_enabled_; + CnameAliasMetricInfo alias_info_; + // Set to the least restrictive load policy by default. LoadPolicy load_policy_ = LoadPolicy::EXPLICITLY_ALLOW;
diff --git a/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle_unittest.cc b/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle_unittest.cc index 686aa9d..5b9f768 100644 --- a/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle_unittest.cc +++ b/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle_unittest.cc
@@ -13,6 +13,7 @@ #include "base/run_loop.h" #include "base/strings/stringprintf.h" #include "base/test/metrics/histogram_tester.h" +#include "base/test/scoped_feature_list.h" #include "base/threading/thread_task_runner_handle.h" #include "components/subresource_filter/content/browser/async_document_subresource_filter.h" #include "components/subresource_filter/content/browser/async_document_subresource_filter_test_utils.h" @@ -31,6 +32,19 @@ namespace subresource_filter { +const char kCnameAliasHadAliasesHistogram[] = + "SubresourceFilter.CnameAlias.Browser.HadAliases"; +const char kCnameAliasIsInvalidCountHistogram[] = + "SubresourceFilter.CnameAlias.Browser.InvalidCount"; +const char kCnameAliasIsRedundantCountHistogram[] = + "SubresourceFilter.CnameAlias.Browser.RedundantCount"; +const char kCnameAliasListLengthHistogram[] = + "SubresourceFilter.CnameAlias.Browser.ListLength"; +const char kCnameAliasWasAdTaggedCountHistogram[] = + "SubresourceFilter.CnameAlias.Browser.WasAdTaggedBasedOnAliasCount"; +const char kCnameAliasWasBlockedCountHistogram[] = + "SubresourceFilter.CnameAlias.Browser.WasBlockedBasedOnAliasCount"; + class MockDelegate : public SubframeNavigationFilteringThrottle::Delegate { public: MockDelegate() = default; @@ -91,6 +105,51 @@ test_ruleset_creator_.CreateRulesetToDisallowURLsWithPathSuffix( "disallowed.html", &test_ruleset_pair_)); + FinishInitializingDocumentSubresourceFilter(document_url, parent_level); + } + + void InitializeDocumentSubresourceFilterWithSubstringRules( + const GURL& document_url, + std::vector<base::StringPiece> urls_to_block, + mojom::ActivationLevel parent_level = mojom::ActivationLevel::kEnabled) { + ASSERT_NO_FATAL_FAILURE( + test_ruleset_creator_.CreateRulesetToDisallowURLWithSubstrings( + urls_to_block, &test_ruleset_pair_)); + + FinishInitializingDocumentSubresourceFilter(document_url, parent_level); + } + + void RunUntilIdle() { base::RunLoop().RunUntilIdle(); } + + void CreateTestSubframeAndInitNavigation(const GURL& first_url, + content::RenderFrameHost* parent) { + content::RenderFrameHost* render_frame = + content::RenderFrameHostTester::For(parent)->AppendChild( + base::StringPrintf("subframe-%s", first_url.spec().c_str())); + navigation_simulator_ = + content::NavigationSimulator::CreateRendererInitiated(first_url, + render_frame); + } + + const std::vector<std::string>& GetConsoleMessages() { + return content::RenderFrameHostTester::For(main_rfh()) + ->GetConsoleMessages(); + } + + std::string GetFilterConsoleMessage(const GURL& filtered_url) { + return base::StringPrintf(kDisallowSubframeConsoleMessageFormat, + filtered_url.possibly_invalid_spec().c_str()); + } + + void SetResponseDnsAliasesForNavigation(std::vector<std::string> aliases) { + DCHECK(navigation_simulator_); + navigation_simulator_->SetResponseDnsAliases(std::move(aliases)); + } + + private: + void FinishInitializingDocumentSubresourceFilter( + const GURL& document_url, + mojom::ActivationLevel parent_level) { // Make the blocking task runner run on the current task runner for the // tests, to ensure that the NavigationSimulator properly runs all necessary // tasks while waiting for throttle checks to finish. @@ -116,29 +175,6 @@ activation_state.ExpectReceivedOnce(parent_activation_state); } - void RunUntilIdle() { base::RunLoop().RunUntilIdle(); } - - void CreateTestSubframeAndInitNavigation(const GURL& first_url, - content::RenderFrameHost* parent) { - content::RenderFrameHost* render_frame = - content::RenderFrameHostTester::For(parent)->AppendChild( - base::StringPrintf("subframe-%s", first_url.spec().c_str())); - navigation_simulator_ = - content::NavigationSimulator::CreateRendererInitiated(first_url, - render_frame); - } - - const std::vector<std::string>& GetConsoleMessages() { - return content::RenderFrameHostTester::For(main_rfh()) - ->GetConsoleMessages(); - } - - std::string GetFilterConsoleMessage(const GURL& filtered_url) { - return base::StringPrintf(kDisallowSubframeConsoleMessageFormat, - filtered_url.possibly_invalid_spec().c_str()); - } - - private: testing::TestRulesetCreator test_ruleset_creator_; testing::TestRulesetPair test_ruleset_pair_; @@ -326,4 +362,116 @@ histogram_tester.ExpectTotalCount(kFilterDelayAllowed, 1); } +class SubframeNavigationFilteringThrottleDnsAliasTest + : public SubframeNavigationFilteringThrottleTest { + public: + SubframeNavigationFilteringThrottleDnsAliasTest() { + feature_list_.InitAndEnableFeature( + ::features::kSendCnameAliasesToSubresourceFilterFromBrowser); + } + + ~SubframeNavigationFilteringThrottleDnsAliasTest() override = default; + + void ExpectHistogramsMatching(CnameAliasMetricInfo info) { + bool has_aliases = info.list_length > 0; + histogram_tester_.ExpectUniqueSample(kCnameAliasHadAliasesHistogram, + has_aliases, 1); + + if (has_aliases) { + histogram_tester_.ExpectUniqueSample(kCnameAliasListLengthHistogram, + info.list_length, 1); + histogram_tester_.ExpectUniqueSample( + kCnameAliasWasAdTaggedCountHistogram, + info.was_ad_tagged_based_on_alias_count, 1); + histogram_tester_.ExpectUniqueSample( + kCnameAliasWasBlockedCountHistogram, + info.was_blocked_based_on_alias_count, 1); + histogram_tester_.ExpectUniqueSample(kCnameAliasIsInvalidCountHistogram, + info.invalid_count, 1); + histogram_tester_.ExpectUniqueSample(kCnameAliasIsRedundantCountHistogram, + info.redundant_count, 1); + } + } + + private: + base::test::ScopedFeatureList feature_list_; + base::HistogramTester histogram_tester_; +}; + +TEST_F(SubframeNavigationFilteringThrottleDnsAliasTest, + FilterOnWillProcessResponse) { + InitializeDocumentSubresourceFilterWithSubstringRules( + GURL("https://example.test"), {"disallowed.com", ".bad-ad/some"}); + + const GURL url("https://example.test/some_path.html"); + CreateTestSubframeAndInitNavigation(url, main_rfh()); + + std::vector<std::string> dns_aliases({"alias1.com", "/", "example.test", "", + "disallowed.com", "allowed.com", + "test.bad-ad"}); + SetResponseDnsAliasesForNavigation(std::move(dns_aliases)); + + EXPECT_EQ(content::NavigationThrottle::CANCEL, + SimulateCommitAndGetResult(navigation_simulator())); + EXPECT_TRUE( + base::Contains(GetConsoleMessages(), GetFilterConsoleMessage(url))); + + CnameAliasMetricInfo info = {.list_length = 7, + .was_ad_tagged_based_on_alias_count = 0, + .was_blocked_based_on_alias_count = 2, + .invalid_count = 2, + .redundant_count = 1}; + + ExpectHistogramsMatching(info); +} + +TEST_F(SubframeNavigationFilteringThrottleDnsAliasTest, + DryRunOnWillProcessResponse) { + InitializeDocumentSubresourceFilterWithSubstringRules( + GURL("https://example.test"), {"disallowed.com", "bad", "blocked"}, + mojom::ActivationLevel::kDryRun); + + const GURL url("https://example.test/some_path.html"); + CreateTestSubframeAndInitNavigation(url, main_rfh()); + + std::vector<std::string> dns_aliases({"alias1.com", "", "test.disallowed.com", + "allowed.com", "blocked.com", + "bad.org"}); + SetResponseDnsAliasesForNavigation(std::move(dns_aliases)); + + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateCommitAndGetResult(navigation_simulator())); + EXPECT_FALSE( + base::Contains(GetConsoleMessages(), GetFilterConsoleMessage(url))); + + CnameAliasMetricInfo info = {.list_length = 6, + .was_ad_tagged_based_on_alias_count = 3, + .was_blocked_based_on_alias_count = 0, + .invalid_count = 1, + .redundant_count = 0}; + + ExpectHistogramsMatching(info); +} + +TEST_F(SubframeNavigationFilteringThrottleDnsAliasTest, EnabledNoAliases) { + InitializeDocumentSubresourceFilterWithSubstringRules( + GURL("https://example.test"), {"disallowed.com"}, + mojom::ActivationLevel::kEnabled); + + const GURL url("https://example.test/some_path.html"); + CreateTestSubframeAndInitNavigation(url, main_rfh()); + + std::vector<std::string> dns_aliases; + SetResponseDnsAliasesForNavigation(std::move(dns_aliases)); + + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateCommitAndGetResult(navigation_simulator())); + EXPECT_FALSE( + base::Contains(GetConsoleMessages(), GetFilterConsoleMessage(url))); + + CnameAliasMetricInfo info; + + ExpectHistogramsMatching(info); +} + } // namespace subresource_filter
diff --git a/components/subresource_filter/core/common/test_ruleset_creator.cc b/components/subresource_filter/core/common/test_ruleset_creator.cc index 9fab0093..1fef23f 100644 --- a/components/subresource_filter/core/common/test_ruleset_creator.cc +++ b/components/subresource_filter/core/common/test_ruleset_creator.cc
@@ -136,6 +136,16 @@ CreateUnindexedRulesetWithRules({suffix_rule}, test_unindexed_ruleset)); } +void TestRulesetCreator::CreateRulesetToDisallowURLWithSubstrings( + std::vector<base::StringPiece> substrings, + TestRulesetPair* test_ruleset_pair) { + DCHECK(test_ruleset_pair); + std::vector<proto::UrlRule> url_rules; + for (const auto& substring : substrings) + url_rules.push_back(CreateSubstringRule(substring)); + CreateRulesetWithRules(url_rules, test_ruleset_pair); +} + void TestRulesetCreator::CreateRulesetToDisallowURLsWithManySuffixes( base::StringPiece suffix, int num_of_suffixes,
diff --git a/components/subresource_filter/core/common/test_ruleset_creator.h b/components/subresource_filter/core/common/test_ruleset_creator.h index 8cc493e..23f59db 100644 --- a/components/subresource_filter/core/common/test_ruleset_creator.h +++ b/components/subresource_filter/core/common/test_ruleset_creator.h
@@ -77,6 +77,14 @@ base::StringPiece suffix, TestRuleset* test_unindexed_ruleset); + // Creates both the indexed and unindexed versions of a testing ruleset that + // consists of filtering rules that disallow subresource loads from URLs + // containing any of the given `substrings`. Enclose call in + // ASSERT_NO_FATAL_FAILURE to detect errors. + void CreateRulesetToDisallowURLWithSubstrings( + std::vector<base::StringPiece> substrings, + TestRulesetPair* test_ruleset_pair); + // Similar to CreateRulesetToDisallowURLsWithPathSuffix, but the resulting // ruleset consists of |num_of_suffixes| rules, each of them disallowing URLs // with suffixes of the form |suffix|_k, 0 <= k < |num_of_suffixes|.
diff --git a/components/subresource_filter/core/common/test_ruleset_utils.cc b/components/subresource_filter/core/common/test_ruleset_utils.cc index 8e2c2b7c..ddf32f0 100644 --- a/components/subresource_filter/core/common/test_ruleset_utils.cc +++ b/components/subresource_filter/core/common/test_ruleset_utils.cc
@@ -11,6 +11,20 @@ namespace proto = url_pattern_index::proto; +proto::UrlRule CreateSubstringRule(base::StringPiece substring) { + proto::UrlRule rule; + + rule.set_semantics(proto::RULE_SEMANTICS_BLACKLIST); + rule.set_source_type(proto::SOURCE_TYPE_ANY); + rule.set_element_types(proto::ELEMENT_TYPE_ALL); + rule.set_url_pattern_type(proto::URL_PATTERN_TYPE_SUBSTRING); + rule.set_anchor_left(proto::ANCHOR_TYPE_NONE); + rule.set_anchor_right(proto::ANCHOR_TYPE_NONE); + rule.set_url_pattern(substring.as_string()); + + return rule; +} + proto::UrlRule CreateSuffixRule(base::StringPiece suffix) { proto::UrlRule rule; rule.set_semantics(proto::RULE_SEMANTICS_BLACKLIST);
diff --git a/components/subresource_filter/core/common/test_ruleset_utils.h b/components/subresource_filter/core/common/test_ruleset_utils.h index 00349fa..2fbfc96 100644 --- a/components/subresource_filter/core/common/test_ruleset_utils.h +++ b/components/subresource_filter/core/common/test_ruleset_utils.h
@@ -15,6 +15,11 @@ namespace subresource_filter { namespace testing { +// Creates a blocklisted URL rule which targets subresources of any type with +// a URL containing the given `substring`. +url_pattern_index::proto::UrlRule CreateSubstringRule( + base::StringPiece substring); + // Creates a blocklisted URL rule which targets subresources of any type such // that the resource URL ends with |suffix|. url_pattern_index::proto::UrlRule CreateSuffixRule(base::StringPiece suffix);
diff --git a/components/user_manager/fake_user_manager.cc b/components/user_manager/fake_user_manager.cc index 64177bc8..d77d9c56 100644 --- a/components/user_manager/fake_user_manager.cc +++ b/components/user_manager/fake_user_manager.cc
@@ -380,7 +380,8 @@ return account_id == StubAccountId(); } -bool FakeUserManager::IsSupervisedAccountId(const AccountId& account_id) const { +bool FakeUserManager::IsDeprecatedSupervisedAccountId( + const AccountId& account_id) const { return false; }
diff --git a/components/user_manager/fake_user_manager.h b/components/user_manager/fake_user_manager.h index 974e584..adcd40e 100644 --- a/components/user_manager/fake_user_manager.h +++ b/components/user_manager/fake_user_manager.h
@@ -123,7 +123,8 @@ const std::string& gaia_id, AccountId* out_account_id) const override; void AsyncRemoveCryptohome(const AccountId& account_id) const override; - bool IsSupervisedAccountId(const AccountId& account_id) const override; + bool IsDeprecatedSupervisedAccountId( + const AccountId& account_id) const override; const gfx::ImageSkia& GetResourceImagekiaNamed(int id) const override; base::string16 GetResourceStringUTF16(int string_id) const override; void ScheduleResolveLocale(const std::string& locale,
diff --git a/components/user_manager/user.cc b/components/user_manager/user.cc index b6d9d68..22164827 100644 --- a/components/user_manager/user.cc +++ b/components/user_manager/user.cc
@@ -209,10 +209,9 @@ return GetType() == user_manager::USER_TYPE_ACTIVE_DIRECTORY; } -bool User::IsSupervised() const { +bool User::IsChildOrDeprecatedSupervised() const { UserType type = GetType(); - return type == USER_TYPE_SUPERVISED || - type == USER_TYPE_CHILD; + return type == USER_TYPE_SUPERVISED_DEPRECATED || type == USER_TYPE_CHILD; } bool User::IsChild() const { @@ -263,7 +262,7 @@ return true; case user_manager::USER_TYPE_GUEST: case user_manager::USER_TYPE_PUBLIC_ACCOUNT: - case user_manager::USER_TYPE_SUPERVISED: + case user_manager::USER_TYPE_SUPERVISED_DEPRECATED: case user_manager::USER_TYPE_KIOSK_APP: case user_manager::USER_TYPE_ARC_KIOSK_APP: case user_manager::USER_TYPE_ACTIVE_DIRECTORY: @@ -507,7 +506,7 @@ } UserType SupervisedUser::GetType() const { - return user_manager::USER_TYPE_SUPERVISED; + return user_manager::USER_TYPE_SUPERVISED_DEPRECATED; } std::string SupervisedUser::display_email() const {
diff --git a/components/user_manager/user.h b/components/user_manager/user.h index 7b4e6c0..82c4d5f 100644 --- a/components/user_manager/user.h +++ b/components/user_manager/user.h
@@ -99,8 +99,9 @@ // Returns true if it's Active Directory user. virtual bool IsActiveDirectoryUser() const; - // Returns true if user is supervised. - virtual bool IsSupervised() const; + // Returns true if user is child or deprecated legacy supervised. + // TODO(crbug/1155729): Remove and replace with IsChild(). + virtual bool IsChildOrDeprecatedSupervised() const; // Returns true if user is child. virtual bool IsChild() const;
diff --git a/components/user_manager/user_manager.cc b/components/user_manager/user_manager.cc index caa9a29..f1384c989 100644 --- a/components/user_manager/user_manager.cc +++ b/components/user_manager/user_manager.cc
@@ -129,8 +129,8 @@ if (is_child) return USER_TYPE_CHILD; - if (IsSupervisedAccountId(account_id)) - return USER_TYPE_SUPERVISED; + if (IsDeprecatedSupervisedAccountId(account_id)) + return USER_TYPE_SUPERVISED_DEPRECATED; if (account_id.GetAccountType() == AccountType::ACTIVE_DIRECTORY) return USER_TYPE_ACTIVE_DIRECTORY;
diff --git a/components/user_manager/user_manager.h b/components/user_manager/user_manager.h index 2e1e434..82a9bbf 100644 --- a/components/user_manager/user_manager.h +++ b/components/user_manager/user_manager.h
@@ -327,7 +327,7 @@ // Returns true if |user| is allowed depending on device policies. // Accepted user types: USER_TYPE_REGULAR, USER_TYPE_GUEST, - // USER_TYPE_SUPERVISED, USER_TYPE_CHILD. + // USER_TYPE_SUPERVISED_DEPRECATED, USER_TYPE_CHILD. virtual bool IsUserAllowed(const User& user) const = 0; // Returns "Local State" PrefService instance. @@ -355,9 +355,10 @@ // Returns true if |account_id| is Stub user. virtual bool IsStubAccountId(const AccountId& account_id) const = 0; - // Returns true if |account_id| is supervised. - // TODO(crbug.com/866790): Check it is not used anymore and remove it. - virtual bool IsSupervisedAccountId(const AccountId& account_id) const = 0; + // Returns true if |account_id| is deprecated supervised. + // TODO(crbug.com/1155729): Check it is not used anymore and remove it. + virtual bool IsDeprecatedSupervisedAccountId( + const AccountId& account_id) const = 0; virtual bool IsDeviceLocalAccountMarkedForRemoval( const AccountId& account_id) const = 0;
diff --git a/components/user_manager/user_manager_base.cc b/components/user_manager/user_manager_base.cc index 71feab5..87e59b2f 100644 --- a/components/user_manager/user_manager_base.cc +++ b/components/user_manager/user_manager_base.cc
@@ -64,8 +64,8 @@ // session restore. const char kLastActiveUser[] = "LastActiveUser"; -// Histogram for tracking the number of legacy supervised user cryptohomes -// remaining in the wild. +// Histogram for tracking the number of deprecated legacy supervised user +// cryptohomes remaining in the wild. const char kHideLegacySupervisedUserHistogramName[] = "ChromeOS.LegacySupervisedUsers.HiddenFromLoginScreen"; @@ -200,7 +200,7 @@ user ? user : User::CreatePublicAccountUser(account_id)); break; - case USER_TYPE_SUPERVISED: + case USER_TYPE_SUPERVISED_DEPRECATED: NOTREACHED() << "Supervised users are not supported anymore"; break; @@ -812,7 +812,7 @@ ®ular_users_set); for (std::vector<AccountId>::const_iterator it = regular_users.begin(); it != regular_users.end(); ++it) { - if (IsSupervisedAccountId(*it)) { + if (IsDeprecatedSupervisedAccountId(*it)) { base::UmaHistogramBoolean(kHideLegacySupervisedUserHistogramName, true); continue; }
diff --git a/components/user_manager/user_type.h b/components/user_manager/user_type.h index 85afb8b..ac1677a 100644 --- a/components/user_manager/user_type.h +++ b/components/user_manager/user_type.h
@@ -33,7 +33,7 @@ // Legacy supervised user, being deprecated. Logs in only with local // authentication. No Gaia account. Never ephemeral. Could have a sync token // to fetch some basic account info. - USER_TYPE_SUPERVISED = 4, + USER_TYPE_SUPERVISED_DEPRECATED = 4, // Kiosk users used to launch application in a single app mode. Logs in // without authentications. No Gaia user account. Uses device robot account.
diff --git a/components/viz/service/display/direct_renderer.cc b/components/viz/service/display/direct_renderer.cc index e4196d75..29a73e7 100644 --- a/components/viz/service/display/direct_renderer.cc +++ b/components/viz/service/display/direct_renderer.cc
@@ -26,6 +26,7 @@ #include "components/viz/common/quads/aggregated_render_pass_draw_quad.h" #include "components/viz/common/quads/compositor_render_pass_draw_quad.h" #include "components/viz/common/quads/draw_quad.h" +#include "components/viz/common/quads/solid_color_draw_quad.h" #include "components/viz/service/display/bsp_tree.h" #include "components/viz/service/display/bsp_walk_action.h" #include "components/viz/service/display/output_surface.h" @@ -688,6 +689,16 @@ SetScissorStateForQuad(quad, render_pass_scissor_in_draw_space, render_pass_requires_scissor); + if (OverlayCandidate::RequiresOverlay(&quad)) { + // We cannot composite this quad properly, replace it with solid black. + SolidColorDrawQuad solid_black; + solid_black.SetAll(quad.shared_quad_state, quad.rect, quad.rect, + /*needs_blending=*/false, SK_ColorBLACK, + /*force_anti_aliasing_off=*/true); + DoDrawQuad(&solid_black, nullptr); + continue; + } + DoDrawQuad(&quad, nullptr); } FlushPolygons(&poly_list, render_pass_scissor_in_draw_space,
diff --git a/components/viz/service/display/overlay_candidate.cc b/components/viz/service/display/overlay_candidate.cc index 8f2a987..a282da4 100644 --- a/components/viz/service/display/overlay_candidate.cc +++ b/components/viz/service/display/overlay_candidate.cc
@@ -305,6 +305,8 @@ OverlayCandidate* candidate) { if (!resource_provider->IsOverlayCandidate(resource_id)) return false; + if (quad->visible_rect.IsEmpty()) + return false; candidate->format = resource_provider->GetBufferFormat(resource_id); candidate->color_space = resource_provider->GetColorSpace(resource_id);
diff --git a/components/viz/service/display/overlay_processor_using_strategy.cc b/components/viz/service/display/overlay_processor_using_strategy.cc index 6f12bf7c..1c0080a 100644 --- a/components/viz/service/display/overlay_processor_using_strategy.cc +++ b/components/viz/service/display/overlay_processor_using_strategy.cc
@@ -326,9 +326,9 @@ // DRM/CDM HW overlay required: // This comparison is for correctness over performance reasons. Some // candidates must be an HW overlay to function. If both require an HW - // overlay we sort on the remaining criteria below. - if (a.candidate.requires_overlay ^ b.candidate.requires_overlay) { - return a.candidate.requires_overlay; + // overlay we leave them in order so the topmost one gets the overlay. + if (a.candidate.requires_overlay || b.candidate.requires_overlay) { + return a.candidate.requires_overlay && !b.candidate.requires_overlay; } // Opaque Power Metric:
diff --git a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc index d6409537..dbe9518 100644 --- a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc +++ b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
@@ -485,6 +485,10 @@ RunAomTest(FILE_PATH_LITERAL("aom-live-region.html")); } +IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, AccessibilityAomModalDialog) { + RunAomTest(FILE_PATH_LITERAL("aom-modal-dialog.html")); +} + // TODO(crbug.com/983709): Flaky. IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, DISABLED_AccessibilityAriaActivedescendant) {
diff --git a/content/browser/child_process_security_policy_impl.cc b/content/browser/child_process_security_policy_impl.cc index 5d2e3a9..c9f95a6d 100644 --- a/content/browser/child_process_security_policy_impl.cc +++ b/content/browser/child_process_security_policy_impl.cc
@@ -1533,19 +1533,6 @@ return CanCommitStatus::CAN_COMMIT_ORIGIN_AND_URL; } - // Allow "no access" schemes to commit even though |url_origin| and - // |origin| tuples don't match. We have to allow this because Blink's - // SecurityOrigin::CreateWithReferenceOrigin() and url::Origin::Resolve() - // handle "no access" URLs differently. CreateWithReferenceOrigin() treats - // "no access" like data: URLs and returns an opaque origin with |origin| - // as a precursor. Resolve() returns a non-opaque origin consisting of the - // scheme and host portions of the original URL. - // - // TODO(1020201): Make CreateWithReferenceOrigin() & Resolve() consistent - // with each other and then remove this exception. - if (base::Contains(url::GetNoAccessSchemes(), url_info.url.scheme())) - return CanCommitStatus::CAN_COMMIT_ORIGIN_AND_URL; - return CanCommitStatus::CANNOT_COMMIT_ORIGIN; }
diff --git a/content/browser/direct_sockets/direct_sockets_browsertest.cc b/content/browser/direct_sockets/direct_sockets_browsertest.cc index 26ddcf2..074e0f9 100644 --- a/content/browser/direct_sockets/direct_sockets_browsertest.cc +++ b/content/browser/direct_sockets/direct_sockets_browsertest.cc
@@ -26,6 +26,7 @@ #include "net/base/ip_address.h" #include "net/base/ip_endpoint.h" #include "net/base/net_errors.h" +#include "net/net_buildflags.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "net/traffic_annotation/network_traffic_annotation.h" #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" @@ -196,6 +197,25 @@ ->GetNetworkContext(); } + std::string CreateMDNSHostName() { + DCHECK(!mdns_responder_.is_bound()); + GetNetworkContext()->CreateMdnsResponder( + mdns_responder_.BindNewPipeAndPassReceiver()); + + std::string name; + base::RunLoop run_loop; + mdns_responder_->CreateNameForAddress( + net::IPAddress::IPv4Localhost(), + base::BindLambdaForTesting( + [&name, &run_loop](const std::string& name_out, + bool announcement_scheduled) { + name = name_out; + run_loop.Quit(); + })); + run_loop.Run(); + return name; + } + // Returns the port listening for TCP connections. uint16_t StartTcpServer() { net::IPEndPoint local_addr; @@ -233,6 +253,7 @@ } base::test::ScopedFeatureList feature_list_; + mojo::Remote<network::mojom::MdnsResponder> mdns_responder_; mojo::Remote<network::mojom::TCPServerSocket> tcp_server_socket_; }; @@ -280,6 +301,26 @@ EXPECT_EQ(expected_result, EvalJs(shell(), script)); } +IN_PROC_BROWSER_TEST_F(DirectSocketsBrowserTest, OpenTcp_MDNS) { + EXPECT_TRUE(NavigateToURL(shell(), GetTestPageURL())); + + const uint16_t listening_port = StartTcpServer(); + const std::string name = CreateMDNSHostName(); + EXPECT_TRUE(base::EndsWith(name, ".local")); + + const std::string script = + base::StringPrintf("openTcp({remoteAddress: '%s', remotePort: %d})", + name.c_str(), listening_port); + +#if BUILDFLAG(ENABLE_MDNS) + EXPECT_THAT(EvalJs(shell(), script).ExtractString(), + StartsWith("openTcp succeeded")); +#else + EXPECT_EQ("openTcp failed: NotAllowedError: Permission denied", + EvalJs(shell(), script)); +#endif // BUILDFLAG(ENABLE_MDNS) +} + IN_PROC_BROWSER_TEST_F(DirectSocketsBrowserTest, OpenTcp_CannotEvadeCors) { EXPECT_TRUE(NavigateToURL(shell(), GetTestPageURL()));
diff --git a/content/browser/direct_sockets/direct_sockets_service_impl.cc b/content/browser/direct_sockets/direct_sockets_service_impl.cc index ae746b2..b1176ab 100644 --- a/content/browser/direct_sockets/direct_sockets_service_impl.cc +++ b/content/browser/direct_sockets/direct_sockets_service_impl.cc
@@ -16,6 +16,7 @@ #include "mojo/public/cpp/bindings/self_owned_receiver.h" #include "mojo/public/cpp/system/data_pipe.h" #include "net/base/address_list.h" +#include "net/net_buildflags.h" #include "services/network/public/cpp/resolve_host_client_base.h" #include "services/network/public/mojom/network_context.mojom.h" @@ -52,6 +53,12 @@ return local_addr; } +// True if |hostname| ends with either ".local" or ".local.". +bool ResemblesMulticastDNSName(const std::string& hostname) { + return base::EndsWith(hostname, ".local") || + base::EndsWith(hostname, ".local."); +} + } // namespace DirectSocketsServiceImpl::DirectSocketsServiceImpl(RenderFrameHost& frame_host) @@ -104,16 +111,22 @@ void Start() { DCHECK(network_context_); DCHECK(!receiver_.is_bound()); + DCHECK(!resolver_.is_bound()); mojo::PendingRemote<network::mojom::HostResolver> pending_host_resolver; - mojo::Remote<network::mojom::HostResolver> resolver; network_context_->CreateHostResolver( base::nullopt, pending_host_resolver.InitWithNewPipeAndPassReceiver()); - resolver.Bind(std::move(pending_host_resolver)); + resolver_.Bind(std::move(pending_host_resolver)); - resolver->ResolveHost( + network::mojom::ResolveHostParametersPtr parameters = + network::mojom::ResolveHostParameters::New(); +#if BUILDFLAG(ENABLE_MDNS) + if (ResemblesMulticastDNSName(*options_->remote_hostname)) + parameters->source = net::HostResolverSource::MULTICAST_DNS; +#endif // !BUILDFLAG(ENABLE_MDNS) + resolver_->ResolveHost( net::HostPortPair(*options_->remote_hostname, options_->remote_port), - net::NetworkIsolationKey::CreateTransient(), nullptr, + net::NetworkIsolationKey::CreateTransient(), std::move(parameters), receiver_.BindNewPipeAndPassRemote()); receiver_.set_disconnect_handler( base::BindOnce(&ResolveHostAndOpenSocket::OnComplete, @@ -206,6 +219,7 @@ OpenUdpSocketCallback udp_callback_; mojo::Receiver<network::mojom::ResolveHostClient> receiver_{this}; + mojo::Remote<network::mojom::HostResolver> resolver_; }; void DirectSocketsServiceImpl::OpenTcpSocket( @@ -320,7 +334,6 @@ if (!options.remote_hostname) return net::ERR_NAME_NOT_RESOLVED; - // TODO(crbug.com/1124255): Support mDNS. return net::OK; }
diff --git a/content/browser/federated_learning/floc_service_impl.cc b/content/browser/federated_learning/floc_service_impl.cc index 8aabcac8..b2d17bf 100644 --- a/content/browser/federated_learning/floc_service_impl.cc +++ b/content/browser/federated_learning/floc_service_impl.cc
@@ -6,7 +6,6 @@ #include "base/bind.h" #include "content/browser/renderer_host/render_frame_host_impl.h" -#include "content/public/browser/browser_context.h" #include "content/public/browser/content_browser_client.h" #include "content/public/browser/render_frame_host.h" #include "content/public/common/content_client.h" @@ -33,12 +32,10 @@ } void FlocServiceImpl::GetInterestCohort(GetInterestCohortCallback callback) { - BrowserContext* browser_context = render_frame_host_->GetBrowserContext(); - DCHECK(browser_context); - std::string interest_cohort = GetContentClient()->browser()->GetInterestCohortForJsApi( - browser_context, render_frame_host_->GetLastCommittedURL(), + WebContents::FromRenderFrameHost(render_frame_host_), + render_frame_host_->GetLastCommittedURL(), render_frame_host_->GetIsolationInfoForSubresources() .top_frame_origin());
diff --git a/content/browser/loader/navigation_url_loader_impl_unittest.cc b/content/browser/loader/navigation_url_loader_impl_unittest.cc index 2f94c42..714868e2 100644 --- a/content/browser/loader/navigation_url_loader_impl_unittest.cc +++ b/content/browser/loader/navigation_url_loader_impl_unittest.cc
@@ -98,7 +98,8 @@ std::move(client), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0, /* request_id */ - 0 /* keepalive_request_size */, resource_scheduler_client_, + 0 /* keepalive_request_size */, + false /* require_network_isolation_key */, resource_scheduler_client_, nullptr /* keepalive_statistics_recorder */, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
diff --git a/content/browser/media/session/media_session_impl.cc b/content/browser/media/session/media_session_impl.cc index 1d5f203..6bb7c81 100644 --- a/content/browser/media/session/media_session_impl.cc +++ b/content/browser/media/session/media_session_impl.cc
@@ -154,6 +154,19 @@ return size.width() >= min_size || size.height() >= min_size; } +bool IsSizesAtLeast(const std::vector<gfx::Size>& sizes, int min_size) { + // If we haven't found an image based on size then we should check if there + // are any images that have no size data or have an "any" size which is + // denoted by a single empty gfx::Size value. + if (sizes.size() == 0 || (sizes.size() == 1 && sizes[0].IsEmpty())) + return true; + + bool check_size = false; + for (auto& size : sizes) + check_size = check_size || IsSizeAtLeast(size, min_size); + return check_size; +} + base::string16 SanitizeMediaTitle(const base::string16 title) { base::string16 out; base::TrimString(title, base::ASCIIToUTF16(" "), &out); @@ -1108,12 +1121,7 @@ } } - // Check that |image.sizes| contains a size that is above the minimum size. - bool check_size = false; - for (auto& size : image.sizes) - check_size = check_size || IsSizeAtLeast(size, minimum_size_px); - - if (!found || !check_size) { + if (!found || !IsSizesAtLeast(image.sizes, minimum_size_px)) { std::move(callback).Run(SkBitmap()); return; }
diff --git a/content/browser/navigation_browsertest.cc b/content/browser/navigation_browsertest.cc index 71d657e..7854ada4 100644 --- a/content/browser/navigation_browsertest.cc +++ b/content/browser/navigation_browsertest.cc
@@ -3314,19 +3314,10 @@ url::ScopedSchemeRegistryForTests scoped_registry_; }; -// TODO(1021779): Figure out why this fails on the kitkat-dbg builder -// and re-enable for all platforms. -#if defined(OS_ANDROID) -#define DISABLE_ON_ANDROID(x) DISABLED_##x -#else -#define DISABLE_ON_ANDROID(x) x -#endif - // Tests navigating to a URL that gets rewritten to a "no access" URL. This // mimics the behavior of navigating to special URLs like chrome://newtab and // chrome://history which get rewritten to "no access" chrome-native:// URLs. -IN_PROC_BROWSER_TEST_F(NavigationUrlRewriteBrowserTest, - DISABLE_ON_ANDROID(RewriteToNoAccess)) { +IN_PROC_BROWSER_TEST_F(NavigationUrlRewriteBrowserTest, RewriteToNoAccess) { // Perform an initial navigation. { TestNavigationObserver observer(web_contents());
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc index 97fd6bda9..6872dce 100644 --- a/content/browser/renderer_host/compositor_impl_android.cc +++ b/content/browser/renderer_host/compositor_impl_android.cc
@@ -341,8 +341,6 @@ } root_window_ = root_window; - if (base::FeatureList::IsEnabled(features::kForce60HzRefreshRate)) - root_window_->SetForce60HzRefreshRate(); root_window_->SetLayer(root_layer ? root_layer : cc::Layer::Create()); root_window_->GetLayer()->SetBounds(size_); root_window->AttachCompositor(this);
diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc index 6c29eb1..30cd8e5 100644 --- a/content/browser/renderer_host/navigation_request.cc +++ b/content/browser/renderer_host/navigation_request.cc
@@ -4,7 +4,9 @@ #include "content/browser/renderer_host/navigation_request.h" +#include <string> #include <utility> +#include <vector> #include "base/auto_reset.h" #include "base/bind.h" @@ -684,12 +686,17 @@ // Srcdoc subframes need to inherit their origin from their parent frame. if (navigation_request->GetURL().IsAboutSrcdoc()) { - // Srcdoc navigations in main frames are blocked before this function is - // called. This should guarantee existence of a parent here. RenderFrameHostImpl* parent = navigation_request->frame_tree_node()->parent(); - DCHECK(parent); - return parent->GetLastCommittedOrigin(); + + // The `parent` may be missing if a renderer executes `location = + // "about:srcdoc` instead of embedding an <iframe srcdoc="..."></iframe> + // element. Such case should use an error page with an opaque, unique + // origin. + // + // See also NavigationBrowserTest.BlockedSrcDoc* tests. + DCHECK(parent || navigation_request->GetNetErrorCode() != net::OK); + return parent ? parent->GetLastCommittedOrigin() : url::Origin(); } // In cases not covered above, URLLoaderFactory should be associated with the @@ -4510,8 +4517,12 @@ } url::Origin NavigationRequest::GetOriginForURLLoaderFactory() { + // The origin to commit is not known until we get the final network response. DCHECK_GE(state_, WILL_PROCESS_RESPONSE); + if (IsSameDocument() || IsServedFromBackForwardCache()) + return GetRenderFrameHost()->GetLastCommittedOrigin(); + // Calculate an approximation of the origin. The sandbox/csp are ignored. url::Origin origin = GetOriginForURLLoaderFactoryUnchecked(this); @@ -4525,15 +4536,20 @@ // This flag also prevents script from reading from or writing to the // document.cookie IDL attribute, and blocks access to localStorage. // ``` - const bool use_opaque_origin = (sandbox_flags_to_commit_.value() & - network::mojom::WebSandboxFlags::kOrigin) == - network::mojom::WebSandboxFlags::kOrigin; + bool use_opaque_origin = (sandbox_flags_to_commit_.value() & + network::mojom::WebSandboxFlags::kOrigin) == + network::mojom::WebSandboxFlags::kOrigin; + // TODO(https://crbug.com/1158370): Move special-casing error pages into + // ComputeSandboxFlagsToCommit (and renderer-side origin calculations) so that + // the most strict sandbox flags are applied. + if (GetNetErrorCode() != net::OK) + use_opaque_origin = true; if (use_opaque_origin) origin = origin.DeriveNewOpaqueOrigin(); // MHTML documents should commit as an opaque origin. They should not be able // to make network request on behalf of the real origin. - DCHECK(!IsMhtmlOrSubframe() || use_opaque_origin); + DCHECK(!IsMhtmlOrSubframe() || origin.opaque()); // https://crbug.com/1041376) of the origin that will be committed because of // |this| NavigationRequest. @@ -4984,6 +5000,11 @@ return common_params().initiator_origin; } +const std::vector<std::string>& NavigationRequest::GetDnsAliases() { + static const base::NoDestructor<std::vector<std::string>> emptyvector_result; + return response_head_ ? response_head_->dns_aliases : *emptyvector_result; +} + bool NavigationRequest::IsSameProcess() { return is_same_process_; }
diff --git a/content/browser/renderer_host/navigation_request.h b/content/browser/renderer_host/navigation_request.h index 6f293b4c..c22481c 100644 --- a/content/browser/renderer_host/navigation_request.h +++ b/content/browser/renderer_host/navigation_request.h
@@ -6,6 +6,8 @@ #define CONTENT_BROWSER_RENDERER_HOST_NAVIGATION_REQUEST_H_ #include <memory> +#include <string> +#include <vector> #include "base/callback.h" #include "base/callback_forward.h" @@ -323,6 +325,7 @@ override; int GetInitiatorProcessID() override; const base::Optional<url::Origin>& GetInitiatorOrigin() override; + const std::vector<std::string>& GetDnsAliases() override; bool IsSameProcess() override; NavigationEntry* GetNavigationEntry() override; int GetNavigationEntryOffset() override;
diff --git a/content/browser/renderer_host/navigation_request_unittest.cc b/content/browser/renderer_host/navigation_request_unittest.cc index a076ad2..8195aaa1 100644 --- a/content/browser/renderer_host/navigation_request_unittest.cc +++ b/content/browser/renderer_host/navigation_request_unittest.cc
@@ -3,6 +3,10 @@ // found in the LICENSE file. #include "content/browser/renderer_host/navigation_request.h" + +#include <string> +#include <vector> + #include "base/bind.h" #include "base/macros.h" #include "base/optional.h" @@ -17,6 +21,7 @@ #include "content/test/test_render_frame_host.h" #include "content/test/test_web_contents.h" #include "net/ssl/ssl_connection_status_flags.h" +#include "testing/gmock/include/gmock/gmock.h" #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom.h" namespace content { @@ -553,4 +558,54 @@ } } +TEST_F(NavigationRequestTest, DnsAliasesCanBeAccessed) { + // Create simulated NavigationRequest for the URL, which has aliases. + const GURL kUrl = GURL("http://chromium.org"); + auto navigation = + NavigationSimulatorImpl::CreateRendererInitiated(kUrl, main_rfh()); + std::vector<std::string> dns_aliases({"alias1", "alias2"}); + navigation->SetResponseDnsAliases(std::move(dns_aliases)); + + // Start the navigation. + navigation->Start(); + EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN, + navigation->GetNavigationHandle()->GetConnectionInfo()); + + // Commit the navigation. + navigation->set_http_connection_info( + net::HttpResponseInfo::CONNECTION_INFO_QUIC_35); + navigation->ReadyToCommit(); + EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_QUIC_35, + navigation->GetNavigationHandle()->GetConnectionInfo()); + + // Verify that the aliases are accessible from the NavigationRequest. + EXPECT_THAT(navigation->GetNavigationHandle()->GetDnsAliases(), + testing::ElementsAre("alias1", "alias2")); +} + +TEST_F(NavigationRequestTest, NoDnsAliases) { + // Create simulated NavigationRequest for the URL, which does not + // have aliases. (Note the empty alias list.) + const GURL kUrl = GURL("http://chromium.org"); + auto navigation = + NavigationSimulatorImpl::CreateRendererInitiated(kUrl, main_rfh()); + std::vector<std::string> dns_aliases; + navigation->SetResponseDnsAliases(std::move(dns_aliases)); + + // Start the navigation. + navigation->Start(); + EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN, + navigation->GetNavigationHandle()->GetConnectionInfo()); + + // Commit the navigation. + navigation->set_http_connection_info( + net::HttpResponseInfo::CONNECTION_INFO_QUIC_35); + navigation->ReadyToCommit(); + EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_QUIC_35, + navigation->GetNavigationHandle()->GetConnectionInfo()); + + // Verify that there are no aliases in the NavigationRequest. + EXPECT_TRUE(navigation->GetNavigationHandle()->GetDnsAliases().empty()); +} + } // namespace content
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc index 6855d3a..b1bab00 100644 --- a/content/browser/renderer_host/render_frame_host_impl.cc +++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -825,23 +825,25 @@ NavigationRequest* navigation_request, const mojom::DidCommitProvisionalLoadParams& params) { DCHECK(navigation_request); + DCHECK(!navigation_request->IsSameDocument()); + DCHECK(!navigation_request->IsServedFromBackForwardCache()); // Ignore for now cases where the NavigationRequest is in an unexpectedly - // early state. See also the NavigationRequestBrowserTest.VerifySameDocument - // test. + // early state. Triggered by the following tests: + // NavigationBrowserTest.OpenerNavigation_DownloadPolicy, + // WebContentsImplBrowserTest.NewNamedWindow. if (navigation_request->state() < NavigationRequest::WILL_PROCESS_RESPONSE) return; - // Ignore for now opaque |renderer_side_origin| origins. This effectively - // ignores the following scenarios: - // - error frames (i.e. navigation_request->GetNetErrorCode() != net::OK; - // see also the NavigationBrowserTest.FailedNavigation test) - // - sandboxed frames (see also https://crbug.com/1145139#c5) - // - comparison of precursor origins + // Check if both the renderer and browser expect an opaque origin. This + // effectively ignores the following: + // - precursor origins // - TODO(https://crbug.com/1041376): mismatched nonces (even if precursor // origins would have matched) const url::Origin& renderer_side_origin = params.origin; - if (renderer_side_origin.opaque()) + url::Origin browser_side_origin = + navigation_request->GetOriginForURLLoaderFactory(); + if (renderer_side_origin.opaque() && browser_side_origin.opaque()) return; // Ignore about:blank navigations, because browser-side calculated the origin @@ -852,9 +854,8 @@ if (navigation_request->GetURL().IsAboutBlank()) return; - url::Origin browser_side_origin = - navigation_request->GetOriginForURLLoaderFactory(); - DCHECK_EQ(browser_side_origin, renderer_side_origin); + DCHECK_EQ(browser_side_origin, renderer_side_origin) + << "; navigation_request->GetURL() = " << navigation_request->GetURL(); } } // namespace @@ -7399,36 +7400,30 @@ // |coep_reporter_receiver| is optional. DCHECK(out_trust_token_redemption_policy); - bool have_successful_request = - navigation_request && navigation_request->GetNetErrorCode() == net::OK; - bool have_failed_request = - navigation_request && navigation_request->GetNetErrorCode() != net::OK; CrossOriginEmbedderPolicyReporter* coep_reporter = nullptr; - if (have_successful_request) { + if (navigation_request) { // Return values based on the |navigation_request|. *out_main_world_origin = navigation_request->GetOriginForURLLoaderFactory(); - *out_isolation_info = navigation_request->isolation_info_for_subresources(); *out_client_security_state = navigation_request->BuildClientSecurityState(); - coep_reporter = navigation_request->coep_reporter(); - *out_trust_token_redemption_policy = - DetermineWhetherToForbidTrustTokenRedemption( - GetParent(), navigation_request->commit_params(), - *out_main_world_origin); - } else if (have_failed_request) { - // Some return values should always be the same for error pages. Some - // return values may be based on the |navigation_request|. - // Error page will commit in an opaque origin. - // TODO(lukasza): https://crbug.com/888079: Use this origin when sending the - // commit IPC and setting |last_committed_origin_|. - url::Origin error_page_origin = url::Origin(); - *out_main_world_origin = error_page_origin; - *out_isolation_info = net::IsolationInfo::CreateTransient(); - *out_client_security_state = navigation_request->BuildClientSecurityState(); - coep_reporter = nullptr; - *out_trust_token_redemption_policy = - network::mojom::TrustTokenRedemptionPolicy::kForbid; + // TODO(lukasza): Consider pushing the ok-vs-error differentiation into + // NavigationRequest methods (e.g. into |isolation_info_for_subresources| + // and/or |coep_reporter| methods). + if (navigation_request->GetNetErrorCode() == net::OK) { + *out_isolation_info = + navigation_request->isolation_info_for_subresources(); + coep_reporter = navigation_request->coep_reporter(); + *out_trust_token_redemption_policy = + DetermineWhetherToForbidTrustTokenRedemption( + GetParent(), navigation_request->commit_params(), + *out_main_world_origin); + } else { + *out_isolation_info = net::IsolationInfo::CreateTransient(); + coep_reporter = nullptr; + *out_trust_token_redemption_policy = + network::mojom::TrustTokenRedemptionPolicy::kForbid; + } } else { // Use properties of the last committed navigation. *out_main_world_origin = last_committed_origin_; @@ -8781,8 +8776,6 @@ DCHECK(navigation_request); DCHECK(navigation_request->IsNavigationStarted()); - VerifyThatBrowserAndRendererCalculatedOriginsToCommitMatch( - navigation_request.get(), *params); VerifyThatBrowserAndRendererCalculatedDidCommitParamsMatch( navigation_request.get(), *params, same_document_params.Clone()); @@ -8970,6 +8963,11 @@ // This should be fixed and the DCHECK restored. } + // TODO(https://crbug.com/888079): The origin computed from the browser must + // match the one reported from the renderer process. + VerifyThatBrowserAndRendererCalculatedOriginsToCommitMatch(navigation_request, + params); + coep_reporter_ = navigation_request->TakeCoepReporter(); if (coep_reporter_) { mojo::PendingRemote<blink::mojom::ReportingObserver> remote;
diff --git a/content/browser/renderer_host/render_frame_host_manager_unittest.cc b/content/browser/renderer_host/render_frame_host_manager_unittest.cc index 1331347..95a892b4 100644 --- a/content/browser/renderer_host/render_frame_host_manager_unittest.cc +++ b/content/browser/renderer_host/render_frame_host_manager_unittest.cc
@@ -18,6 +18,7 @@ #include "base/files/file_path.h" #include "base/hash/hash.h" #include "base/macros.h" +#include "base/memory/scoped_refptr.h" #include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" #include "base/test/metrics/histogram_tester.h" @@ -61,6 +62,7 @@ #include "content/test/test_render_widget_host.h" #include "content/test/test_web_contents.h" #include "net/base/load_flags.h" +#include "net/http/http_response_headers.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/frame/frame_policy.h" #include "third_party/blink/public/common/loader/previews_state.h" @@ -2805,7 +2807,14 @@ for (const auto& test_case : cases) { auto navigation = NavigationSimulatorImpl::CreateBrowserInitiated( GURL(test_case.url), contents()); - navigation->set_origin(url::Origin::Create(GURL(test_case.origin))); + url::Origin origin = url::Origin::Create(GURL(test_case.origin)); + navigation->set_origin(origin); + if (origin.opaque()) { + auto response_headers = + base::MakeRefCounted<net::HttpResponseHeaders>(std::string()); + response_headers->SetHeader("Content-Security-Policy", "sandbox"); + navigation->SetResponseHeaders(response_headers); + } navigation->ReadyToCommit(); int expected_bad_msg_count =
diff --git a/content/browser/service_worker/service_worker_controllee_request_handler.cc b/content/browser/service_worker/service_worker_controllee_request_handler.cc index 485cfc6c..94572f5 100644 --- a/content/browser/service_worker/service_worker_controllee_request_handler.cc +++ b/content/browser/service_worker/service_worker_controllee_request_handler.cc
@@ -118,15 +118,17 @@ BrowserContext* browser_context, NavigationLoaderInterceptor::LoaderCallback loader_callback, NavigationLoaderInterceptor::FallbackCallback fallback_callback) { - // InitializeContainerHost() will update the host. This is important to do - // before falling back to network below, so service worker APIs still work - // even if the service worker is bypassed for request interception. - if (!InitializeContainerHost(tentative_resource_request)) { + if (!container_host_) { // We can't do anything other than to fall back to network. std::move(loader_callback).Run({}); return; } + // Update the host. This is important to do before falling back to network + // below, so service worker APIs still work even if the service worker is + // bypassed for request interception. + InitializeContainerHost(tentative_resource_request); + // Fall back to network if we were instructed to bypass the service worker for // request interception, or if the context is gone so we have to bypass // anyway. @@ -173,14 +175,8 @@ weak_factory_.GetWeakPtr())); } -bool ServiceWorkerControlleeRequestHandler::InitializeContainerHost( +void ServiceWorkerControlleeRequestHandler::InitializeContainerHost( const network::ResourceRequest& tentative_resource_request) { - ClearJob(); - - if (!container_host_) { - return false; - } - // Update the container host with this request, clearing old controller state // if this is a redirect. container_host_->SetControllerRegistration(nullptr, @@ -192,7 +188,6 @@ ? tentative_resource_request.trusted_params ->isolation_info.top_frame_origin() : base::nullopt); - return true; } void ServiceWorkerControlleeRequestHandler::ContinueWithRegistration( @@ -520,16 +515,6 @@ weak_factory_.GetWeakPtr(), std::move(registration), version)); } -void ServiceWorkerControlleeRequestHandler::ClearJob() { - // Invalidate weak pointers to cancel RegisterStatusChangeCallback(). - // Otherwise we may end up calling ForwardToServiceWorer() - // or FallbackToNetwork() twice on the same |loader()|. - // TODO(bashi): Consider not to reuse this handler when restarting the - // request after S13nServiceWorker is shipped. - weak_factory_.InvalidateWeakPtrs(); - loader_wrapper_.reset(); -} - void ServiceWorkerControlleeRequestHandler::CompleteWithoutLoader() { std::move(loader_callback_).Run({}); }
diff --git a/content/browser/service_worker/service_worker_controllee_request_handler.h b/content/browser/service_worker/service_worker_controllee_request_handler.h index e9b5c26..f245aa97 100644 --- a/content/browser/service_worker/service_worker_controllee_request_handler.h +++ b/content/browser/service_worker/service_worker_controllee_request_handler.h
@@ -31,12 +31,15 @@ class ServiceWorkerRegistration; class ServiceWorkerVersion; -// Handles main resource requests for service worker clients (documents and -// shared workers). +// Handles a main resource request for service worker clients (documents and +// shared workers). This manages state for a single request and does not +// live across redirects. ServiceWorkerMainResourceLoaderInterceptor creates +// one instance of this class for each request/redirect. // -// TODO(crbug.com/1138155): Merge into -// ServiceWorkerMainResourceLoaderInterceptor now that they are on the same -// thread. +// This class associates the ServiceWorkerContainerHost undergoing navigation +// with a controller service worker, after looking up the registration and +// activating the service worker if needed. Once ready, it creates +// ServiceWorkerMainResourceLoader to perform the resource load. class CONTENT_EXPORT ServiceWorkerControlleeRequestHandler final { public: // If |skip_service_worker| is true, service workers are bypassed for @@ -49,19 +52,14 @@ ServiceWorkerAccessedCallback service_worker_accessed_callback); ~ServiceWorkerControlleeRequestHandler(); - // This could get called multiple times during the lifetime in redirect - // cases. (In fallback-to-network cases we basically forward the request - // to the request to the next request handler) + // This is called only once. On redirects, a new instance of this + // class is created. void MaybeCreateLoader( const network::ResourceRequest& tentative_request, BrowserContext* browser_context, NavigationLoaderInterceptor::LoaderCallback loader_callback, NavigationLoaderInterceptor::FallbackCallback fallback_callback); - // Does all initialization of |container_host_| for a request. - bool InitializeContainerHost( - const network::ResourceRequest& tentative_request); - // Exposed for testing. ServiceWorkerMainResourceLoader* loader() { return loader_wrapper_ ? loader_wrapper_->get() : nullptr; @@ -71,6 +69,10 @@ FRIEND_TEST_ALL_PREFIXES(ServiceWorkerControlleeRequestHandlerTest, ActivateWaitingVersion); + // Does all initialization of |container_host_| for a request. + void InitializeContainerHost( + const network::ResourceRequest& tentative_request); + void ContinueWithRegistration( blink::ServiceWorkerStatusCode status, scoped_refptr<ServiceWorkerRegistration> registration); @@ -88,10 +90,6 @@ scoped_refptr<ServiceWorkerRegistration> registration, scoped_refptr<ServiceWorkerVersion> version); - // Sets |job_| to nullptr, and clears all extra response info associated with - // that job, except for timing information. - void ClearJob(); - void CompleteWithoutLoader(); // Schedules a service worker update to occur shortly after the page and its
diff --git a/content/browser/service_worker/service_worker_main_resource_handle.h b/content/browser/service_worker/service_worker_main_resource_handle.h index cd904fb1..f7877f62 100644 --- a/content/browser/service_worker/service_worker_main_resource_handle.h +++ b/content/browser/service_worker/service_worker_main_resource_handle.h
@@ -9,7 +9,6 @@ #include "base/memory/weak_ptr.h" #include "content/browser/service_worker/service_worker_accessed_callback.h" #include "content/browser/service_worker/service_worker_container_host.h" -#include "content/browser/service_worker/service_worker_controllee_request_handler.h" #include "content/common/content_export.h" #include "services/metrics/public/cpp/ukm_source_id.h" #include "services/network/public/mojom/network_context.mojom.h" @@ -115,15 +114,6 @@ return parent_container_host_; } - void set_interceptor( - std::unique_ptr<ServiceWorkerControlleeRequestHandler> interceptor) { - interceptor_ = std::move(interceptor); - } - - ServiceWorkerControlleeRequestHandler* interceptor() { - return interceptor_.get(); - } - const ServiceWorkerAccessedCallback& service_worker_accessed_callback() { return service_worker_accessed_callback_; } @@ -144,8 +134,6 @@ // Only used for workers with a blob URL. base::WeakPtr<ServiceWorkerContainerHost> parent_container_host_; - std::unique_ptr<ServiceWorkerControlleeRequestHandler> interceptor_; - ServiceWorkerAccessedCallback service_worker_accessed_callback_; scoped_refptr<ServiceWorkerContextWrapper> context_wrapper_;
diff --git a/content/browser/service_worker/service_worker_main_resource_loader_interceptor.cc b/content/browser/service_worker/service_worker_main_resource_loader_interceptor.cc index 9d31f41..fe85f03 100644 --- a/content/browser/service_worker/service_worker_main_resource_loader_interceptor.cc +++ b/content/browser/service_worker/service_worker_main_resource_loader_interceptor.cc
@@ -16,7 +16,6 @@ #include "content/browser/service_worker/service_worker_container_host.h" #include "content/browser/service_worker/service_worker_context_core.h" #include "content/browser/service_worker/service_worker_context_wrapper.h" -#include "content/browser/service_worker/service_worker_controllee_request_handler.h" #include "content/browser/service_worker/service_worker_main_resource_handle.h" #include "content/browser/service_worker/service_worker_object_host.h" #include "content/public/common/content_client.h" @@ -148,7 +147,7 @@ // `container_info`. DCHECK(!handle_->container_host()); base::WeakPtr<ServiceWorkerContainerHost> container_host; - bool inherit_container_host_only = false; + bool inherit_controller_only = false; if (request_destination_ == network::mojom::RequestDestination::kDocument || request_destination_ == network::mojom::RequestDestination::kIframe) { @@ -177,34 +176,29 @@ tentative_resource_request.url.SchemeIsBlob()) { container_host->InheritControllerFrom(*parent_container_host, tentative_resource_request.url); - inherit_container_host_only = true; + inherit_controller_only = true; } } DCHECK(container_host); handle_->set_container_host(container_host); - // Also make the inner interceptor. - DCHECK(!handle_->interceptor()); - handle_->set_interceptor( - std::make_unique<ServiceWorkerControlleeRequestHandler>( - context_core->AsWeakPtr(), container_host, request_destination_, - skip_service_worker_, handle_->service_worker_accessed_callback())); - - // For the blob worker case, we only inherit the controller and do not - // let it intercept the requests. Blob URLs are not eligible to go through - // service worker interception. So just call the loader callback now. - // We don't use the interceptor but have to set it because we need - // ControllerServiceWorkerInfoPtr and ServiceWorkerObjectHost from the - // subresource loader params which is created by the interceptor. - if (inherit_container_host_only) { + // For the blob worker case, we only inherit the controller and do not let + // it intercept the main resource request. Blob URLs are not eligible to + // go through service worker interception. So just call the loader + // callback now. + if (inherit_controller_only) { std::move(loader_callback).Run(/*handler=*/{}); return; } } - // Start the inner interceptor. It will invoke the loader callback - // or fallback callback. - handle_->interceptor()->MaybeCreateLoader( + // Create and start the handler for this request. It will invoke the loader + // callback or fallback callback. + request_handler_ = std::make_unique<ServiceWorkerControlleeRequestHandler>( + context_core->AsWeakPtr(), handle_->container_host(), + request_destination_, skip_service_worker_, + handle_->service_worker_accessed_callback()); + request_handler_->MaybeCreateLoader( tentative_resource_request, browser_context, std::move(loader_callback), std::move(fallback_callback)); }
diff --git a/content/browser/service_worker/service_worker_main_resource_loader_interceptor.h b/content/browser/service_worker/service_worker_main_resource_loader_interceptor.h index 8997c46..67a2447d 100644 --- a/content/browser/service_worker/service_worker_main_resource_loader_interceptor.h +++ b/content/browser/service_worker/service_worker_main_resource_loader_interceptor.h
@@ -13,6 +13,7 @@ #include "content/browser/loader/navigation_loader_interceptor.h" #include "content/browser/loader/single_request_url_loader_factory.h" #include "content/browser/navigation_subresource_loader_params.h" +#include "content/browser/service_worker/service_worker_controllee_request_handler.h" #include "content/common/content_export.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/service_worker_client_info.h" @@ -126,6 +127,9 @@ const int process_id_; const base::Optional<DedicatedOrSharedWorkerToken> worker_token_; + // Handles a single request. Set to a new instance on redirects. + std::unique_ptr<ServiceWorkerControlleeRequestHandler> request_handler_; + DISALLOW_COPY_AND_ASSIGN(ServiceWorkerMainResourceLoaderInterceptor); };
diff --git a/content/browser/speech/tts_controller_impl.cc b/content/browser/speech/tts_controller_impl.cc index 8715e8e..421ec2db 100644 --- a/content/browser/speech/tts_controller_impl.cc +++ b/content/browser/speech/tts_controller_impl.cc
@@ -15,6 +15,7 @@ #include "base/json/json_reader.h" #include "base/metrics/histogram_macros.h" #include "base/metrics/user_metrics.h" +#include "base/strings/string_util.h" #include "base/values.h" #include "build/build_config.h" #include "build/chromeos_buildflags.h" @@ -691,11 +692,13 @@ // Prefer the utterance language. if (!voice.lang.empty() && !utterance->GetLang().empty()) { - // An exact language match is worth more than a partial match. - if (voice.lang == utterance->GetLang()) { + // An exact locale match is worth more than a partial match. + // Convert locales to lowercase to handle cases like "en-us" vs. "en-US". + if (base::EqualsCaseInsensitiveASCII(voice.lang, utterance->GetLang())) { score += 128; - } else if (l10n_util::GetLanguage(voice.lang) == - l10n_util::GetLanguage(utterance->GetLang())) { + } else if (base::EqualsCaseInsensitiveASCII( + l10n_util::GetLanguage(voice.lang), + l10n_util::GetLanguage(utterance->GetLang()))) { score += 64; } } @@ -739,8 +742,9 @@ if (!voice.lang.empty()) { if (voice.lang == app_lang) { score += 2; - } else if (l10n_util::GetLanguage(voice.lang) == - l10n_util::GetLanguage(app_lang)) { + } else if (base::EqualsCaseInsensitiveASCII( + l10n_util::GetLanguage(voice.lang), + l10n_util::GetLanguage(app_lang))) { score += 1; } }
diff --git a/content/browser/speech/tts_controller_unittest.cc b/content/browser/speech/tts_controller_unittest.cc index 31dd5bc..2f1e8c0 100644 --- a/content/browser/speech/tts_controller_unittest.cc +++ b/content/browser/speech/tts_controller_unittest.cc
@@ -510,6 +510,50 @@ EXPECT_EQ(0, controller()->GetMatchingVoice(utterance.get(), voices)); #endif } + + { + // This block ensures that voices can be matched, even if their locale's + // casing doesn't exactly match that of the utterance e.g. "en-us" will + // match with "en-US". + std::vector<VoiceData> voices; + VoiceData voice0; + voice0.engine_id = "id0"; + voice0.name = "English voice"; + voice0.lang = "en-US"; + voices.push_back(voice0); + VoiceData voice1; + voice1.engine_id = "id0"; + voice1.name = "French voice"; + voice1.lang = "fr"; + voices.push_back(voice1); + + std::unique_ptr<TtsUtterance> utterance(TtsUtterance::Create()); + utterance->SetLang("en-us"); + EXPECT_EQ(0, controller()->GetMatchingVoice(utterance.get(), voices)); + utterance->SetLang("en-US"); + EXPECT_EQ(0, controller()->GetMatchingVoice(utterance.get(), voices)); + utterance->SetLang("EN-US"); + EXPECT_EQ(0, controller()->GetMatchingVoice(utterance.get(), voices)); + +#if BUILDFLAG(IS_CHROMEOS_ASH) + // Add another English voice. + VoiceData voice2; + voice2.engine_id = "id1"; + voice2.name = "Another English voice"; + voice2.lang = "en-us"; + voices.push_back(voice2); + + // Set voice2 as the preferred voice for English. + TtsControllerDelegate::PreferredVoiceIds preferred_voice_ids; + preferred_voice_ids.lang_voice_id.emplace(voice2.name, voice2.engine_id); + delegate()->SetPreferredVoiceIds(preferred_voice_ids); + + // Ensure that voice2 is chosen over voice0, even though the locales don't + // match exactly. The utterance has a locale of "en-US", while voice2 has + // a locale of "en-us"; this shouldn't prevent voice2 from being used. + EXPECT_EQ(2, controller()->GetMatchingVoice(utterance.get(), voices)); +#endif + } } TEST_F(TtsControllerTest, StopsWhenWebContentsDestroyed) {
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc index c366ae5..96b405fd 100644 --- a/content/public/browser/content_browser_client.cc +++ b/content/public/browser/content_browser_client.cc
@@ -1045,7 +1045,7 @@ NavigationDownloadPolicy* download_policy) {} std::string ContentBrowserClient::GetInterestCohortForJsApi( - content::BrowserContext* browser_context, + WebContents* web_contents, const GURL& url, const base::Optional<url::Origin>& top_frame_origin) { return std::string();
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index 0cd721c..03f8c36 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h
@@ -1814,9 +1814,10 @@ bool user_gesture, NavigationDownloadPolicy* download_policy); - // Returns the interest cohort associated with the |browser_context|. + // Returns the interest cohort associated with the browser context of + // |web_contents|. virtual std::string GetInterestCohortForJsApi( - content::BrowserContext* browser_context, + WebContents* web_contents, const GURL& url, const base::Optional<url::Origin>& top_frame_origin);
diff --git a/content/public/browser/navigation_handle.h b/content/public/browser/navigation_handle.h index 867387d..160f243 100644 --- a/content/public/browser/navigation_handle.h +++ b/content/public/browser/navigation_handle.h
@@ -7,6 +7,7 @@ #include <memory> #include <string> +#include <vector> #include "content/common/content_export.h" #include "content/public/browser/navigation_handle_timing.h" @@ -385,6 +386,11 @@ // navigation for this NavigationHandle. virtual const base::Optional<url::Origin>& GetInitiatorOrigin() = 0; + // Retrieves any DNS aliases for the requested URL. The alias chain order + // is preserved in reverse, from canonical name (i.e. address record name) + // through to query name. + virtual const std::vector<std::string>& GetDnsAliases() = 0; + // Whether the new document will be hosted in the same process as the current // document or not. Set only when the navigation commits. virtual bool IsSameProcess() = 0;
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc index 9884308..1801553c 100644 --- a/content/public/common/content_features.cc +++ b/content/public/common/content_features.cc
@@ -877,10 +877,6 @@ "BackgroundMediaRendererHasModerateBinding", base::FEATURE_DISABLED_BY_DEFAULT}; -// Force display to tick at ~60Hz refresh rate. -const base::Feature kForce60HzRefreshRate{"Force60HzRefreshRate", - base::FEATURE_DISABLED_BY_DEFAULT}; - // Screen Capture API support for Android const base::Feature kUserMediaScreenCapturing{ "UserMediaScreenCapturing", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h index 9f7bf5a9..7d22686 100644 --- a/content/public/common/content_features.h +++ b/content/public/common/content_features.h
@@ -201,7 +201,6 @@ CONTENT_EXPORT extern const base::Feature kAndroidAutofillAccessibility; CONTENT_EXPORT extern const base::Feature kBackgroundMediaRendererHasModerateBinding; -CONTENT_EXPORT extern const base::Feature kForce60HzRefreshRate; CONTENT_EXPORT extern const base::Feature kUserMediaScreenCapturing; CONTENT_EXPORT extern const base::Feature kWarmUpNetworkProcess; CONTENT_EXPORT extern const base::Feature kWebNfc;
diff --git a/content/public/test/mock_navigation_handle.h b/content/public/test/mock_navigation_handle.h index df996d3..4440d5e 100644 --- a/content/public/test/mock_navigation_handle.h +++ b/content/public/test/mock_navigation_handle.h
@@ -5,7 +5,11 @@ #ifndef CONTENT_PUBLIC_TEST_MOCK_NAVIGATION_HANDLE_H_ #define CONTENT_PUBLIC_TEST_MOCK_NAVIGATION_HANDLE_H_ +#include <string> +#include <vector> + #include "base/memory/ref_counted.h" +#include "base/no_destructor.h" #include "content/public/browser/global_request_id.h" #include "content/public/browser/global_routing_id.h" #include "content/public/browser/navigation_handle.h" @@ -130,6 +134,11 @@ const base::Optional<url::Origin>& GetInitiatorOrigin() override { return initiator_origin_; } + const std::vector<std::string>& GetDnsAliases() override { + static const base::NoDestructor<std::vector<std::string>> + emptyvector_result; + return *emptyvector_result; + } MOCK_METHOD(void, RegisterThrottleForTesting, (std::unique_ptr<NavigationThrottle>));
diff --git a/content/public/test/navigation_simulator.h b/content/public/test/navigation_simulator.h index cf2acb5..2761c57 100644 --- a/content/public/test/navigation_simulator.h +++ b/content/public/test/navigation_simulator.h
@@ -305,6 +305,12 @@ // Commit(). virtual void SetSSLInfo(const net::SSLInfo& ssl_info) = 0; + // Sets the DNS aliases to be received in the URLResponseHead. The aliases + // are what would be read from DNS CNAME records, and the alias chain should + // be preserved in reverse order, from canonical name (i.e. address record + // name) through to query name. This method should be called before Commit(). + virtual void SetResponseDnsAliases(std::vector<std::string> aliases) = 0; + // -------------------------------------------------------------------------- // Gets the last throttle check result computed by the navigation throttles.
diff --git a/content/renderer/accessibility/render_accessibility_impl.cc b/content/renderer/accessibility/render_accessibility_impl.cc index b13f677..af3294e 100644 --- a/content/renderer/accessibility/render_accessibility_impl.cc +++ b/content/renderer/accessibility/render_accessibility_impl.cc
@@ -265,14 +265,9 @@ if (!document.IsNull()) { StartOrStopLabelingImages(old_mode, mode); - // If there are any events in flight, |HandleAXEvent| will refuse to process - // our new event. - pending_events_.clear(); - auto root_object = WebAXObject::FromWebDocument(document, false); - ax::mojom::Event event = root_object.IsLoaded() - ? ax::mojom::Event::kLoadComplete - : ax::mojom::Event::kLayoutComplete; - HandleAXEvent(ui::AXEvent(root_object.AxID(), event)); + needs_initial_ax_tree_root_ = true; + event_schedule_mode_ = EventScheduleMode::kProcessEventsImmediately; + ScheduleSendPendingAccessibilityEvents(); } } @@ -476,11 +471,11 @@ if (!document.IsNull()) { // Tree-only mode gets used by the automation extension API which requires a // load complete event to invoke listener callbacks. - auto root_object = WebAXObject::FromWebDocument(document, false); - ax::mojom::Event event = root_object.IsLoaded() - ? ax::mojom::Event::kLoadComplete - : ax::mojom::Event::kLayoutComplete; - HandleAXEvent(ui::AXEvent(root_object.AxID(), event)); + // SendPendingAccessibilityEvents() will fire the load complete event + // if the page is loaded. + needs_initial_ax_tree_root_ = true; + event_schedule_mode_ = EventScheduleMode::kProcessEventsImmediately; + ScheduleSendPendingAccessibilityEvents(); } } @@ -797,10 +792,20 @@ // complete for the entire document, in order to initialize the browser's // cached accessibility tree. needs_initial_ax_tree_root_ = false; - auto obj = WebAXObject::FromWebDocument(document); + auto root_obj = WebAXObject::FromWebDocument(document); + // Always fire layout complete for a new root object. pending_events_.insert( pending_events_.begin(), - ui::AXEvent(obj.AxID(), ax::mojom::Event::kLayoutComplete)); + ui::AXEvent(root_obj.AxID(), ax::mojom::Event::kLayoutComplete)); + + // If loaded and has some content, insert load complete at the top, so that + // screen readers are informed a new document is ready. + if (root_obj.IsLoaded() && !document.Body().IsNull() && + !document.Body().FirstChild().IsNull()) { + pending_events_.insert( + pending_events_.begin(), + ui::AXEvent(root_obj.AxID(), ax::mojom::Event::kLoadComplete)); + } } if (pending_events_.empty() && dirty_objects_.empty()) { @@ -834,8 +839,8 @@ // location changes. bool need_to_send_location_changes = false; - // If there's a load complete message, we need to change the event schedule - // mode. + // Keep track of load complete messages. When a load completes, it's a good + // time to inject a stylesheet for image annotation debugging. bool had_load_complete_messages = false; ScopedFreezeBlinkAXTreeSource freeze(tree_source_.get());
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index c2efa9d1..352a04b 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -1563,10 +1563,8 @@ "../browser/site_per_process_mac_browsertest.mm", "../renderer/render_view_browsertest_mac.mm", ] - deps += [ - "//content/shell:content_shell", - "//third_party/ocmock", - ] + deps += [ "//third_party/ocmock" ] + data_deps += [ "//content/shell:content_shell" ] data += [ "$root_out_dir/Content Shell.app/" ] }
diff --git a/content/test/data/accessibility/aom/aom-modal-dialog-expected-android.txt b/content/test/data/accessibility/aom/aom-modal-dialog-expected-android.txt new file mode 100644 index 0000000..3d832796 --- /dev/null +++ b/content/test/data/accessibility/aom/aom-modal-dialog-expected-android.txt
@@ -0,0 +1,6 @@ +android.webkit.WebView focusable focused scrollable +++android.view.View +++++android.widget.TextView name='Content outside modal dialog. ' +++++android.widget.Button role_description='button' clickable focusable name='Button outside modal dialog.' +++android.app.Dialog role_description='dialog' name='Modal dialog.' +++++android.widget.Button role_description='button' clickable name='Button inside modal dialog.'
diff --git a/content/test/data/accessibility/aom/aom-modal-dialog-expected-auralinux.txt b/content/test/data/accessibility/aom/aom-modal-dialog-expected-auralinux.txt new file mode 100644 index 0000000..9b09d395 --- /dev/null +++ b/content/test/data/accessibility/aom/aom-modal-dialog-expected-auralinux.txt
@@ -0,0 +1,6 @@ +[document web] +++[section] +++++[static] name='Content outside modal dialog. ' +++++[push button] name='Button outside modal dialog.' +++[dialog] name='Modal dialog.' modal +++++[push button] name='Button inside modal dialog.'
diff --git a/content/test/data/accessibility/aom/aom-modal-dialog-expected-blink.txt b/content/test/data/accessibility/aom/aom-modal-dialog-expected-blink.txt new file mode 100644 index 0000000..032a717 --- /dev/null +++ b/content/test/data/accessibility/aom/aom-modal-dialog-expected-blink.txt
@@ -0,0 +1,11 @@ +rootWebArea +++genericContainer ignored +++++genericContainer ignored +++++++genericContainer +++++++++staticText name='Content outside modal dialog. ' +++++++++++inlineTextBox name='Content outside modal dialog. ' +++++++++button name='Button outside modal dialog.' +++++++++++staticText name='Button outside modal dialog.' +++++++++++++inlineTextBox name='Button outside modal dialog.' +++++++dialog name='Modal dialog.' modal=true +++++++++button name='Button inside modal dialog.'
diff --git a/content/test/data/accessibility/aom/aom-modal-dialog-expected-mac.txt b/content/test/data/accessibility/aom/aom-modal-dialog-expected-mac.txt new file mode 100644 index 0000000..90b0ce92 --- /dev/null +++ b/content/test/data/accessibility/aom/aom-modal-dialog-expected-mac.txt
@@ -0,0 +1,6 @@ +AXWebArea +++AXGroup +++++AXStaticText AXValue='Content outside modal dialog. ' +++++AXButton AXTitle='Button outside modal dialog.' +++AXGroup AXSubrole=AXApplicationDialog AXDescription='Modal dialog.' +++++AXButton AXDescription='Button inside modal dialog.'
diff --git a/content/test/data/accessibility/aom/aom-modal-dialog-expected-uia-win.txt b/content/test/data/accessibility/aom/aom-modal-dialog-expected-uia-win.txt new file mode 100644 index 0000000..cb7d5e84 --- /dev/null +++ b/content/test/data/accessibility/aom/aom-modal-dialog-expected-uia-win.txt
@@ -0,0 +1,6 @@ +Document LocalizedControlType='document' +++Group LocalizedControlType='group' IsControlElement=false +++++Text LocalizedControlType='text' Name='Content outside modal dialog. ' +++++Button LocalizedControlType='button' Name='Button outside modal dialog.' +++Pane LocalizedControlType='dialog' Name='Modal dialog.' Window.IsModal=true +++++Button LocalizedControlType='button' Name='Button inside modal dialog.'
diff --git a/content/test/data/accessibility/aom/aom-modal-dialog-expected-uia-win7.txt b/content/test/data/accessibility/aom/aom-modal-dialog-expected-uia-win7.txt new file mode 100644 index 0000000..d0369093 --- /dev/null +++ b/content/test/data/accessibility/aom/aom-modal-dialog-expected-uia-win7.txt
@@ -0,0 +1,6 @@ +Document LocalizedControlType='document' +++Group LocalizedControlType='group' IsControlElement=false +++++Text LocalizedControlType='text' Name='Content outside modal dialog. ' +++++Button LocalizedControlType='button' Name='Button outside modal dialog.' +++Pane LocalizedControlType='pane' Name='Modal dialog.' Window.IsModal=true +++++Button LocalizedControlType='button' Name='Button inside modal dialog.'
diff --git a/content/test/data/accessibility/aom/aom-modal-dialog-expected-win.txt b/content/test/data/accessibility/aom/aom-modal-dialog-expected-win.txt new file mode 100644 index 0000000..45773d2 --- /dev/null +++ b/content/test/data/accessibility/aom/aom-modal-dialog-expected-win.txt
@@ -0,0 +1,6 @@ +ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE +++IA2_ROLE_SECTION +++++ROLE_SYSTEM_STATICTEXT name='Content outside modal dialog. ' +++++ROLE_SYSTEM_PUSHBUTTON name='Button outside modal dialog.' FOCUSABLE +++ROLE_SYSTEM_DIALOG name='Modal dialog.' IA2_STATE_MODAL +++++ROLE_SYSTEM_PUSHBUTTON name='Button inside modal dialog.'
diff --git a/content/test/data/accessibility/aom/aom-modal-dialog.html b/content/test/data/accessibility/aom/aom-modal-dialog.html new file mode 100644 index 0000000..622a9e8 --- /dev/null +++ b/content/test/data/accessibility/aom/aom-modal-dialog.html
@@ -0,0 +1,33 @@ +<!DOCTYPE html> +<!-- +@BLINK-ALLOW:modal* +@WIN-ALLOW:IA2_STATE_MODAL +@WIN-ALLOW:container* +@UIA-WIN-ALLOW:Window.IsModal* +@UIA-WIN-ALLOW:LocalizedControlType* +@MAC-ALLOW:AXSubrole +@AURALINUX-ALLOW:modal* + +TODO: For Mac and Android, we need to prune the content outside modal dialog. +http://crbug.com/1165298 +--> +<html> +<body> + <div> + Content outside modal dialog. + <button>Button outside modal dialog.</button> + </div> + <script> + var button_node = new AccessibleNode(); + button_node.role = "button"; + button_node.label = "Button inside modal dialog."; + + var dialog_node = new AccessibleNode(); + dialog_node.role = "dialog"; + dialog_node.modal = "true"; + dialog_node.label = "Modal dialog." + document.body.accessibleNode.appendChild(dialog_node); + dialog_node.appendChild(button_node); + </script> +</body> +</html>
diff --git a/content/test/navigation_simulator_impl.cc b/content/test/navigation_simulator_impl.cc index 16db4797..e70b71f 100644 --- a/content/test/navigation_simulator_impl.cc +++ b/content/test/navigation_simulator_impl.cc
@@ -527,7 +527,7 @@ ->PrepareForCommitDeprecatedForNavigationSimulator( remote_endpoint_, was_fetched_via_cache_, is_signed_exchange_inner_response_, http_connection_info_, - ssl_info_, response_headers_); + ssl_info_, response_headers_, response_dns_aliases_); } // Synchronous failure can cause the navigation to finish here. @@ -949,6 +949,11 @@ ssl_info_ = ssl_info; } +void NavigationSimulatorImpl::SetResponseDnsAliases( + std::vector<std::string> aliases) { + response_dns_aliases_ = std::move(aliases); +} + NavigationThrottle::ThrottleCheckResult NavigationSimulatorImpl::GetLastThrottleCheckResult() { return last_throttle_check_result_.value();
diff --git a/content/test/navigation_simulator_impl.h b/content/test/navigation_simulator_impl.h index d07c629..8591616 100644 --- a/content/test/navigation_simulator_impl.h +++ b/content/test/navigation_simulator_impl.h
@@ -94,6 +94,7 @@ void SetResolveErrorInfo( const net::ResolveErrorInfo& resolve_error_info) override; void SetSSLInfo(const net::SSLInfo& ssl_info) override; + void SetResponseDnsAliases(std::vector<std::string> aliases) override; NavigationThrottle::ThrottleCheckResult GetLastThrottleCheckResult() override; NavigationRequest* GetNavigationHandle() override; @@ -296,6 +297,12 @@ base::Optional<Impression> impression_; int64_t post_id_ = -1; + // Any DNS aliases, as read from CNAME records, for the request URL that + // would be in the network::mojom::URLResponseHead. The alias chain order + // is preserved in reverse, from canonical name (i.e. address record name) + // through to query name. + std::vector<std::string> response_dns_aliases_; + bool auto_advance_ = true; bool drop_unload_ack_ = false; bool block_invoking_before_unload_completed_callback_ = false;
diff --git a/content/test/test_render_frame_host.cc b/content/test/test_render_frame_host.cc index de9e3c15..34e1356 100644 --- a/content/test/test_render_frame_host.cc +++ b/content/test/test_render_frame_host.cc
@@ -346,7 +346,7 @@ /* was_fetched_via_cache=*/false, /* is_signed_exchange_inner_response=*/false, net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN, - base::nullopt, nullptr); + base::nullopt, nullptr, {} /* dns_aliases */); } void TestRenderFrameHost::PrepareForCommitDeprecatedForNavigationSimulator( @@ -355,10 +355,11 @@ bool is_signed_exchange_inner_response, net::HttpResponseInfo::ConnectionInfo connection_info, base::Optional<net::SSLInfo> ssl_info, - scoped_refptr<net::HttpResponseHeaders> response_headers) { + scoped_refptr<net::HttpResponseHeaders> response_headers, + const std::vector<std::string>& dns_aliases) { PrepareForCommitInternal(remote_endpoint, was_fetched_via_cache, is_signed_exchange_inner_response, connection_info, - ssl_info, response_headers); + ssl_info, response_headers, dns_aliases); } void TestRenderFrameHost::PrepareForCommitInternal( @@ -367,7 +368,8 @@ bool is_signed_exchange_inner_response, net::HttpResponseInfo::ConnectionInfo connection_info, base::Optional<net::SSLInfo> ssl_info, - scoped_refptr<net::HttpResponseHeaders> response_headers) { + scoped_refptr<net::HttpResponseHeaders> response_headers, + const std::vector<std::string>& dns_aliases) { NavigationRequest* request = frame_tree_node_->navigation_request(); CHECK(request); bool have_to_make_network_request = @@ -412,6 +414,7 @@ response->headers = response_headers; response->parsed_headers = network::PopulateParsedHeaders(response->headers, request->GetURL()); + response->dns_aliases = dns_aliases; // TODO(carlosk): Ideally, it should be possible someday to // fully commit the navigation at this call to CallOnResponseStarted. url_loader->CallOnResponseStarted(std::move(response));
diff --git a/content/test/test_render_frame_host.h b/content/test/test_render_frame_host.h index e0bd9e5..170d554 100644 --- a/content/test/test_render_frame_host.h +++ b/content/test/test_render_frame_host.h
@@ -147,7 +147,8 @@ bool is_signed_exchange_inner_response, net::HttpResponseInfo::ConnectionInfo connection_info, base::Optional<net::SSLInfo> ssl_info, - scoped_refptr<net::HttpResponseHeaders> response_headers); + scoped_refptr<net::HttpResponseHeaders> response_headers, + const std::vector<std::string>& dns_aliases); // Used to simulate the commit of a navigation having been processed in the // renderer. If parameters required to commit are not provided, they will be @@ -239,7 +240,8 @@ bool is_signed_exchange_inner_response, net::HttpResponseInfo::ConnectionInfo connection_info, base::Optional<net::SSLInfo> ssl_info, - scoped_refptr<net::HttpResponseHeaders> response_headers); + scoped_refptr<net::HttpResponseHeaders> response_headers, + const std::vector<std::string>& dns_aliases); // Computes the page ID for a pending navigation in this RenderFrameHost; int32_t ComputeNextPageID();
diff --git a/device/bluetooth/public/mojom/adapter.mojom b/device/bluetooth/public/mojom/adapter.mojom index b593b1e..9c8932a 100644 --- a/device/bluetooth/public/mojom/adapter.mojom +++ b/device/bluetooth/public/mojom/adapter.mojom
@@ -92,8 +92,9 @@ }; // Represents an open connection to a remote device. Releasing it will destroy -// the underlying connection, but callers should prefer to let a call to -// Disconnect() to finish first. +// the underlying connection, but if callers want to try again soon, they should +// call Disconnect() first and wait for completion to ensure that the resource +// has been completely released. // Note: Methods which are declared [Sync] are for use by // //chrome/services/sharing/nearby; all other usage of their synchronous // signatures is strongly discouraged. @@ -107,7 +108,9 @@ }; // Represents a pending connecting from a remote device. Releasing it will -// stop listening for an incoming connection. +// stop listening for an incoming connection, but if callers want to start +// listening again soon, they should call Disconnect() first and wait for +// completion to ensure that the resource has been completely released. // Note: Methods which are declared [Sync] are for use by // //chrome/services/sharing/nearby; all other usage of their synchronous // signatures is strongly discouraged. @@ -116,6 +119,13 @@ // goes wrong, the returned |result| will be null. [Sync] Accept() => (AcceptConnectionResult? result); + + // Use to gracefully close the underlying resource before destroying. The + // reply callback can be used to synchronize an attempt to re-initialize + // a server socket; attempting to listen on the same server socket on this + // device may fail with a busy error until the reply callback is invoked. + [Sync] + Disconnect() => (); }; // Handles requests to either query Bluetooth adapter capabilities or state, or
diff --git a/device/bluetooth/server_socket.cc b/device/bluetooth/server_socket.cc index f673e2e..af21933 100644 --- a/device/bluetooth/server_socket.cc +++ b/device/bluetooth/server_socket.cc
@@ -36,6 +36,11 @@ weak_ptr_factory_.GetWeakPtr(), copyable_callback)); } +void ServerSocket::Disconnect(DisconnectCallback callback) { + DCHECK(server_socket_); + server_socket_->Disconnect(std::move(callback)); +} + void ServerSocket::OnAccept( AcceptCallback callback, const device::BluetoothDevice* device,
diff --git a/device/bluetooth/server_socket.h b/device/bluetooth/server_socket.h index e685936..8647a3bb 100644 --- a/device/bluetooth/server_socket.h +++ b/device/bluetooth/server_socket.h
@@ -33,6 +33,7 @@ // mojom::ServerSocket: void Accept(AcceptCallback callback) override; + void Disconnect(DisconnectCallback callback) override; private: void OnAccept(AcceptCallback callback,
diff --git a/device/bluetooth/server_socket_unittest.cc b/device/bluetooth/server_socket_unittest.cc index 4f54124..506dbce 100644 --- a/device/bluetooth/server_socket_unittest.cc +++ b/device/bluetooth/server_socket_unittest.cc
@@ -123,4 +123,9 @@ EXPECT_FALSE(fake_bluetooth_server_socket_->HasAcceptArgs()); } +TEST_F(ServerSocketTest, TestDisconnect) { + server_socket_->Disconnect(base::DoNothing()); + EXPECT_TRUE(fake_bluetooth_server_socket_->called_disconnect()); +} + } // namespace bluetooth
diff --git a/docs/accessibility/chromevox_on_desktop_linux.md b/docs/accessibility/chromevox_on_desktop_linux.md index 9f016cd..828b963 100644 --- a/docs/accessibility/chromevox_on_desktop_linux.md +++ b/docs/accessibility/chromevox_on_desktop_linux.md
@@ -85,9 +85,10 @@ Pick the latest version and ``` +VERSION=1.49.3.7 TMPDIR=$(mktemp -d) -gsutil cp gs://chromeos-localmirror/distfiles/espeak-ng-20180801.tar.gz $TMPDIR -tar -C $TMPDIR -xvf ~/espeak-ng/espeak-ng-20180801.tar.gz +gsutil cp gs://chromeos-localmirror/distfiles/espeak-ng-$VERSION.tar.gz $TMPDIR +tar -C $TMPDIR -xvf $TMPDIR/espeak-ng-$VERSION.tar.gz sudo mkdir -p /usr/share/chromeos-assets/speech_synthesis/espeak-ng/ sudo chown -R $(whoami) /usr/share/chromeos-assets/ cp -r $TMPDIR/espeak-ng/chrome-extension/* /usr/share/chromeos-assets/speech_synthesis/espeak-ng
diff --git a/docs/media/autoplay.md b/docs/media/autoplay.md index 3d0594a7..04ee027 100644 --- a/docs/media/autoplay.md +++ b/docs/media/autoplay.md
@@ -1,9 +1,8 @@ # Autoplay of HTMLMediaElements -Autoplay is the concept of playing media elements without user gesture. On -desktop, autoplay is always allowed. On mobile, only muted video elements are -allowed to autoplay. The autoplay logic follows -the +Autoplay is the concept of playing media elements without user gesture. The +policy that defines when autoplay is allowed is defined [here](https://www.chromium.org/audio-video/autoplay). +The autoplay logic follows the [HTML spec](https://html.spec.whatwg.org/multipage/embedded-content.html#media-elements). There are two ways of initiating autoplay:
diff --git a/extensions/browser/api/BUILD.gn b/extensions/browser/api/BUILD.gn index 1fb8850a..7777e3d 100644 --- a/extensions/browser/api/BUILD.gn +++ b/extensions/browser/api/BUILD.gn
@@ -134,12 +134,6 @@ "media_perception_private/media_perception_private_api.h", ] - # TODO(crbug/1158984): as above, remove these deps. - public_deps += [ - "//extensions/browser/api/vpn_provider", - "//extensions/browser/api/webcam_private", - ] - deps += [ "//chromeos", "//chromeos/dbus", @@ -211,6 +205,8 @@ "//extensions/browser/api/clipboard", "//extensions/browser/api/diagnostics", "//extensions/browser/api/virtual_keyboard", + "//extensions/browser/api/vpn_provider", + "//extensions/browser/api/webcam_private", ] } }
diff --git a/extensions/browser/api/vpn_provider/BUILD.gn b/extensions/browser/api/vpn_provider/BUILD.gn index 6312734c..222e86b2 100644 --- a/extensions/browser/api/vpn_provider/BUILD.gn +++ b/extensions/browser/api/vpn_provider/BUILD.gn
@@ -25,6 +25,8 @@ "//chromeos/dbus", "//chromeos/login/login_state", "//chromeos/network", + "//components/keyed_service/content", + "//content/public/browser", "//extensions/common/api", ]
diff --git a/extensions/browser/api/webcam_private/BUILD.gn b/extensions/browser/api/webcam_private/BUILD.gn index 1e24696..fb187db 100644 --- a/extensions/browser/api/webcam_private/BUILD.gn +++ b/extensions/browser/api/webcam_private/BUILD.gn
@@ -25,6 +25,8 @@ deps = [ "//chromeos/dbus/ip_peripheral", + "//extensions/browser/api", + "//extensions/browser/api/serial", "//extensions/common/api", "//mojo/public/cpp/bindings", "//services/device/public/mojom",
diff --git a/extensions/common/manifest_constants.cc b/extensions/common/manifest_constants.cc index e45815a..990d80d 100644 --- a/extensions/common/manifest_constants.cc +++ b/extensions/common/manifest_constants.cc
@@ -137,11 +137,6 @@ const char kShortName[] = "short_name"; const char kSignature[] = "signature"; const char kSockets[] = "sockets"; -const char kSpellcheck[] = "spellcheck"; -const char kSpellcheckDictionaryFormat[] = "dictionary_format"; -const char kSpellcheckDictionaryLanguage[] = "dictionary_language"; -const char kSpellcheckDictionaryLocale[] = "dictionary_locale"; -const char kSpellcheckDictionaryPath[] = "dictionary_path"; const char kStorageManagedSchema[] = "storage.managed_schema"; const char kSuggestedKey[] = "suggested_key"; const char kSystemIndicator[] = "system_indicator"; @@ -594,16 +589,6 @@ "Invalid value for 'short_name'."; const char kInvalidSignature[] = "Value 'signature' is missing or invalid."; -const char kInvalidSpellcheck[] = - "Invalid value for 'spellcheck'."; -const char kInvalidSpellcheckDictionaryFormat[] = - "Invalid value for spellcheck dictionary format."; -const char kInvalidSpellcheckDictionaryLanguage[] = - "Invalid value for spellcheck dictionary language."; -const char kInvalidSpellcheckDictionaryLocale[] = - "Invalid value for spellcheck dictionary locale."; -const char kInvalidSpellcheckDictionaryPath[] = - "Invalid value for spellcheck dictionary path."; const char kInvalidStartupOverrideURL[] = "Invalid value for overriding startup URL: '[*]'."; const char kInvalidSystemIndicator[] =
diff --git a/extensions/common/manifest_constants.h b/extensions/common/manifest_constants.h index fabc5c1d4..0a93f7c 100644 --- a/extensions/common/manifest_constants.h +++ b/extensions/common/manifest_constants.h
@@ -139,11 +139,6 @@ extern const char kShortName[]; extern const char kSignature[]; extern const char kSockets[]; -extern const char kSpellcheck[]; -extern const char kSpellcheckDictionaryFormat[]; -extern const char kSpellcheckDictionaryLanguage[]; -extern const char kSpellcheckDictionaryLocale[]; -extern const char kSpellcheckDictionaryPath[]; extern const char kStorageManagedSchema[]; extern const char kSuggestedKey[]; extern const char kSystemIndicator[]; @@ -423,11 +418,6 @@ extern const char kInvalidSearchEngineURL[]; extern const char kInvalidShortName[]; extern const char kInvalidSignature[]; -extern const char kInvalidSpellcheck[]; -extern const char kInvalidSpellcheckDictionaryFormat[]; -extern const char kInvalidSpellcheckDictionaryLanguage[]; -extern const char kInvalidSpellcheckDictionaryLocale[]; -extern const char kInvalidSpellcheckDictionaryPath[]; extern const char kInvalidStartupOverrideURL[]; extern const char kInvalidSystemIndicator[]; extern const char kInvalidTheme[];
diff --git a/gpu/command_buffer/client/webgpu_implementation.cc b/gpu/command_buffer/client/webgpu_implementation.cc index c12b382..9fa76a2 100644 --- a/gpu/command_buffer/client/webgpu_implementation.cc +++ b/gpu/command_buffer/client/webgpu_implementation.cc
@@ -136,10 +136,10 @@ TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("gpu.dawn"), "WebGPUCommandSerializer::Flush", "bytes", c2s_put_offset_); - TRACE_EVENT_FLOW_BEGIN0( - TRACE_DISABLED_BY_DEFAULT("gpu.dawn"), "DawnCommands", - (static_cast<uint64_t>(c2s_buffer_.shm_id()) << 32) + - c2s_buffer_.offset()); + TRACE_EVENT_WITH_FLOW0(TRACE_DISABLED_BY_DEFAULT("gpu.dawn"), + "DawnCommands", TRACE_EVENT_FLAG_FLOW_OUT, + (static_cast<uint64_t>(c2s_buffer_.shm_id()) << 32) + + c2s_buffer_.offset()); c2s_buffer_.Shrink(c2s_put_offset_); helper_->DawnCommands(device_client_id_, c2s_buffer_.shm_id(), @@ -415,8 +415,9 @@ #if BUILDFLAG(USE_DAWN) static uint32_t return_trace_id = 0; - TRACE_EVENT_FLOW_END0(TRACE_DISABLED_BY_DEFAULT("gpu.dawn"), - "DawnReturnCommands", return_trace_id++); + TRACE_EVENT_WITH_FLOW0(TRACE_DISABLED_BY_DEFAULT("gpu.dawn"), + "DawnReturnCommands", TRACE_EVENT_FLAG_FLOW_IN, + return_trace_id++); TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("gpu.dawn"), "WebGPUImplementation::OnGpuControlReturnData", "bytes",
diff --git a/gpu/command_buffer/service/webgpu_decoder_impl.cc b/gpu/command_buffer/service/webgpu_decoder_impl.cc index 3fd0449..233a6ff 100644 --- a/gpu/command_buffer/service/webgpu_decoder_impl.cc +++ b/gpu/command_buffer/service/webgpu_decoder_impl.cc
@@ -115,8 +115,9 @@ "WireServerCommandSerializer::Flush", "bytes", put_offset_); static uint32_t return_trace_id = 0; - TRACE_EVENT_FLOW_BEGIN0(TRACE_DISABLED_BY_DEFAULT("gpu.dawn"), - "DawnReturnCommands", return_trace_id++); + TRACE_EVENT_WITH_FLOW0(TRACE_DISABLED_BY_DEFAULT("gpu.dawn"), + "DawnReturnCommands", TRACE_EVENT_FLAG_FLOW_OUT, + return_trace_id++); client_->HandleReturnData(base::make_span(buffer_.data(), put_offset_)); put_offset_ = kDawnReturnCmdsOffset; @@ -1026,8 +1027,9 @@ return error::kOutOfBounds; } - TRACE_EVENT_FLOW_END0( + TRACE_EVENT_WITH_FLOW0( TRACE_DISABLED_BY_DEFAULT("gpu.dawn"), "DawnCommands", + TRACE_EVENT_FLAG_FLOW_IN, (static_cast<uint64_t>(commands_shm_id) << 32) + commands_shm_offset); TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("gpu.dawn"),
diff --git a/headless/test/data/protocol/emulation/screenshot-device-scale-factor-expected.txt b/headless/test/data/protocol/emulation/screenshot-device-scale-factor-expected.txt new file mode 100644 index 0000000..bdd7a42 --- /dev/null +++ b/headless/test/data/protocol/emulation/screenshot-device-scale-factor-expected.txt
@@ -0,0 +1,4 @@ +Tests screenshot with overridden device scale factor +requested url: http://example.com/ +Screenshot size: 200 x 200 +rgba @(175,175) 0,0,255,255 \ No newline at end of file
diff --git a/headless/test/data/protocol/emulation/screenshot-device-scale-factor.js b/headless/test/data/protocol/emulation/screenshot-device-scale-factor.js new file mode 100644 index 0000000..1e79d0b4 --- /dev/null +++ b/headless/test/data/protocol/emulation/screenshot-device-scale-factor.js
@@ -0,0 +1,58 @@ +// 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. + +(async function(testRunner) { + const {page, session, dp} = await testRunner.startWithFrameControl( + 'Tests screenshot with overridden device scale factor'); + + await dp.Runtime.enable(); + await dp.HeadlessExperimental.enable(); + + dp.Emulation.enable(); + await dp.Emulation.setDeviceMetricsOverride({ + deviceScaleFactor: 2, + width: 100, + height: 100, + screenHeight: 100, + screenWidth: 100, + mobile: true, + viewport: {x: 0, y: 0, width: 100, height: 100, scale: 1} + }); + + const RendererTestHelper = + await testRunner.loadScript('../helpers/renderer-test-helper.js'); + const {httpInterceptor, frameNavigationHelper, virtualTimeController} = + await (new RendererTestHelper(testRunner, dp, page)).init(); + + httpInterceptor.addResponse(`http://example.com/`, + `<!doctype html> + <html> + <meta name=viewport content="width=device-width"> + <style> + html, body { width: 100%; height: 100%; margin:0; padding:0; } + div { + width: 100%; height: 100%; margin:0; padding:0; + background-size: 100% 100%; + background-color: blue; + } + </style> + <body> + <div></div> + </body> + </html> + `); + + let ctx = await new Promise(async fulfill => { + await virtualTimeController.grantInitialTime(500, 100, + null, + async () => fulfill(await virtualTimeController.captureScreenshot()) + ); + frameNavigationHelper.navigate('http://example.com/'); + }); + // We use a screen and viewport of 100x100 DIP, which is 200 physical pixels + // due to deviceScaleFactor of 2. Make sure the screenshot is not clipped. + let rgba = ctx.getImageData(175, 175, 1, 1).data; + testRunner.log(`rgba @(175,175) ${rgba}`); + testRunner.completeTest(); +}) \ No newline at end of file
diff --git a/headless/test/headless_compositor_browsertest.cc b/headless/test/headless_compositor_browsertest.cc index c2563d2..9986738e 100644 --- a/headless/test/headless_compositor_browsertest.cc +++ b/headless/test/headless_compositor_browsertest.cc
@@ -157,5 +157,7 @@ "sanity/renderer-opacity-animation.js") HEADLESS_COMPOSITOR_TEST(ScreenshotAfterMetricsOverride, "sanity/screenshot-after-metrics-override.js") +HEADLESS_COMPOSITOR_TEST(ScreenshotDeviceScaleFactor, + "emulation/screenshot-device-scale-factor.js") } // namespace headless
diff --git a/infra/config/generated/cr-buildbucket.cfg b/infra/config/generated/cr-buildbucket.cfg index 1218a18..1eb1bd9 100644 --- a/infra/config/generated/cr-buildbucket.cfg +++ b/infra/config/generated/cr-buildbucket.cfg
@@ -8527,116 +8527,6 @@ } } builders { - name: "Linux remote_run Builder" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.fyi\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 36000 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - } - } - builders { - name: "Linux remote_run Tester" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.fyi\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 36000 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - } - } - builders { name: "Lollipop Phone Tester" swarming_host: "chromium-swarm.appspot.com" swarming_tags: "vpython:native-python-wrapper"
diff --git a/infra/config/generated/luci-milo.cfg b/infra/config/generated/luci-milo.cfg index 2764aaef..849986f 100644 --- a/infra/config/generated/luci-milo.cfg +++ b/infra/config/generated/luci-milo.cfg
@@ -5922,14 +5922,6 @@ short_name: "tst" } builders { - name: "buildbucket/luci.chromium.ci/Linux remote_run Builder" - category: "remote_run" - } - builders { - name: "buildbucket/luci.chromium.ci/Linux remote_run Tester" - category: "remote_run" - } - builders { name: "buildbucket/luci.chromium.ci/Site Isolation Android" category: "site_isolation" }
diff --git a/infra/config/generated/luci-scheduler.cfg b/infra/config/generated/luci-scheduler.cfg index 8365c1b..f5dfeb64 100644 --- a/infra/config/generated/luci-scheduler.cfg +++ b/infra/config/generated/luci-scheduler.cfg
@@ -2079,30 +2079,6 @@ } } job { - id: "Linux remote_run Builder" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium.ci" - builder: "Linux remote_run Builder" - } -} -job { - id: "Linux remote_run Tester" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium.ci" - builder: "Linux remote_run Tester" - } -} -job { id: "Lollipop Phone Tester" realm: "ci" acls { @@ -6985,7 +6961,6 @@ triggers: "Linux MSan Builder" triggers: "Linux TSan Builder" triggers: "Linux Viz" - triggers: "Linux remote_run Builder" triggers: "MSAN Release (chained origins)" triggers: "MSAN Release (no origins)" triggers: "Mac ASAN Release"
diff --git a/infra/config/subprojects/chromium/ci.star b/infra/config/subprojects/chromium/ci.star index ff34b32..b7112793 100644 --- a/infra/config/subprojects/chromium/ci.star +++ b/infra/config/subprojects/chromium/ci.star
@@ -217,7 +217,6 @@ "infra", "linux", "recipe", - "remote_run", "site_isolation", "network", "viz", @@ -2733,21 +2732,6 @@ ) ci.fyi_builder( - name = "Linux remote_run Builder", - console_view_entry = consoles.console_view_entry( - category = "remote_run", - ), -) - -ci.fyi_builder( - name = "Linux remote_run Tester", - console_view_entry = consoles.console_view_entry( - category = "remote_run", - ), - triggered_by = ["Linux remote_run Builder"], -) - -ci.fyi_builder( name = "Site Isolation Android", console_view_entry = consoles.console_view_entry( category = "site_isolation",
diff --git a/ios/chrome/app/main_application_delegate.mm b/ios/chrome/app/main_application_delegate.mm index f994d9d..a830c3d 100644 --- a/ios/chrome/app/main_application_delegate.mm +++ b/ios/chrome/app/main_application_delegate.mm
@@ -326,12 +326,10 @@ base::RecordAction( base::UserMetricsAction("IOSOpenByMainIntent")); } - - [_appState - applicationWillEnterForeground:UIApplication.sharedApplication - metricsMediator:_metricsMediator - memoryHelper:_memoryHelper]; }); + [_appState applicationWillEnterForeground:UIApplication.sharedApplication + metricsMediator:_metricsMediator + memoryHelper:_memoryHelper]; } }
diff --git a/ios/chrome/app/strings/ios_chromium_strings.grd b/ios/chrome/app/strings/ios_chromium_strings.grd index edd1fdf..9a4d2af 100644 --- a/ios/chrome/app/strings/ios_chromium_strings.grd +++ b/ios/chrome/app/strings/ios_chromium_strings.grd
@@ -190,6 +190,12 @@ <message name="IDS_IOS_DEFAULT_BROWSER_LEARN_MORE_MESSAGE" desc="Message when the user taps the addition information button in the default browser promotion modal. [iOS only]"> You can now use Chromium any time you tap links in messages, documents, and other apps. </message> + <message name="IDS_IOS_DEFAULT_BROWSER_LEARN_MORE_INSTRUCTIONS_MESSAGE" desc="Description to user about how to reach the default browser setting in their device. [iOS only]"> + To make Chromium your default: +1. Open Settings +2. Tap Default Browser App +3. Select Chromium. + </message> <message name="IDS_IOS_DISCONNECT_DIALOG_TITLE" desc="The title of the disconnect dialog [Length: 30em]."> Sign out of Chromium? </message>
diff --git a/ios/chrome/app/strings/ios_chromium_strings_grd/IDS_IOS_DEFAULT_BROWSER_LEARN_MORE_INSTRUCTIONS_MESSAGE.png.sha1 b/ios/chrome/app/strings/ios_chromium_strings_grd/IDS_IOS_DEFAULT_BROWSER_LEARN_MORE_INSTRUCTIONS_MESSAGE.png.sha1 new file mode 100644 index 0000000..84ed9a7 --- /dev/null +++ b/ios/chrome/app/strings/ios_chromium_strings_grd/IDS_IOS_DEFAULT_BROWSER_LEARN_MORE_INSTRUCTIONS_MESSAGE.png.sha1
@@ -0,0 +1 @@ +d8c0993b2c1a5c82af50aba4aefa5caf4f2b7995 \ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_google_chrome_strings.grd b/ios/chrome/app/strings/ios_google_chrome_strings.grd index b6e4558..ff5b080 100644 --- a/ios/chrome/app/strings/ios_google_chrome_strings.grd +++ b/ios/chrome/app/strings/ios_google_chrome_strings.grd
@@ -190,6 +190,12 @@ <message name="IDS_IOS_DEFAULT_BROWSER_LEARN_MORE_MESSAGE" desc="Message when the user taps the addition information button in the default browser promotion modal. [iOS only]"> You can now use Chrome any time you tap links in messages, documents, and other apps. </message> + <message name="IDS_IOS_DEFAULT_BROWSER_LEARN_MORE_INSTRUCTIONS_MESSAGE" desc="Description to user about how to reach the default browser setting in their device. [iOS only]"> + To make Chrome your default: + 1. Open Settings + 2. Tap Default Browser App + 3. Select Chrome. + </message> <message name="IDS_IOS_DISCONNECT_DIALOG_TITLE" desc="The title of the disconnect dialog [Length: 30em]."> Sign out of Chrome? </message>
diff --git a/ios/chrome/app/strings/ios_google_chrome_strings_grd/IDS_IOS_DEFAULT_BROWSER_LEARN_MORE_INSTRUCTIONS_MESSAGE.png.sha1 b/ios/chrome/app/strings/ios_google_chrome_strings_grd/IDS_IOS_DEFAULT_BROWSER_LEARN_MORE_INSTRUCTIONS_MESSAGE.png.sha1 new file mode 100644 index 0000000..84ed9a7 --- /dev/null +++ b/ios/chrome/app/strings/ios_google_chrome_strings_grd/IDS_IOS_DEFAULT_BROWSER_LEARN_MORE_INSTRUCTIONS_MESSAGE.png.sha1
@@ -0,0 +1 @@ +d8c0993b2c1a5c82af50aba4aefa5caf4f2b7995 \ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd index a352744..3a2edfff 100644 --- a/ios/chrome/app/strings/ios_strings.grd +++ b/ios/chrome/app/strings/ios_strings.grd
@@ -688,6 +688,9 @@ <message name="IDS_IOS_DEFAULT_BROWSER_MAIN_BUTTON_TEXT" desc="Text of the button that will take the user to the Settings page to configure the default browser [iOS only]"> Open Settings </message> + <message name="IDS_IOS_DEFAULT_BROWSER_REMIND_ME_LATER_BUTTON_TEXT" desc="Text of button that will show the default browser modal promo UI again at a later time. [iOS only]"> + Remind Me Later + </message> <message name="IDS_IOS_DEFAULT_BROWSER_SECONDARY_BUTTON_TEXT" desc="Text of secondary button that will dismiss the default browser modal promo UI [iOS only]"> No Thanks </message>
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_DEFAULT_BROWSER_REMIND_ME_LATER_BUTTON_TEXT.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_DEFAULT_BROWSER_REMIND_ME_LATER_BUTTON_TEXT.png.sha1 new file mode 100644 index 0000000..1b54c6dc --- /dev/null +++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_DEFAULT_BROWSER_REMIND_ME_LATER_BUTTON_TEXT.png.sha1
@@ -0,0 +1 @@ +2be6f7f0d2d54ea282942be1fac13e1ca8e6244a \ No newline at end of file
diff --git a/ios/chrome/browser/ios_chrome_main_parts.mm b/ios/chrome/browser/ios_chrome_main_parts.mm index 66ef6f54..6cb15f4 100644 --- a/ios/chrome/browser/ios_chrome_main_parts.mm +++ b/ios/chrome/browser/ios_chrome_main_parts.mm
@@ -79,12 +79,6 @@ namespace { -// If enabled local state file will have NSURLFileProtectionNone protection -// level set for NSURLFileProtectionKey key. The purpose of this feature is to -// understand if file protection interferes with "clean exit beacon" pref. -const base::Feature kRemoveProtectionFromPrefFile{ - "RemoveProtectionFromPrefFile", base::FEATURE_DISABLED_BY_DEFAULT}; - // Sets |level| value for NSURLFileProtectionKey key for the URL with given // |local_state_path|. void SetProtectionLevel(const base::FilePath& file_path, id level) { @@ -213,15 +207,11 @@ metrics::EnableExpiryChecker(::kExpiredHistogramsHashes, ::kNumExpiredHistograms); + // TODO(crbug.com/1164533): Remove code below some time after February 2021. NSString* const kRemoveProtectionFromPrefFileKey = @"RemoveProtectionFromPrefKey"; - if (base::FeatureList::IsEnabled(kRemoveProtectionFromPrefFile)) { - SetProtectionLevel(local_state_path, NSURLFileProtectionNone); - [NSUserDefaults.standardUserDefaults - setBool:YES - forKey:kRemoveProtectionFromPrefFileKey]; - } else if ([NSUserDefaults.standardUserDefaults - boolForKey:kRemoveProtectionFromPrefFileKey]) { + if ([NSUserDefaults.standardUserDefaults + boolForKey:kRemoveProtectionFromPrefFileKey]) { // Restore default protection level when user is no longer in the // experimental group. SetProtectionLevel(local_state_path,
diff --git a/ios/chrome/browser/metrics/mobile_session_shutdown_metrics_provider.mm b/ios/chrome/browser/metrics/mobile_session_shutdown_metrics_provider.mm index 50dd4c0..b23784b 100644 --- a/ios/chrome/browser/metrics/mobile_session_shutdown_metrics_provider.mm +++ b/ios/chrome/browser/metrics/mobile_session_shutdown_metrics_provider.mm
@@ -61,10 +61,10 @@ kMaxValue = SessionRestorationXte }; -// Values of the Stability.iOS.UTE.MobileSessionAppWillTerminateReceived +// Values of the Stability.iOS.UTE.MobileSessionAppWillTerminateWasReceived // histogram. These values are persisted to logs. Entries should not be // renumbered and numeric values should never be reused. -enum class MobileSessionAppWillTerminateReceived { +enum class MobileSessionAppWillTerminateWasReceived { // ApplicationWillTerminate notification was not received for this XTE. WasNotReceivedForXte = 0, // ApplicationWillTerminate notification was not received for this UTE. @@ -143,18 +143,18 @@ } // Returns value to record for -// Stability.iOS.UTE.MobileSessionAppWillTerminateReceived histogram. -MobileSessionAppWillTerminateReceived GetMobileSessionAppWillTerminateReceived( - bool has_possible_explanation) { +// Stability.iOS.UTE.MobileSessionAppWillTerminateWasReceived histogram. +MobileSessionAppWillTerminateWasReceived +GetMobileSessionAppWillTerminateWasReceived(bool has_possible_explanation) { if (!PreviousSessionInfo.sharedInstance.applicationWillTerminateWasReceived) { return has_possible_explanation - ? MobileSessionAppWillTerminateReceived::WasNotReceivedForXte - : MobileSessionAppWillTerminateReceived::WasNotReceivedForUte; + ? MobileSessionAppWillTerminateWasReceived::WasNotReceivedForXte + : MobileSessionAppWillTerminateWasReceived::WasNotReceivedForUte; } return has_possible_explanation - ? MobileSessionAppWillTerminateReceived::WasReceivedForXte - : MobileSessionAppWillTerminateReceived::WasReceivedForUte; + ? MobileSessionAppWillTerminateWasReceived::WasReceivedForXte + : MobileSessionAppWillTerminateWasReceived::WasReceivedForUte; } // Logs |type| in the shutdown type histogram. @@ -351,8 +351,8 @@ UMA_STABILITY_HISTOGRAM_ENUMERATION( "Stability.iOS.UTE.MobileSessionAppWillTerminateWasReceived", - GetMobileSessionAppWillTerminateReceived(possible_explanation), - MobileSessionAppWillTerminateReceived::kMaxValue); + GetMobileSessionAppWillTerminateWasReceived(possible_explanation), + MobileSessionAppWillTerminateWasReceived::kMaxValue); if (!possible_explanation && EnableSyntheticCrashReportsForUte() && GetApplicationContext()->GetLocalState()->GetBoolean(
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm index c5352e8..4639414 100644 --- a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm +++ b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
@@ -3639,6 +3639,8 @@ - (void)webState:(web::WebState*)webState contextMenuConfigurationForParams:(const web::ContextMenuParams&)params + previewProvider: + (UIContextMenuContentPreviewProvider)previewProvider completionHandler: (void (^)(UIContextMenuConfiguration*))completionHandler API_AVAILABLE(ios(13.0)) {
diff --git a/ios/chrome/browser/ui/main/scene_controller.mm b/ios/chrome/browser/ui/main/scene_controller.mm index fe73efe..ea407ba 100644 --- a/ios/chrome/browser/ui/main/scene_controller.mm +++ b/ios/chrome/browser/ui/main/scene_controller.mm
@@ -784,12 +784,16 @@ // the categorization of potentially interested users or if the user is // signed in. Do not show if it is determined that Chrome is already the // default browser or if the user has already seen the promo UI. + // If the user was in the experiment group that showed the Remind Me Later + // button and tapped on it, then show the promo again if now is the right + // time. BOOL isEligibleUser = IsLikelyInterestedDefaultBrowserUser() || ios::GetChromeBrowserProvider() ->GetChromeIdentityService() ->HasIdentities(); - if (!IsChromeLikelyDefaultBrowser() && - !HasUserInteractedWithFullscreenPromoBefore() && isEligibleUser) { + if ((!IsChromeLikelyDefaultBrowser() && + !HasUserInteractedWithFullscreenPromoBefore() && isEligibleUser) || + ShouldShowRemindMeLaterDefaultBrowserFullscreenPromo()) { self.sceneState.appState.shouldShowDefaultBrowserPromo = YES; } }
diff --git a/ios/chrome/browser/ui/whats_new/BUILD.gn b/ios/chrome/browser/ui/whats_new/BUILD.gn index bf94748a..0592c596 100644 --- a/ios/chrome/browser/ui/whats_new/BUILD.gn +++ b/ios/chrome/browser/ui/whats_new/BUILD.gn
@@ -8,7 +8,10 @@ "default_browser_utils.h", "default_browser_utils.mm", ] - deps = [ "//base" ] + deps = [ + "//base", + "//ios/chrome/browser/ui:feature_flags", + ] } source_set("whats_new") {
diff --git a/ios/chrome/browser/ui/whats_new/default_browser_promo_coordinator.mm b/ios/chrome/browser/ui/whats_new/default_browser_promo_coordinator.mm index b4e70a0..9fba13a0 100644 --- a/ios/chrome/browser/ui/whats_new/default_browser_promo_coordinator.mm +++ b/ios/chrome/browser/ui/whats_new/default_browser_promo_coordinator.mm
@@ -4,9 +4,11 @@ #import "ios/chrome/browser/ui/whats_new/default_browser_promo_coordinator.h" -#include "base/metrics/histogram_macros.h" +#include "base/feature_list.h" +#include "base/metrics/histogram_functions.h" #include "base/metrics/user_metrics.h" #include "base/metrics/user_metrics_action.h" +#include "ios/chrome/browser/ui/ui_feature_flags.h" #import "ios/chrome/browser/ui/whats_new/default_browser_promo_view_controller.h" #import "ios/chrome/browser/ui/whats_new/default_browser_utils.h" #import "ios/chrome/common/ui/confirmation_alert/confirmation_alert_action_handler.h" @@ -24,7 +26,8 @@ enum IOSDefaultBrowserFullscreenPromoAction { ACTION_BUTTON = 0, CANCEL = 1, - kMaxValue = CANCEL, + REMIND_ME_LATER = 2, + kMaxValue = REMIND_ME_LATER, }; } // namespace @@ -92,7 +95,17 @@ } - (void)confirmationAlertPrimaryAction { - UMA_HISTOGRAM_ENUMERATION("IOS.DefaultBrowserFullscreenPromo", ACTION_BUTTON); + if (IsInRemindMeLaterGroup()) { + if (self.defaultBrowerPromoViewController.tertiaryActionAvailable) { + [self logDefaultBrowserFullscreenPromoRemindMeHistogramForAction: + ACTION_BUTTON]; + } else { + [self logDefaultBrowserFullscreenRemindMeSecondPromoHistogramForAction: + ACTION_BUTTON]; + } + } else { + [self logDefaultBrowserFullscreenPromoHistogramForAction:ACTION_BUTTON]; + } base::RecordAction(base::UserMetricsAction( "IOS.DefaultBrowserFullscreenPromo.PrimaryActionTapped")); LogUserInteractionWithFullscreenPromo(); @@ -105,7 +118,34 @@ } - (void)confirmationAlertSecondaryAction { - UMA_HISTOGRAM_ENUMERATION("IOS.DefaultBrowserFullscreenPromo", CANCEL); + if (IsInRemindMeLaterGroup()) { + if (self.defaultBrowerPromoViewController.tertiaryActionAvailable) { + // When the "Remind Me Later" button is visible, it is the secondary + // button, while the "No Thanks" button is the tertiary button. + [self logDefaultBrowserFullscreenPromoRemindMeHistogramForAction: + REMIND_ME_LATER]; + base::RecordAction(base::UserMetricsAction( + "IOS.DefaultBrowserFullscreenPromo.RemindMeTapped")); + LogRemindMeLaterPromoActionInteraction(); + } else { + [self logDefaultBrowserFullscreenRemindMeSecondPromoHistogramForAction: + CANCEL]; + base::RecordAction(base::UserMetricsAction( + "IOS.DefaultBrowserFullscreenPromo.Dismissed")); + LogUserInteractionWithFullscreenPromo(); + } + } else { + [self logDefaultBrowserFullscreenPromoHistogramForAction:CANCEL]; + base::RecordAction( + base::UserMetricsAction("IOS.DefaultBrowserFullscreenPromo.Dismissed")); + LogUserInteractionWithFullscreenPromo(); + } + [self.handler hidePromo]; +} + +- (void)confirmationAlertTertiaryAction { + DCHECK(IsInRemindMeLaterGroup()); + [self logDefaultBrowserFullscreenPromoRemindMeHistogramForAction:CANCEL]; base::RecordAction( base::UserMetricsAction("IOS.DefaultBrowserFullscreenPromo.Dismissed")); LogUserInteractionWithFullscreenPromo(); @@ -116,7 +156,10 @@ base::RecordAction(base::UserMetricsAction( "IOS.DefaultBrowserFullscreen.PromoMoreInfoTapped")); NSString* message = - l10n_util::GetNSString(IDS_IOS_DEFAULT_BROWSER_LEARN_MORE_MESSAGE); + IsInModifiedStringsGroup() + ? l10n_util::GetNSString( + IDS_IOS_DEFAULT_BROWSER_LEARN_MORE_INSTRUCTIONS_MESSAGE) + : l10n_util::GetNSString(IDS_IOS_DEFAULT_BROWSER_LEARN_MORE_MESSAGE); self.learnMoreViewController = [[PopoverLabelViewController alloc] initWithMessage:message]; @@ -131,4 +174,21 @@ completion:nil]; } +- (void)logDefaultBrowserFullscreenPromoHistogramForAction: + (IOSDefaultBrowserFullscreenPromoAction)action { + base::UmaHistogramEnumeration("IOS.DefaultBrowserFullscreenPromo", action); +} + +- (void)logDefaultBrowserFullscreenPromoRemindMeHistogramForAction: + (IOSDefaultBrowserFullscreenPromoAction)action { + base::UmaHistogramEnumeration("IOS.DefaultBrowserFullscreenPromoRemindMe", + action); +} + +- (void)logDefaultBrowserFullscreenRemindMeSecondPromoHistogramForAction: + (IOSDefaultBrowserFullscreenPromoAction)action { + base::UmaHistogramEnumeration( + "IOS.DefaultBrowserFullscreenPromoRemindMeSecondPromo", action); +} + @end
diff --git a/ios/chrome/browser/ui/whats_new/default_browser_promo_view_controller.mm b/ios/chrome/browser/ui/whats_new/default_browser_promo_view_controller.mm index a921213..f8b2c59e 100644 --- a/ios/chrome/browser/ui/whats_new/default_browser_promo_view_controller.mm +++ b/ios/chrome/browser/ui/whats_new/default_browser_promo_view_controller.mm
@@ -6,6 +6,7 @@ #include "base/feature_list.h" #include "ios/chrome/browser/ui/ui_feature_flags.h" +#import "ios/chrome/browser/ui/whats_new/default_browser_utils.h" #include "ios/chrome/grit/ios_google_chrome_strings.h" #include "ios/chrome/grit/ios_strings.h" #include "ui/base/l10n/l10n_util_mac.h" @@ -29,12 +30,17 @@ self.showDismissBarButton = NO; self.titleString = l10n_util::GetNSString(IDS_IOS_DEFAULT_BROWSER_TITLE); self.subtitleString = - l10n_util::GetNSString(IDS_IOS_DEFAULT_BROWSER_DESCRIPTION); + IsInModifiedStringsGroup() + ? l10n_util::GetNSString(IDS_IOS_DEFAULT_BROWSER_LEARN_MORE_MESSAGE) + : l10n_util::GetNSString(IDS_IOS_DEFAULT_BROWSER_DESCRIPTION); self.primaryActionString = l10n_util::GetNSString(IDS_IOS_DEFAULT_BROWSER_MAIN_BUTTON_TEXT); - if (base::FeatureList::IsEnabled(kDefaultBrowserFullscreenPromoExperiment)) { - // TODO:(crubg.com/1155778): Add translation string. - self.secondaryActionString = @"Remind Me Later"; + if (IsInRemindMeLaterGroup() && + !ShouldShowRemindMeLaterDefaultBrowserFullscreenPromo()) { + // Show the Remind Me Later button if the user is in the correct experiment + // group and this isn't the second impression. + self.secondaryActionString = l10n_util::GetNSString( + IDS_IOS_DEFAULT_BROWSER_REMIND_ME_LATER_BUTTON_TEXT); self.tertiaryActionAvailable = YES; self.tertiaryActionString = l10n_util::GetNSString(IDS_IOS_DEFAULT_BROWSER_SECONDARY_BUTTON_TEXT); @@ -43,7 +49,6 @@ l10n_util::GetNSString(IDS_IOS_DEFAULT_BROWSER_SECONDARY_BUTTON_TEXT); } self.dismissBarButtonSystemItem = UIBarButtonSystemItemCancel; - #if defined(__IPHONE_13_4) if (@available(iOS 13.4, *)) { self.pointerInteractionEnabled = YES;
diff --git a/ios/chrome/browser/ui/whats_new/default_browser_utils.h b/ios/chrome/browser/ui/whats_new/default_browser_utils.h index a9b6efc..fe0ddcfd 100644 --- a/ios/chrome/browser/ui/whats_new/default_browser_utils.h +++ b/ios/chrome/browser/ui/whats_new/default_browser_utils.h
@@ -17,6 +17,22 @@ // past expired logs that have happened too far in the past. void LogLikelyInterestedDefaultBrowserUserActivity(); +// Logs the timestamp of a user tap on the "Remind Me Later" button in the +// Fullscreen Promo. +void LogRemindMeLaterPromoActionInteraction(); + +// Returns true if the user has tapped on the "Remind Me Later" button and the +// delay time threshold has been met. +bool ShouldShowRemindMeLaterDefaultBrowserFullscreenPromo(); + +// Returns true if the user is in the group that will be shown the Remind Me +// Later button in the fullscreen promo. +bool IsInRemindMeLaterGroup(); + +// Returns true if the user is in the group that will be shown a modified +// description and "Learn More" text. +bool IsInModifiedStringsGroup(); + // Returns true if the user has interacted with the Fullscreen Promo previously. // Returns false otherwise. bool HasUserInteractedWithFullscreenPromoBefore();
diff --git a/ios/chrome/browser/ui/whats_new/default_browser_utils.mm b/ios/chrome/browser/ui/whats_new/default_browser_utils.mm index 0150559..41b95d8 100644 --- a/ios/chrome/browser/ui/whats_new/default_browser_utils.mm +++ b/ios/chrome/browser/ui/whats_new/default_browser_utils.mm
@@ -4,7 +4,10 @@ #import "ios/chrome/browser/ui/whats_new/default_browser_utils.h" +#include "base/feature_list.h" #include "base/ios/ios_util.h" +#include "base/metrics/field_trial.h" +#include "ios/chrome/browser/ui/ui_feature_flags.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -18,12 +21,24 @@ NSString* const kUserHasInteractedWithFullscreenPromo = @"userHasInteractedWithFullscreenPromo"; +NSString* const kRemindMeLaterPromoActionInteraction = + @"remindMeLaterPromoActionInteraction"; + +const char kDefaultBrowserFullscreenPromoExperimentRemindMeGroupName[] = + "RemindMeLater"; + +const char kDefaultBrowserFullscreenPromoExperimentChangeStringsGroupName[] = + "ChangeStrings"; + // Time threshold before activity timestamps should be removed. Currently set to // seven days. const NSTimeInterval kUserActivityTimestampExpiration = 7 * 24 * 60 * 60; // Time threshold for the last URL open before no URL opens likely indicates // Chrome is no longer the default browser. const NSTimeInterval kLatestURLOpenForDefaultBrowser = 7 * 24 * 60 * 60; +// Delay for the user to be reshown the fullscreen promo when the user taps on +// the "Remind Me Later" button. 50 hours. +const NSTimeInterval kRemindMeLaterPresentationDelay = 50 * 60 * 60; } NSString* const kLastHTTPURLOpenTime = @"lastHTTPURLOpenTime"; @@ -58,6 +73,43 @@ forKey:kLastSignificantUserEvent]; } +void LogRemindMeLaterPromoActionInteraction() { + DCHECK(IsInRemindMeLaterGroup()); + [[NSUserDefaults standardUserDefaults] + setObject:[NSDate date] + forKey:kRemindMeLaterPromoActionInteraction]; +} + +bool ShouldShowRemindMeLaterDefaultBrowserFullscreenPromo() { + if (!IsInRemindMeLaterGroup()) { + return false; + } + NSDate* remindMeTimestamp = [[NSUserDefaults standardUserDefaults] + objectForKey:kRemindMeLaterPromoActionInteraction]; + if (!remindMeTimestamp) { + return false; + } + NSDate* fiftyHoursAgoDate = + [NSDate dateWithTimeIntervalSinceNow:-kRemindMeLaterPresentationDelay]; + return [remindMeTimestamp laterDate:fiftyHoursAgoDate] == fiftyHoursAgoDate; +} + +bool IsInRemindMeLaterGroup() { + return base::FeatureList::IsEnabled( + kDefaultBrowserFullscreenPromoExperiment) && + base::FieldTrialList::FindFullName( + kDefaultBrowserFullscreenPromoExperiment.name) == + kDefaultBrowserFullscreenPromoExperimentRemindMeGroupName; +} + +bool IsInModifiedStringsGroup() { + return base::FeatureList::IsEnabled( + kDefaultBrowserFullscreenPromoExperiment) && + base::FieldTrialList::FindFullName( + kDefaultBrowserFullscreenPromoExperiment.name) == + kDefaultBrowserFullscreenPromoExperimentChangeStringsGroupName; +} + bool HasUserInteractedWithFullscreenPromoBefore() { return [[NSUserDefaults standardUserDefaults] boolForKey:kUserHasInteractedWithFullscreenPromo]; @@ -67,6 +119,12 @@ [[NSUserDefaults standardUserDefaults] setBool:YES forKey:kUserHasInteractedWithFullscreenPromo]; + + if (IsInRemindMeLaterGroup()) { + // Clear any possible Remind Me Later timestamp saved. + [[NSUserDefaults standardUserDefaults] + removeObjectForKey:kRemindMeLaterPromoActionInteraction]; + } } bool IsChromeLikelyDefaultBrowser() {
diff --git a/ios/web/public/web_state_delegate.h b/ios/web/public/web_state_delegate.h index 4bcbd58..8c7e1694 100644 --- a/ios/web/public/web_state_delegate.h +++ b/ios/web/public/web_state_delegate.h
@@ -96,10 +96,12 @@ // Called when iOS13+ context menu is triggered and now it is required to // provide a UIContextMenuConfiguration to |completion_handler| to generate - // the context menu. + // the context menu. |previewProvider| is used to show a custom ViewController + // to preview the page. virtual void ContextMenuConfiguration( WebState* source, const ContextMenuParams& params, + UIContextMenuContentPreviewProvider preview_provider, void (^completion_handler)(UIContextMenuConfiguration*)) API_AVAILABLE(ios(13.0)); // Called when iOS13+ context menu is ready to be showed.
diff --git a/ios/web/public/web_state_delegate_bridge.h b/ios/web/public/web_state_delegate_bridge.h index cc15ef4..9e529a3 100644 --- a/ios/web/public/web_state_delegate_bridge.h +++ b/ios/web/public/web_state_delegate_bridge.h
@@ -84,9 +84,12 @@ // Called when iOS13+ context menu is triggered and now it is required to // provide a UIContextMenuConfiguration to |completion_handler| to generate the -// context menu. +// context menu. |previewProvider| is used to show a custom ViewController to +// preview the page. - (void)webState:(web::WebState*)webState contextMenuConfigurationForParams:(const web::ContextMenuParams&)params + previewProvider: + (UIContextMenuContentPreviewProvider)previewProvider completionHandler: (void (^)(UIContextMenuConfiguration*))completionHandler API_AVAILABLE(ios(13.0)); @@ -147,6 +150,7 @@ void ContextMenuConfiguration( WebState* source, const ContextMenuParams& params, + UIContextMenuContentPreviewProvider preview_provider, void (^completion_handler)(UIContextMenuConfiguration*)) API_AVAILABLE(ios(13.0)) override; void ContextMenuDidEnd(WebState* source, const GURL& link_url)
diff --git a/ios/web/web_state/ui/crw_context_menu_controller.mm b/ios/web/web_state/ui/crw_context_menu_controller.mm index 85e2c1f..930d43a7 100644 --- a/ios/web/web_state/ui/crw_context_menu_controller.mm +++ b/ios/web/web_state/ui/crw_context_menu_controller.mm
@@ -146,13 +146,16 @@ // delegate's methods. [interaction.view addSubview:self.highlightView]; [interaction.view addSubview:self.dismissView]; + self.highlightView.center = location; + self.dismissView.center = location; self.params.location = [self.webView convertPoint:location fromView:interaction.view]; __block UIContextMenuConfiguration* configuration; self.webState->GetDelegate()->ContextMenuConfiguration( - self.webState, self.params, ^(UIContextMenuConfiguration* conf) { + self.webState, self.params, /*preview_provider=*/nil, + ^(UIContextMenuConfiguration* conf) { configuration = conf; });
diff --git a/ios/web/web_state/ui/crw_wk_ui_handler.mm b/ios/web/web_state/ui/crw_wk_ui_handler.mm index adf24de..359a801 100644 --- a/ios/web/web_state/ui/crw_wk_ui_handler.mm +++ b/ios/web/web_state/ui/crw_wk_ui_handler.mm
@@ -210,8 +210,8 @@ web::ContextMenuParams params; params.link_url = net::GURLWithNSURL(elementInfo.linkURL); - delegate->ContextMenuConfiguration(self.webStateImpl, params, - completionHandler); + delegate->ContextMenuConfiguration( + self.webStateImpl, params, /*preview_provider=*/nil, completionHandler); } #endif // End of >iOS13 deprecated block.
diff --git a/ios/web/web_state/web_state_context_menu_bridge_unittest.mm b/ios/web/web_state/web_state_context_menu_bridge_unittest.mm index aa3e1bc..5bd7859 100644 --- a/ios/web/web_state/web_state_context_menu_bridge_unittest.mm +++ b/ios/web/web_state/web_state_context_menu_bridge_unittest.mm
@@ -31,6 +31,8 @@ - (void)webState:(web::WebState*)webState contextMenuConfigurationForParams:(const web::ContextMenuParams&)params + previewProvider: + (UIContextMenuContentPreviewProvider)previewProvider completionHandler: (void (^)(UIContextMenuConfiguration*))completionHandler API_AVAILABLE(ios(13.0)) {
diff --git a/ios/web/web_state/web_state_delegate.mm b/ios/web/web_state/web_state_delegate.mm index 3a2efa0..9ef2836 100644 --- a/ios/web/web_state/web_state_delegate.mm +++ b/ios/web/web_state/web_state_delegate.mm
@@ -87,6 +87,7 @@ void WebStateDelegate::ContextMenuConfiguration( WebState* source, const ContextMenuParams& params, + UIContextMenuContentPreviewProvider preview_provider, void (^completion_handler)(UIContextMenuConfiguration*)) API_AVAILABLE(ios(13.0)) { completion_handler(nil);
diff --git a/ios/web/web_state/web_state_delegate_bridge.mm b/ios/web/web_state/web_state_delegate_bridge.mm index eeaf5639..df64357c 100644 --- a/ios/web/web_state/web_state_delegate_bridge.mm +++ b/ios/web/web_state/web_state_delegate_bridge.mm
@@ -141,13 +141,16 @@ void WebStateDelegateBridge::ContextMenuConfiguration( WebState* source, const ContextMenuParams& params, + UIContextMenuContentPreviewProvider preview_provider, void (^completion_handler)(UIContextMenuConfiguration*)) API_AVAILABLE(ios(13.0)) { if ([delegate_ respondsToSelector:@selector (webState: - contextMenuConfigurationForParams:completionHandler:)]) { + contextMenuConfigurationForParams:previewProvider + :completionHandler:)]) { [delegate_ webState:source contextMenuConfigurationForParams:params + previewProvider:preview_provider completionHandler:completion_handler]; } else { completion_handler(nil);
diff --git a/ios/web_view/internal/cwv_web_view.mm b/ios/web_view/internal/cwv_web_view.mm index 5ca736ba..eeb140e 100644 --- a/ios/web_view/internal/cwv_web_view.mm +++ b/ios/web_view/internal/cwv_web_view.mm
@@ -524,6 +524,8 @@ - (void)webState:(web::WebState*)webState contextMenuConfigurationForParams:(const web::ContextMenuParams&)params + previewProvider: + (UIContextMenuContentPreviewProvider)previewProvider completionHandler: (void (^)(UIContextMenuConfiguration*))completionHandler API_AVAILABLE(ios(13.0)) {
diff --git a/ipc/ipc_sync_channel.cc b/ipc/ipc_sync_channel.cc index 0b558d9..4ce87905 100644 --- a/ipc/ipc_sync_channel.cc +++ b/ipc/ipc_sync_channel.cc
@@ -457,9 +457,9 @@ } base::WaitableEvent* done_event = deserializers_.back().done_event; - TRACE_EVENT_FLOW_BEGIN0("toplevel.flow", - "SyncChannel::SyncContext::TryToUnblockListener", - done_event); + TRACE_EVENT_WITH_FLOW0("toplevel.flow", + "SyncChannel::SyncContext::TryToUnblockListener", + done_event, TRACE_EVENT_FLAG_FLOW_OUT); done_event->Signal(); @@ -522,9 +522,9 @@ PendingSyncMessageQueue::iterator iter; DVLOG(1) << "Canceling pending sends"; for (iter = deserializers_.begin(); iter != deserializers_.end(); iter++) { - TRACE_EVENT_FLOW_BEGIN0("toplevel.flow", - "SyncChannel::SyncContext::CancelPendingSends", - iter->done_event); + TRACE_EVENT_WITH_FLOW0("toplevel.flow", + "SyncChannel::SyncContext::CancelPendingSends", + iter->done_event, TRACE_EVENT_FLAG_FLOW_OUT); iter->done_event->Signal(); } } @@ -644,8 +644,8 @@ scoped_refptr<mojo::SyncHandleRegistry> registry = sync_handle_registry_; WaitForReply(registry.get(), context.get(), pump_messages); - TRACE_EVENT_FLOW_END0("toplevel.flow", "SyncChannel::Send", - context->GetSendDoneEvent()); + TRACE_EVENT_WITH_FLOW0("toplevel.flow", "SyncChannel::Send", + context->GetSendDoneEvent(), TRACE_EVENT_FLAG_FLOW_IN); return context->Pop(); }
diff --git a/ipc/ipc_sync_message_filter.cc b/ipc/ipc_sync_message_filter.cc index 929f3d2..747766f 100644 --- a/ipc/ipc_sync_message_filter.cc +++ b/ipc/ipc_sync_message_filter.cc
@@ -84,8 +84,8 @@ const bool* stop_flags[] = {&done, &shutdown}; registry->Wait(stop_flags, 2); if (done) { - TRACE_EVENT_FLOW_END0("toplevel.flow", "SyncMessageFilter::Send", - &done_event); + TRACE_EVENT_WITH_FLOW0("toplevel.flow", "SyncMessageFilter::Send", + &done_event, TRACE_EVENT_FLAG_FLOW_IN); } } @@ -132,9 +132,9 @@ (*iter)->send_result = (*iter)->deserializer->SerializeOutputParameters(message); } - TRACE_EVENT_FLOW_BEGIN0("toplevel.flow", - "SyncMessageFilter::OnMessageReceived", - (*iter)->done_event); + TRACE_EVENT_WITH_FLOW0("toplevel.flow", + "SyncMessageFilter::OnMessageReceived", + (*iter)->done_event, TRACE_EVENT_FLAG_FLOW_OUT); (*iter)->done_event->Signal(); return true; } @@ -170,9 +170,9 @@ lock_.AssertAcquired(); for (PendingSyncMessages::iterator iter = pending_sync_messages_.begin(); iter != pending_sync_messages_.end(); ++iter) { - TRACE_EVENT_FLOW_BEGIN0("toplevel.flow", - "SyncMessageFilter::SignalAllEvents", - (*iter)->done_event); + TRACE_EVENT_WITH_FLOW0("toplevel.flow", + "SyncMessageFilter::SignalAllEvents", + (*iter)->done_event, TRACE_EVENT_FLAG_FLOW_OUT); (*iter)->done_event->Signal(); } }
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc index 7c394c4a..5305528 100644 --- a/media/base/media_switches.cc +++ b/media/base/media_switches.cc
@@ -498,6 +498,10 @@ const base::Feature kUseSodaForLiveCaption{"UseSodaForLiveCaption", base::FEATURE_DISABLED_BY_DEFAULT}; +// Live Caption runs system-wide on ChromeOS, as opposed to just in the browser. +const base::Feature kLiveCaptionSystemWideOnChromeOS{ + "LiveCaptionSystemWideOnChromeOS", base::FEATURE_DISABLED_BY_DEFAULT}; + // Prevents UrlProvisionFetcher from making a provisioning request. If // specified, any provisioning request made will not be sent to the provisioning // server, and the response will indicate a failure to communicate with the
diff --git a/media/base/media_switches.h b/media/base/media_switches.h index 3e11fe5c..9f17fdc1 100644 --- a/media/base/media_switches.h +++ b/media/base/media_switches.h
@@ -145,6 +145,7 @@ MEDIA_EXPORT extern const base::Feature kKaleidoscopeModule; MEDIA_EXPORT extern const base::Feature kKaleidoscopeModuleCacheOnly; MEDIA_EXPORT extern const base::Feature kLiveCaption; +MEDIA_EXPORT extern const base::Feature kLiveCaptionSystemWideOnChromeOS; MEDIA_EXPORT extern const base::Feature kLowDelayVideoRenderingOnLiveStream; MEDIA_EXPORT extern const base::Feature kMediaCapabilitiesQueryGpuFactories; MEDIA_EXPORT extern const base::Feature kMediaCapabilitiesWithParameters;
diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc index b13be4d..d715ba3 100644 --- a/media/blink/webmediaplayer_impl.cc +++ b/media/blink/webmediaplayer_impl.cc
@@ -1351,10 +1351,8 @@ if (video_frame && video_frame->HasTextures()) { if (!raster_context_provider_) return; // Unable to get/create a shared main thread context. - if (!raster_context_provider_->GrContext() && - !raster_context_provider_->ContextCapabilities().supports_oop_raster) { - return; // The context has been lost. - } + if (!raster_context_provider_->GrContext()) + return; // The context has been lost since and can't setup a GrContext. } if (out_metadata && video_frame) { // WebGL last-uploaded-frame-metadata API enabled. https://crbug.com/639174
diff --git a/media/gpu/BUILD.gn b/media/gpu/BUILD.gn index 20b9867..dcb6458 100644 --- a/media/gpu/BUILD.gn +++ b/media/gpu/BUILD.gn
@@ -548,6 +548,7 @@ sources += [ "windows/d3d11_copying_texture_wrapper_unittest.cc", "windows/d3d11_decoder_configurator_unittest.cc", + "windows/d3d11_picture_buffer_unittest.cc", "windows/d3d11_texture_selector_unittest.cc", "windows/d3d11_texture_wrapper_unittest.cc", "windows/d3d11_video_decoder_unittest.cc",
diff --git a/media/gpu/v4l2/v4l2_device.cc b/media/gpu/v4l2/v4l2_device.cc index 7a498ff..d9d3ba8 100644 --- a/media/gpu/v4l2/v4l2_device.cc +++ b/media/gpu/v4l2/v4l2_device.cc
@@ -958,8 +958,7 @@ struct v4l2_format format = BuildV4L2Format(type_, fourcc, size, buffer_size); if (device_->Ioctl(VIDIOC_S_FMT, &format) != 0 || format.fmt.pix_mp.pixelformat != fourcc) { - VPQLOGF(2) << "Failed to set format (format_fourcc=0x" << std::hex << fourcc - << ")"; + VPQLOGF(2) << "Failed to set format fourcc: " << FourccToString(fourcc); return base::nullopt; } @@ -973,8 +972,7 @@ struct v4l2_format format = BuildV4L2Format(type_, fourcc, size, buffer_size); if (device_->Ioctl(VIDIOC_TRY_FMT, &format) != 0 || format.fmt.pix_mp.pixelformat != fourcc) { - VPQLOGF(2) << "Tried format not supported (format_fourcc=0x" << std::hex - << fourcc << ")"; + VPQLOGF(2) << "Failed to try format fourcc: " << FourccToString(fourcc); return base::nullopt; }
diff --git a/media/gpu/v4l2/v4l2_video_decoder.cc b/media/gpu/v4l2/v4l2_video_decoder.cc index 6caf038..e08e331 100644 --- a/media/gpu/v4l2/v4l2_video_decoder.cc +++ b/media/gpu/v4l2/v4l2_video_decoder.cc
@@ -152,35 +152,25 @@ SetState(State::kUninitialized); } - // Open V4L2 device. - VideoCodecProfile profile = config.profile(); - uint32_t input_format_fourcc_stateless = - V4L2Device::VideoCodecProfileToV4L2PixFmt(profile, true); - if (!input_format_fourcc_stateless || - !device_->Open(V4L2Device::Type::kDecoder, - input_format_fourcc_stateless)) { - VLOGF(1) << "Failed to open device for profile: " << profile - << " fourcc: " << FourccToString(input_format_fourcc_stateless); - input_format_fourcc_stateless = 0; - } else { - VLOGF(1) << "Found V4L2 device capable of stateless decoding for " - << FourccToString(input_format_fourcc_stateless); + const VideoCodecProfile profile = config.profile(); + constexpr bool kStateful = false; + constexpr bool kStateless = true; + base::Optional<std::pair<bool, uint32_t>> api_and_format; + // Try both kStateful and kStateless APIs via |fourcc| and select the first + // combination where Open()ing the |device_| works. + for (const auto api : {kStateful, kStateless}) { + const auto fourcc = V4L2Device::VideoCodecProfileToV4L2PixFmt(profile, api); + constexpr uint32_t kInvalidV4L2PixFmt = 0; + if (fourcc == kInvalidV4L2PixFmt || + !device_->Open(V4L2Device::Type::kDecoder, fourcc)) { + continue; + } + api_and_format = std::make_pair(api, fourcc); + break; } - uint32_t input_format_fourcc_stateful = - V4L2Device::VideoCodecProfileToV4L2PixFmt(profile, false); - if (!input_format_fourcc_stateful || - !device_->Open(V4L2Device::Type::kDecoder, - input_format_fourcc_stateful)) { - VLOGF(1) << "Failed to open device for profile: " << profile - << " fourcc: " << FourccToString(input_format_fourcc_stateful); - input_format_fourcc_stateful = 0; - } else { - VLOGF(1) << "Found V4L2 device capable of stateful decoding for " - << FourccToString(input_format_fourcc_stateful); - } - - if (!input_format_fourcc_stateless && !input_format_fourcc_stateful) { + if (!api_and_format.has_value()) { + VLOGF(1) << "No V4L2 API found for profile: " << GetProfileName(profile); std::move(init_cb).Run(StatusCode::kV4l2NoDecoder); return; } @@ -206,19 +196,19 @@ return; } - uint32_t input_format_fourcc; - if (input_format_fourcc_stateful) { + const auto preferred_api_and_format = api_and_format.value(); + const uint32_t input_format_fourcc = preferred_api_and_format.second; + if (preferred_api_and_format.first == kStateful) { + VLOGF(1) << "Using a stateful API for profile: " << GetProfileName(profile) + << " and fourcc: " << FourccToString(input_format_fourcc); backend_ = std::make_unique<V4L2StatefulVideoDecoderBackend>( this, device_, profile, decoder_task_runner_); - input_format_fourcc = input_format_fourcc_stateful; - } else if (input_format_fourcc_stateless) { + } else { + DCHECK_EQ(preferred_api_and_format.first, kStateless); + VLOGF(1) << "Using a stateless API for profile: " << GetProfileName(profile) + << " and fourcc: " << FourccToString(input_format_fourcc); backend_ = std::make_unique<V4L2StatelessVideoDecoderBackend>( this, device_, profile, decoder_task_runner_); - input_format_fourcc = input_format_fourcc_stateless; - } else { - VLOGF(1) << "No backend capable of taking this profile."; - std::move(init_cb).Run(StatusCode::kV4l2FailedResourceAllocation); - return; } if (!backend_->Initialize()) { @@ -227,7 +217,6 @@ return; } - // Setup input format. if (!SetupInputFormat(input_format_fourcc)) { VLOGF(1) << "Failed to setup input format."; std::move(init_cb).Run(StatusCode::kV4l2BadFormat);
diff --git a/media/gpu/vp9_decoder.cc b/media/gpu/vp9_decoder.cc index eee5e501..bbe17de 100644 --- a/media/gpu/vp9_decoder.cc +++ b/media/gpu/vp9_decoder.cc
@@ -120,6 +120,7 @@ void VP9Decoder::Reset() { curr_frame_hdr_ = nullptr; + decrypt_config_.reset(); pending_pic_.reset(); ref_frames_.Clear(); @@ -146,12 +147,11 @@ } // Read a new frame header if one is not awaiting decoding already. - std::unique_ptr<DecryptConfig> decrypt_config; if (!curr_frame_hdr_) { gfx::Size allocate_size; std::unique_ptr<Vp9FrameHeader> hdr(new Vp9FrameHeader()); Vp9Parser::Result res = - parser_.ParseNextFrame(hdr.get(), &allocate_size, &decrypt_config); + parser_.ParseNextFrame(hdr.get(), &allocate_size, &decrypt_config_); switch (res) { case Vp9Parser::kOk: curr_frame_hdr_ = std::move(hdr); @@ -183,6 +183,7 @@ state_ = kDecoding; } else { curr_frame_hdr_.reset(); + decrypt_config_.reset(); continue; } } @@ -215,6 +216,7 @@ } curr_frame_hdr_.reset(); + decrypt_config_.reset(); continue; } @@ -267,6 +269,7 @@ } curr_frame_hdr_.reset(); + decrypt_config_.reset(); return kRanOutOfStreamData; } @@ -293,7 +296,7 @@ pic->set_visible_rect(new_render_rect); pic->set_bitstream_id(stream_id_); - pic->set_decrypt_config(std::move(decrypt_config)); + pic->set_decrypt_config(std::move(decrypt_config_)); // For VP9, container color spaces override video stream color spaces. if (container_color_space_.IsSpecified())
diff --git a/media/gpu/vp9_decoder.h b/media/gpu/vp9_decoder.h index 31dd7ce..2698e98 100644 --- a/media/gpu/vp9_decoder.h +++ b/media/gpu/vp9_decoder.h
@@ -157,8 +157,10 @@ // Current stream buffer id; to be assigned to pictures decoded from it. int32_t stream_id_ = -1; - // Current frame header to be used in decoding the next picture. + // Current frame header and decrypt config to be used in decoding the next + // picture. std::unique_ptr<Vp9FrameHeader> curr_frame_hdr_; + std::unique_ptr<DecryptConfig> decrypt_config_; // Current frame size that is necessary to decode |curr_frame_hdr_|. gfx::Size curr_frame_size_;
diff --git a/media/gpu/windows/d3d11_picture_buffer.h b/media/gpu/windows/d3d11_picture_buffer.h index 70d48fc7..8ceadaa3 100644 --- a/media/gpu/windows/d3d11_picture_buffer.h +++ b/media/gpu/windows/d3d11_picture_buffer.h
@@ -80,12 +80,19 @@ size_t picture_index() const { return picture_index_; } // Is this PictureBuffer backing a VideoFrame right now? - bool in_client_use() const { return in_client_use_; } + bool in_client_use() const { return in_client_use_ > 0; } // Is this PictureBuffer holding an image that's in use by the decoder? bool in_picture_use() const { return in_picture_use_; } - void set_in_client_use(bool use) { in_client_use_ = use; } + void add_client_use() { + in_client_use_++; + DCHECK_GT(in_client_use_, 0); + } + void remove_client_use() { + DCHECK_GT(in_client_use_, 0); + in_client_use_--; + } void set_in_picture_use(bool use) { in_picture_use_ = use; } const ComD3D11VideoDecoderOutputView& output_view() const { @@ -108,7 +115,7 @@ std::unique_ptr<Texture2DWrapper> texture_wrapper_; gfx::Size size_; bool in_picture_use_ = false; - bool in_client_use_ = false; + int in_client_use_ = 0; size_t picture_index_; ComD3D11VideoDecoderOutputView output_view_;
diff --git a/media/gpu/windows/d3d11_picture_buffer_unittest.cc b/media/gpu/windows/d3d11_picture_buffer_unittest.cc new file mode 100644 index 0000000..546dee2 --- /dev/null +++ b/media/gpu/windows/d3d11_picture_buffer_unittest.cc
@@ -0,0 +1,48 @@ +// 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 <utility> + +#include "base/callback_helpers.h" +#include "base/test/task_environment.h" +#include "media/gpu/windows/d3d11_picture_buffer.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace media { + +class D3D11PictureBufferTest : public ::testing::Test { + public: + D3D11PictureBufferTest() { + picture_buffer_ = base::MakeRefCounted<D3D11PictureBuffer>( + task_environment_.GetMainThreadTaskRunner(), nullptr, 0, nullptr, + gfx::Size(), 0); + } + + base::test::TaskEnvironment task_environment_; + + scoped_refptr<D3D11PictureBuffer> picture_buffer_; +}; + +// The processor proxy wraps the VideoDevice/VideoContext and stores some of the +// d3d11 types. Make sure that the arguments we give these methods are passed +// through correctly. +TEST_F(D3D11PictureBufferTest, InClientUse) { + EXPECT_FALSE(picture_buffer_->in_client_use()); + + // Add two client refs. + picture_buffer_->add_client_use(); + EXPECT_TRUE(picture_buffer_->in_client_use()); + picture_buffer_->add_client_use(); + EXPECT_TRUE(picture_buffer_->in_client_use()); + + // Remove them. Should still be in use by the client until the second one has + // been removed. + picture_buffer_->remove_client_use(); + EXPECT_TRUE(picture_buffer_->in_client_use()); + picture_buffer_->remove_client_use(); + EXPECT_FALSE(picture_buffer_->in_client_use()); +} + +} // namespace media \ No newline at end of file
diff --git a/media/gpu/windows/d3d11_video_decoder.cc b/media/gpu/windows/d3d11_video_decoder.cc index ac043a7..a98333e 100644 --- a/media/gpu/windows/d3d11_video_decoder.cc +++ b/media/gpu/windows/d3d11_video_decoder.cc
@@ -470,7 +470,7 @@ // We may decode into this buffer again. // Note that |buffer| might no longer be in |picture_buffers_| if we've // replaced them. That's okay. - buffer->set_in_client_use(false); + buffer->remove_client_use(); // Also re-start decoding in case it was waiting for more pictures. DoDecode(); @@ -818,7 +818,7 @@ DCHECK(texture_selector_); TRACE_EVENT0("gpu", "D3D11VideoDecoder::OutputResult"); - picture_buffer->set_in_client_use(true); + picture_buffer->add_client_use(); // Note: The pixel format doesn't matter. gfx::Rect visible_rect = picture->visible_rect();
diff --git a/media/gpu/windows/d3d11_vp9_accelerator.cc b/media/gpu/windows/d3d11_vp9_accelerator.cc index 4f8c29fb..cc0e40e 100644 --- a/media/gpu/windows/d3d11_vp9_accelerator.cc +++ b/media/gpu/windows/d3d11_vp9_accelerator.cc
@@ -63,7 +63,7 @@ D3D11PictureBuffer* picture_buffer = client_->GetPicture(); if (!picture_buffer) return nullptr; - return base::MakeRefCounted<D3D11VP9Picture>(picture_buffer); + return base::MakeRefCounted<D3D11VP9Picture>(picture_buffer, client_); } bool D3D11VP9Accelerator::BeginFrame(const D3D11VP9Picture& pic) {
diff --git a/media/gpu/windows/d3d11_vp9_picture.cc b/media/gpu/windows/d3d11_vp9_picture.cc index 5efa82b5..913fefec 100644 --- a/media/gpu/windows/d3d11_vp9_picture.cc +++ b/media/gpu/windows/d3d11_vp9_picture.cc
@@ -6,8 +6,10 @@ namespace media { -D3D11VP9Picture::D3D11VP9Picture(D3D11PictureBuffer* picture_buffer) +D3D11VP9Picture::D3D11VP9Picture(D3D11PictureBuffer* picture_buffer, + D3D11VideoDecoderClient* client) : picture_buffer_(picture_buffer), + client_(client), picture_index_(picture_buffer_->picture_index()) { picture_buffer_->set_in_picture_use(true); } @@ -16,4 +18,11 @@ picture_buffer_->set_in_picture_use(false); } +scoped_refptr<VP9Picture> D3D11VP9Picture::CreateDuplicate() { + // We've already sent off the base frame for rendering, so we can just stamp + // |picture_buffer_| with the updated timestamp. + client_->UpdateTimestamp(picture_buffer_); + return this; +} + } // namespace media
diff --git a/media/gpu/windows/d3d11_vp9_picture.h b/media/gpu/windows/d3d11_vp9_picture.h index 27b14440..68b2998 100644 --- a/media/gpu/windows/d3d11_vp9_picture.h +++ b/media/gpu/windows/d3d11_vp9_picture.h
@@ -8,6 +8,7 @@ #include "media/gpu/vp9_picture.h" #include "media/gpu/windows/d3d11_picture_buffer.h" +#include "media/gpu/windows/d3d11_video_decoder_client.h" namespace media { @@ -15,7 +16,8 @@ class D3D11VP9Picture : public VP9Picture { public: - explicit D3D11VP9Picture(D3D11PictureBuffer* picture_buffer); + explicit D3D11VP9Picture(D3D11PictureBuffer* picture_buffer, + D3D11VideoDecoderClient* client); D3D11PictureBuffer* picture_buffer() const { return picture_buffer_; } @@ -24,8 +26,11 @@ protected: ~D3D11VP9Picture() override; + scoped_refptr<VP9Picture> CreateDuplicate() override; + private: D3D11PictureBuffer* picture_buffer_; + D3D11VideoDecoderClient* client_; size_t picture_index_; };
diff --git a/media/renderers/paint_canvas_video_renderer.cc b/media/renderers/paint_canvas_video_renderer.cc index fc0ff827..f4d4428 100644 --- a/media/renderers/paint_canvas_video_renderer.cc +++ b/media/renderers/paint_canvas_video_renderer.cc
@@ -800,67 +800,28 @@ DISALLOW_IMPLICIT_CONSTRUCTORS(VideoImageGenerator); }; +// TODO(jochin): Add support for all OOP-R specific APIs (eg. GetMailbox() and +// GetSkImageViaReadback()) class VideoTextureBacking : public cc::TextureBacking { public: explicit VideoTextureBacking( sk_sp<SkImage> sk_image, - const gpu::Mailbox& mailbox, - bool wraps_video_frame_texture, scoped_refptr<viz::RasterContextProvider> raster_context_provider) - : sk_image_(std::move(sk_image)), - sk_image_info_(sk_image_->imageInfo()), - mailbox_(mailbox), - wraps_video_frame_texture_(wraps_video_frame_texture) { + : sk_image_(std::move(sk_image)) { raster_context_provider_ = std::move(raster_context_provider); } - explicit VideoTextureBacking( - const gpu::Mailbox& mailbox, - const SkImageInfo& info, - bool wraps_video_frame_texture, - scoped_refptr<viz::RasterContextProvider> raster_context_provider) - : sk_image_info_(info), - mailbox_(mailbox), - wraps_video_frame_texture_(wraps_video_frame_texture) { - raster_context_provider_ = std::move(raster_context_provider); + const SkImageInfo& GetSkImageInfo() override { + return sk_image_->imageInfo(); } - - ~VideoTextureBacking() override { - auto* ri = raster_context_provider_->RasterInterface(); - if (!wraps_video_frame_texture_) { - gpu::SyncToken sync_token; - ri->GenUnverifiedSyncTokenCHROMIUM(sync_token.GetData()); - auto* sii = raster_context_provider_->SharedImageInterface(); - sii->DestroySharedImage(sync_token, mailbox_); - } - } - - const SkImageInfo& GetSkImageInfo() override { return sk_image_info_; } gpu::Mailbox GetMailbox() const override { return mailbox_; } sk_sp<SkImage> GetAcceleratedSkImage() override { return sk_image_; } - bool wraps_video_frame_texture() const { return wraps_video_frame_texture_; } - const scoped_refptr<viz::RasterContextProvider>& raster_context_provider() - const { - return raster_context_provider_; - } - sk_sp<SkImage> GetSkImageViaReadback() override { - if (sk_image_) + if (sk_image_) { return sk_image_->makeNonTextureImage(); - - sk_sp<SkData> image_pixels = - SkData::MakeUninitialized(sk_image_info_.computeMinByteSize()); - uint8_t* writable_pixels = - static_cast<uint8_t*>(image_pixels->writable_data()); - gpu::raster::RasterInterface* ri = - raster_context_provider_->RasterInterface(); - ri->ReadbackImagePixels(mailbox_, sk_image_info_, - sk_image_info_.minRowBytes(), 0, 0, - writable_pixels); - return SkImage::MakeRasterData(sk_image_info_, std::move(image_pixels), - sk_image_info_.minRowBytes()); + } + return nullptr; } - bool readPixels(const SkImageInfo& dst_info, void* dst_pixels, size_t dst_row_bytes, @@ -870,13 +831,8 @@ return sk_image_->readPixels(dst_info, dst_pixels, dst_row_bytes, src_x, src_y); } - gpu::raster::RasterInterface* ri = - raster_context_provider_->RasterInterface(); - ri->ReadbackImagePixels(mailbox_, dst_info, dst_info.minRowBytes(), src_x, - src_y, dst_pixels); - return true; + return false; } - void FlushPendingSkiaOps() override { if (!raster_context_provider_ || !sk_image_) return; @@ -884,19 +840,9 @@ } private: - sk_sp<SkImage> sk_image_; - SkImageInfo sk_image_info_; - scoped_refptr<viz::RasterContextProvider> raster_context_provider_; - - // This can be either the source VideoFrame's texture (if - // |wraps_video_frame_texture_| is true) or a newly allocated shared image - // (if |wraps_video_frame_texture_| is false) if a copy or conversion was - // necessary. + const sk_sp<SkImage> sk_image_; const gpu::Mailbox mailbox_; - - // Whether |mailbox_| directly points to a texture of the VideoFrame - // (if true), or to an allocated shared image (if false). - const bool wraps_video_frame_texture_; + scoped_refptr<viz::RasterContextProvider> raster_context_provider_; }; PaintCanvasVideoRenderer::PaintCanvasVideoRenderer() @@ -952,11 +898,11 @@ DCHECK(image); base::Optional<ScopedSharedImageAccess> source_access; - if (video_frame->HasTextures() && cache_->source_texture) { - DCHECK(cache_->texture_backing); + if (video_frame->HasTextures()) { + DCHECK(!cache_->source_mailbox.IsZero()); + DCHECK(cache_->source_texture); source_access.emplace(raster_context_provider->RasterInterface(), - cache_->source_texture, - cache_->texture_backing->GetMailbox()); + cache_->source_texture, cache_->source_mailbox); } cc::PaintFlags video_flags; @@ -1048,9 +994,9 @@ raster_context_provider->ContextSupport()); } // Because we are not retaining a reference to the VideoFrame, it would be - // invalid for the texture_backing to directly wrap its texture(s), as they - // will be recycled. - DCHECK(!CacheBackingWrapsTexture()); + // invalid for the cache to directly wrap its texture(s), as they will be + // recycled. + DCHECK(!cache_ || !cache_->wraps_video_frame_texture); } void PaintCanvasVideoRenderer::Copy( @@ -1380,8 +1326,7 @@ if (!raster_context_provider) return false; GrDirectContext* gr_context = raster_context_provider->GrContext(); - if (!gr_context && - !raster_context_provider->ContextCapabilities().supports_oop_raster) + if (!gr_context) return false; // TODO(crbug.com/1108154): Expand this uploading path to macOS, linux // chromeOS after collecting perf data and resolve failure cases. @@ -1407,7 +1352,7 @@ } DCHECK(cache_); - DCHECK(cache_->texture_backing); + DCHECK(!cache_->source_mailbox.IsZero()); gpu::raster::RasterInterface* canvas_ri = raster_context_provider->RasterInterface(); @@ -1417,10 +1362,10 @@ canvas_ri->GenUnverifiedSyncTokenCHROMIUM(sync_token.GetData()); uint32_t intermediate_texture = SynchronizeAndImportMailbox( - destination_gl, sync_token, cache_->texture_backing->GetMailbox()); + destination_gl, sync_token, cache_->source_mailbox); { ScopedSharedImageAccess access(destination_gl, intermediate_texture, - cache_->texture_backing->GetMailbox()); + cache_->source_mailbox); VideoFrameCopyTextureOrSubTexture( destination_gl, cache_->coded_size, cache_->visible_rect, intermediate_texture, target, texture, internal_format, format, type, @@ -1438,7 +1383,7 @@ // Because we are not retaining a reference to the VideoFrame, it would be // invalid to keep the cache around if it directly wraps the VideoFrame // texture(s), as they will be recycled. - if (cache_->texture_backing->wraps_video_frame_texture()) + if (cache_->wraps_video_frame_texture) cache_.reset(); // Synchronize |video_frame| with the read operations in UpdateLastImage(), @@ -1453,7 +1398,8 @@ WaitAndReplaceSyncTokenClient client(destination_gl); video_frame->UpdateReleaseSyncToken(&client); } - DCHECK(!CacheBackingWrapsTexture()); + DCHECK(!cache_ || !cache_->wraps_video_frame_texture); + return true; } @@ -1486,7 +1432,6 @@ return false; } - // TODO(nazabris): Support OOP-R code path here that does not have GrContext. if (!raster_context_provider || !raster_context_provider->GrContext()) return false; @@ -1546,7 +1491,6 @@ return false; } - // TODO(nazabris): Support OOP-R code path here that does not have GrContext. if (!raster_context_provider || !raster_context_provider->GrContext()) return false; @@ -1584,7 +1528,7 @@ WaitAndReplaceSyncTokenClient client(source_ri); video_frame->UpdateReleaseSyncToken(&client); - DCHECK(!CacheBackingWrapsTexture()); + DCHECK(!cache_ || !cache_->wraps_video_frame_texture); return true; } @@ -1758,17 +1702,33 @@ PaintCanvasVideoRenderer::Cache::Cache(int frame_id) : frame_id(frame_id) {} -PaintCanvasVideoRenderer::Cache::~Cache() = default; +PaintCanvasVideoRenderer::Cache::~Cache() { + if (!raster_context_provider) + return; + + DCHECK(!source_mailbox.IsZero()); + DCHECK(source_texture); + auto* ri = raster_context_provider->RasterInterface(); + if (!wraps_video_frame_texture) { + gpu::SyncToken sync_token; + ri->GenUnverifiedSyncTokenCHROMIUM(sync_token.GetData()); + auto* sii = raster_context_provider->SharedImageInterface(); + sii->DestroySharedImage(sync_token, source_mailbox); + } +} bool PaintCanvasVideoRenderer::Cache::Recycle() { - DCHECK(!texture_backing->wraps_video_frame_texture()); - - paint_image = cc::PaintImage(); - if (!texture_backing->unique()) + DCHECK(!wraps_video_frame_texture); + if (!paint_image.HasExclusiveTextureAccess()) return false; // Flush any pending GPU work using this texture. - texture_backing->FlushPendingSkiaOps(); + paint_image.FlushPendingSkiaOps(); + + paint_image = cc::PaintImage(); + // We need a new texture ID because skia will destroy the previous one with + // the SkImage. + source_texture = 0; return true; } @@ -1776,9 +1736,9 @@ scoped_refptr<VideoFrame> video_frame, viz::RasterContextProvider* raster_context_provider, bool allow_wrap_texture) { - DCHECK(!CacheBackingWrapsTexture()); + DCHECK(!cache_ || !cache_->wraps_video_frame_texture); if (!cache_ || video_frame->unique_id() != cache_->frame_id || - !cache_->paint_image) { + cache_->source_mailbox.IsZero()) { auto paint_image_builder = cc::PaintImageBuilder::WithDefault() .set_id(renderer_stable_id_) @@ -1792,30 +1752,24 @@ // could cause problems since the pool of VideoFrames has a fixed size. if (video_frame->HasTextures()) { DCHECK(raster_context_provider); - bool supports_oop_raster = - raster_context_provider->ContextCapabilities().supports_oop_raster; - DCHECK(supports_oop_raster || raster_context_provider->GrContext()); + DCHECK(raster_context_provider->GrContext()); auto* ri = raster_context_provider->RasterInterface(); DCHECK(ri); - bool wraps_video_frame_texture = false; - gpu::Mailbox mailbox; if (allow_wrap_texture && video_frame->NumTextures() == 1) { cache_.emplace(video_frame->unique_id()); const gpu::MailboxHolder& holder = GetVideoFrameMailboxHolder(video_frame.get()); - mailbox = holder.mailbox; + cache_->source_mailbox = holder.mailbox; ri->WaitSyncTokenCHROMIUM(holder.sync_token.GetConstData()); - wraps_video_frame_texture = true; + cache_->wraps_video_frame_texture = true; } else { - if (cache_ && cache_->texture_backing && - cache_->texture_backing->raster_context_provider() == - raster_context_provider && + if (cache_ && + cache_->raster_context_provider == raster_context_provider && cache_->coded_size == video_frame->coded_size() && cache_->Recycle()) { // We can reuse the shared image from the previous cache. cache_->frame_id = video_frame->unique_id(); - mailbox = cache_->texture_backing->GetMailbox(); } else { cache_.emplace(video_frame->unique_id()); auto* sii = raster_context_provider->SharedImageInterface(); @@ -1823,10 +1777,11 @@ // cached shared image is created without it. uint32_t flags = gpu::SHARED_IMAGE_USAGE_GLES2 | gpu::SHARED_IMAGE_USAGE_RASTER; - if (supports_oop_raster) { + if (raster_context_provider->ContextCapabilities() + .supports_oop_raster) { flags |= gpu::SHARED_IMAGE_USAGE_OOP_RASTERIZATION; } - mailbox = sii->CreateSharedImage( + cache_->source_mailbox = sii->CreateSharedImage( viz::ResourceFormat::RGBA_8888, video_frame->coded_size(), gfx::ColorSpace(), kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType, flags, gpu::kNullSurfaceHandle); @@ -1836,55 +1791,48 @@ if (video_frame->NumTextures() == 1) { auto frame_mailbox = SynchronizeVideoFrameSingleMailbox(ri, video_frame.get()); - ri->CopySubTexture(frame_mailbox, mailbox, GL_TEXTURE_2D, 0, 0, 0, 0, - video_frame->coded_size().width(), - video_frame->coded_size().height(), GL_FALSE, - GL_FALSE); + ri->CopySubTexture( + frame_mailbox, cache_->source_mailbox, GL_TEXTURE_2D, 0, 0, 0, 0, + video_frame->coded_size().width(), + video_frame->coded_size().height(), GL_FALSE, GL_FALSE); } else { - gpu::MailboxHolder dest_holder{mailbox, gpu::SyncToken(), - GL_TEXTURE_2D}; + gpu::MailboxHolder dest_holder{cache_->source_mailbox, + gpu::SyncToken(), GL_TEXTURE_2D}; VideoFrameYUVConverter::ConvertYUVVideoFrameNoCaching( video_frame.get(), raster_context_provider, dest_holder); } - if (!supports_oop_raster) - raster_context_provider->GrContext()->flushAndSubmit(); + raster_context_provider->GrContext()->flushAndSubmit(); } + // TODO(jochin): Don't always generate SkImage here. + DCHECK(cache_->source_texture == 0); + cache_->source_texture = + ri->CreateAndConsumeForGpuRaster(cache_->source_mailbox); + + // TODO(nazabris): Handle scoped access correctly. This follows the + // current pattern but is most likely bugged. Access should last for the + // lifetime of the SkImage. + ScopedSharedImageAccess(ri, cache_->source_texture, + cache_->source_mailbox); + auto source_image = + WrapGLTexture(cache_->wraps_video_frame_texture + ? video_frame->mailbox_holder(0).texture_target + : GL_TEXTURE_2D, + cache_->source_texture, video_frame->coded_size(), + video_frame->ColorSpace(), raster_context_provider); + if (!source_image) { + // Couldn't create the SkImage. + cache_.reset(); + return false; + } + cache_->raster_context_provider = raster_context_provider; cache_->coded_size = video_frame->coded_size(); cache_->visible_rect = video_frame->visible_rect(); - if (!cache_->texture_backing) { - if (supports_oop_raster) { - SkImageInfo sk_image_info = SkImageInfo::Make( - gfx::SizeToSkISize(cache_->coded_size), kRGBA_8888_SkColorType, - kPremul_SkAlphaType, video_frame->ColorSpace().ToSkColorSpace()); - cache_->texture_backing = sk_make_sp<VideoTextureBacking>( - mailbox, sk_image_info, wraps_video_frame_texture, - raster_context_provider); - } else { - cache_->source_texture = ri->CreateAndConsumeForGpuRaster(mailbox); - // TODO(nazabris): Handle scoped access correctly. This follows the - // current pattern but is most likely bugged. Access should last for - // the lifetime of the SkImage. - ScopedSharedImageAccess(ri, cache_->source_texture, mailbox); - auto source_image = - WrapGLTexture(wraps_video_frame_texture - ? video_frame->mailbox_holder(0).texture_target - : GL_TEXTURE_2D, - cache_->source_texture, video_frame->coded_size(), - video_frame->ColorSpace(), raster_context_provider); - if (!source_image) { - // Couldn't create the SkImage. - cache_.reset(); - return false; - } - cache_->texture_backing = sk_make_sp<VideoTextureBacking>( - std::move(source_image), mailbox, wraps_video_frame_texture, - raster_context_provider); - } - } paint_image_builder.set_texture_backing( - cache_->texture_backing, cc::PaintImage::GetNextContentId()); + sk_sp<VideoTextureBacking>(new VideoTextureBacking( + std::move(source_image), raster_context_provider)), + cc::PaintImage::GetNextContentId()); } else { cache_.emplace(video_frame->unique_id()); paint_image_builder.set_paint_image_generator( @@ -1892,7 +1840,7 @@ } cache_->paint_image = paint_image_builder.TakePaintImage(); if (!cache_->paint_image) { - // Couldn't create the PaintImage. + // Couldn't create the SkImage. cache_.reset(); return false; } @@ -1955,9 +1903,4 @@ return gfx::Size(cache_->paint_image.width(), cache_->paint_image.height()); } -bool PaintCanvasVideoRenderer::CacheBackingWrapsTexture() const { - return cache_ && cache_->texture_backing && - cache_->texture_backing->wraps_video_frame_texture(); -} - } // namespace media
diff --git a/media/renderers/paint_canvas_video_renderer.h b/media/renderers/paint_canvas_video_renderer.h index 0c6b406..a422e23 100644 --- a/media/renderers/paint_canvas_video_renderer.h +++ b/media/renderers/paint_canvas_video_renderer.h
@@ -41,7 +41,6 @@ } namespace media { -class VideoTextureBacking; // Handles rendering of VideoFrames to PaintCanvases. class MEDIA_EXPORT PaintCanvasVideoRenderer { @@ -212,15 +211,22 @@ // to the visible size of the VideoFrame. Its contents are generated lazily. cc::PaintImage paint_image; - // The backing for the source texture. This is also responsible for managing - // the lifetime of the texture. - sk_sp<VideoTextureBacking> texture_backing; + // The context provider used to generate |source_mailbox| and + // |source_texture|. This is only set if the VideoFrame was texture-backed. + scoped_refptr<viz::RasterContextProvider> raster_context_provider; - // The GL texture ID used in non-OOP code path. + // The mailbox for the source texture. This can be either the source + // VideoFrame's texture (if |wraps_video_frame_texture| is true) or a newly + // allocated shared image (if |wraps_video_frame_texture| is false) if a + // copy or conversion was necessary. + // This is only set if the VideoFrame was texture-backed. + gpu::Mailbox source_mailbox; + + // The texture ID created when importing |source_mailbox|. // This is only set if the VideoFrame was texture-backed. uint32_t source_texture = 0; - // The allocated size of VideoFrame texture. + // The allocated size of |source_mailbox|. // This is only set if the VideoFrame was texture-backed. gfx::Size coded_size; @@ -229,6 +235,10 @@ // This is only set if the VideoFrame was texture-backed. gfx::Rect visible_rect; + // Whether |source_mailbox| directly points to a texture of the VideoFrame + // (if true), or to an allocated shared image (if false). + bool wraps_video_frame_texture = false; + // Used to allow recycling of the previous shared image. This requires that // no external users have access to this resource via SkImage. Returns true // if the existing resource can be recycled. @@ -256,8 +266,6 @@ unsigned int type, bool flip_y); - bool CacheBackingWrapsTexture() const; - base::Optional<Cache> cache_; // If |cache_| is not used for a while, it's deleted to save memory.
diff --git a/net/third_party/quiche/BUILD.gn b/net/third_party/quiche/BUILD.gn index f3b0b3d..082c6ae 100644 --- a/net/third_party/quiche/BUILD.gn +++ b/net/third_party/quiche/BUILD.gn
@@ -72,6 +72,8 @@ "src/http2/decoder/payload_decoders/ping_payload_decoder.h", "src/http2/decoder/payload_decoders/priority_payload_decoder.cc", "src/http2/decoder/payload_decoders/priority_payload_decoder.h", + "src/http2/decoder/payload_decoders/priority_update_payload_decoder.cc", + "src/http2/decoder/payload_decoders/priority_update_payload_decoder.h", "src/http2/decoder/payload_decoders/push_promise_payload_decoder.cc", "src/http2/decoder/payload_decoders/push_promise_payload_decoder.h", "src/http2/decoder/payload_decoders/rst_stream_payload_decoder.cc", @@ -1195,6 +1197,7 @@ "src/http2/decoder/payload_decoders/payload_decoder_base_test_util.h", "src/http2/decoder/payload_decoders/ping_payload_decoder_test.cc", "src/http2/decoder/payload_decoders/priority_payload_decoder_test.cc", + "src/http2/decoder/payload_decoders/priority_update_payload_decoder_test.cc", "src/http2/decoder/payload_decoders/push_promise_payload_decoder_test.cc", "src/http2/decoder/payload_decoders/rst_stream_payload_decoder_test.cc", "src/http2/decoder/payload_decoders/settings_payload_decoder_test.cc",
diff --git a/net/url_request/url_request.cc b/net/url_request/url_request.cc index 3c9d005..bdfc3d8 100644 --- a/net/url_request/url_request.cc +++ b/net/url_request/url_request.cc
@@ -499,6 +499,9 @@ if (status_ != OK) return; + if (context_->require_network_isolation_key()) + DCHECK(!isolation_info_.IsEmpty()); + // Some values can be NULL, but the job factory must not be. DCHECK(context_->job_factory());
diff --git a/pdf/BUILD.gn b/pdf/BUILD.gn index f78853d..759e3e5 100644 --- a/pdf/BUILD.gn +++ b/pdf/BUILD.gn
@@ -253,6 +253,7 @@ ":internal", ":ppapi_migration", "//base", + "//base:i18n", "//build:chromeos_buildflags", "//net", "//ppapi/cpp:objects",
diff --git a/pdf/out_of_process_instance.cc b/pdf/out_of_process_instance.cc index 4a4fb96..d443a21 100644 --- a/pdf/out_of_process_instance.cc +++ b/pdf/out_of_process_instance.cc
@@ -17,6 +17,7 @@ #include "base/bind.h" #include "base/callback.h" #include "base/feature_list.h" +#include "base/i18n/number_formatting.h" #include "base/location.h" #include "base/logging.h" #include "base/memory/weak_ptr.h" @@ -130,6 +131,7 @@ // Metadata (Plugin -> Page) constexpr char kJSMetadataType[] = "metadata"; constexpr char kJSMetadataData[] = "metadataData"; +constexpr char kJSVersion[] = "version"; constexpr char kJSTitle[] = "title"; constexpr char kJSAuthor[] = "author"; constexpr char kJSSubject[] = "subject"; @@ -535,6 +537,48 @@ return pp_text_runs; } +// Converts |version| to a formatted string. +base::string16 GetFormattedVersion(PdfVersion version) { + double value = 0; + switch (version) { + case PdfVersion::k1_0: + value = 1.0; + break; + case PdfVersion::k1_1: + value = 1.1; + break; + case PdfVersion::k1_2: + value = 1.2; + break; + case PdfVersion::k1_3: + value = 1.3; + break; + case PdfVersion::k1_4: + value = 1.4; + break; + case PdfVersion::k1_5: + value = 1.5; + break; + case PdfVersion::k1_6: + value = 1.6; + break; + case PdfVersion::k1_7: + value = 1.7; + break; + case PdfVersion::k2_0: + value = 2.0; + break; + case PdfVersion::kUnknown: + case PdfVersion::k1_8: // Not an actual version + return base::string16(); + } + // The default case is excluded from the above switch statement to ensure that + // all supported versions are determinantly handled. + + DCHECK_NE(0, value); + return base::FormatDouble(value, 1); +} + } // namespace OutOfProcessInstance::OutOfProcessInstance(PP_Instance instance) @@ -2381,6 +2425,10 @@ const DocumentMetadata& document_metadata = engine()->GetDocumentMetadata(); pp::VarDictionary metadata_data; + base::string16 version = GetFormattedVersion(document_metadata.version); + if (!version.empty()) + metadata_data.Set(pp::Var(kJSVersion), pp::Var(base::UTF16ToUTF8(version))); + if (!document_metadata.title.empty()) metadata_data.Set(pp::Var(kJSTitle), pp::Var(document_metadata.title));
diff --git a/remoting/protocol/webrtc_data_stream_adapter.cc b/remoting/protocol/webrtc_data_stream_adapter.cc index df52f61..2f972cc 100644 --- a/remoting/protocol/webrtc_data_stream_adapter.cc +++ b/remoting/protocol/webrtc_data_stream_adapter.cc
@@ -59,8 +59,7 @@ rtc::CopyOnWriteBuffer buffer; buffer.SetSize(message->ByteSize()); - message->SerializeWithCachedSizesToArray( - reinterpret_cast<uint8_t*>(buffer.data())); + message->SerializeWithCachedSizesToArray(buffer.MutableData()); pending_messages_.emplace( webrtc::DataBuffer(std::move(buffer), true /* binary */), std::move(done));
diff --git a/services/device/battery/android/java/src/org/chromium/device/battery/BatteryStatusManager.java b/services/device/battery/android/java/src/org/chromium/device/battery/BatteryStatusManager.java index 44c2696..4d5d3f4d 100644 --- a/services/device/battery/android/java/src/org/chromium/device/battery/BatteryStatusManager.java +++ b/services/device/battery/android/java/src/org/chromium/device/battery/BatteryStatusManager.java
@@ -15,6 +15,7 @@ import org.chromium.base.ContextUtils; import org.chromium.base.Log; +import org.chromium.base.task.AsyncTask; import org.chromium.device.mojom.BatteryStatus; /** @@ -140,10 +141,22 @@ batteryStatus.level = level; if (mAndroidBatteryManager != null) { - updateBatteryStatus(batteryStatus); + // Doing an AsyncTask since querying the BatteryManager might be slow. In the past, it + // has caused ANRs when executed on the main thread - see crbug.com/1163401. + new AsyncTask<BatteryStatus>() { + @Override + protected BatteryStatus doInBackground() { + updateBatteryStatus(batteryStatus); + return batteryStatus; + } + @Override + protected void onPostExecute(BatteryStatus batteryStatus) { + mCallback.onBatteryStatusChanged(batteryStatus); + } + }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + } else { + mCallback.onBatteryStatusChanged(batteryStatus); } - - mCallback.onBatteryStatusChanged(batteryStatus); } private void updateBatteryStatus(BatteryStatus batteryStatus) {
diff --git a/services/media_session/public/cpp/media_image_manager.cc b/services/media_session/public/cpp/media_image_manager.cc index 825c90c..73fde77 100644 --- a/services/media_session/public/cpp/media_image_manager.cc +++ b/services/media_session/public/cpp/media_image_manager.cc
@@ -88,6 +88,16 @@ } } + // If we haven't found an image based on size then we should check if there + // are any images that have an "any" size which is denoted by a single empty + // gfx::Size value. + if (!selected.has_value()) { + for (auto& image : images) { + if (image.sizes.size() == 1 && image.sizes[0].IsEmpty()) + return image; + } + } + return selected; }
diff --git a/services/media_session/public/cpp/media_image_manager_unittest.cc b/services/media_session/public/cpp/media_image_manager_unittest.cc index 9c8d0189..dceed3b 100644 --- a/services/media_session/public/cpp/media_image_manager_unittest.cc +++ b/services/media_session/public/cpp/media_image_manager_unittest.cc
@@ -204,4 +204,17 @@ EXPECT_EQ(image1, manager()->SelectImage(images)); } +TEST_F(MediaImageManagerTest, PickImageWithAnySize) { + MediaImageManager manager(10, 10); + + std::vector<MediaImage> images; + + // Empty size denotes "any" value. + MediaImage image; + image.sizes.push_back(gfx::Size()); + images.push_back(image); + + EXPECT_TRUE(manager.SelectImage(images)); +} + } // namespace media_session
diff --git a/services/network/network_context.cc b/services/network/network_context.cc index 238fc37..afaf375 100644 --- a/services/network/network_context.cc +++ b/services/network/network_context.cc
@@ -33,6 +33,7 @@ #include "build/chromecast_buildflags.h" #include "build/chromeos_buildflags.h" #include "components/cookie_config/cookie_store_util.h" +#include "components/domain_reliability/features.h" #include "components/domain_reliability/monitor.h" #include "components/network_session_configurator/browser/network_session_configurator.h" #include "components/network_session_configurator/common/network_switches.h" @@ -42,6 +43,7 @@ #include "components/prefs/pref_service_factory.h" #include "crypto/sha2.h" #include "mojo/public/cpp/bindings/pending_receiver.h" +#include "net/base/features.h" #include "net/base/load_flags.h" #include "net/base/net_errors.h" #include "net/base/network_delegate.h" @@ -853,7 +855,7 @@ const net::NetworkIsolationKey& network_isolation_key, const base::Optional<std::string>& user_agent, base::Value body) { - if (url_request_context_->require_network_isolation_key()) + if (require_network_isolation_key_) DCHECK(!network_isolation_key.IsEmpty()); DCHECK(body.is_dict()); @@ -885,7 +887,7 @@ void NetworkContext::QueueSignedExchangeReport( mojom::SignedExchangeReportPtr report, const net::NetworkIsolationKey& network_isolation_key) { - if (url_request_context_->require_network_isolation_key()) + if (require_network_isolation_key_) DCHECK(!network_isolation_key.IsEmpty()); net::NetworkErrorLoggingService* logging_service = @@ -1387,7 +1389,7 @@ const std::string& ocsp_result, const std::string& sct_list, VerifyCertForSignedExchangeCallback callback) { - if (url_request_context_->require_network_isolation_key()) + if (require_network_isolation_key_) DCHECK(!network_isolation_key.IsEmpty()); int cert_verify_id = ++next_cert_verify_id_; @@ -2193,8 +2195,29 @@ auto result = URLRequestContextOwner(std::move(pref_service), builder.Build()); - result.url_request_context->set_require_network_isolation_key( - params_->require_network_isolation_key); + require_network_isolation_key_ = params_->require_network_isolation_key; + + // If `require_network_isolation_key_` is true, but the features that can + // trigger another URLRequest are not set to respect NetworkIsolationKeys, + // the URLRequests that they create might not have a NIK, so only set the + // corresponding value in the URLRequestContext to true at the URLRequest + // layer if all those features are set to respect NIK. + if (require_network_isolation_key_ && + base::FeatureList::IsEnabled( + net::features::kPartitionConnectionsByNetworkIsolationKey) && + base::FeatureList::IsEnabled( + net::features::kPartitionExpectCTStateByNetworkIsolationKey) && + base::FeatureList::IsEnabled( + net::features::kPartitionHttpServerPropertiesByNetworkIsolationKey) && + base::FeatureList::IsEnabled( + net::features::kPartitionNelAndReportingByNetworkIsolationKey) && + base::FeatureList::IsEnabled( + net::features::kPartitionSSLSessionsByNetworkIsolationKey) && + base::FeatureList::IsEnabled( + domain_reliability::features:: + kPartitionDomainReliabilityByNetworkIsolationKey)) { + result.url_request_context->set_require_network_isolation_key(true); + } // Subscribe the CertVerifier to configuration changes that are exposed via // the mojom::SSLConfig, but which are not part of the
diff --git a/services/network/network_context.h b/services/network/network_context.h index 022b586d..90391023 100644 --- a/services/network/network_context.h +++ b/services/network/network_context.h
@@ -529,6 +529,10 @@ return &cors_origin_access_list_; } + bool require_network_isolation_key() const { + return require_network_isolation_key_; + } + private: URLRequestContextOwner MakeURLRequestContext( mojo::PendingRemote<mojom::URLLoaderFactory> @@ -758,6 +762,11 @@ // manages the lifetiem of a WebBundleURLLoaderFactory object. WebBundleManager web_bundle_manager_; + // Whether all external consumers are expected to provide a non-empty + // NetworkIsolationKey with all requests. When set, enabled a variety of + // DCHECKs on APIs used by external callers. + bool require_network_isolation_key_ = false; + base::WeakPtrFactory<NetworkContext> weak_factory_{this}; DISALLOW_COPY_AND_ASSIGN(NetworkContext);
diff --git a/services/network/public/cpp/data_element.cc b/services/network/public/cpp/data_element.cc index 32879fe..db8d7309 100644 --- a/services/network/public/cpp/data_element.cc +++ b/services/network/public/cpp/data_element.cc
@@ -28,11 +28,10 @@ DataElement::DataElement(DataElement&& other) = default; DataElement& DataElement::operator=(DataElement&& other) = default; -void DataElement::SetToFilePathRange( - const base::FilePath& path, - uint64_t offset, - uint64_t length, - const base::Time& expected_modification_time) { +void DataElement::SetToFilePathRange(const base::FilePath& path, + uint64_t offset, + uint64_t length, + base::Time expected_modification_time) { type_ = mojom::DataElementType::kFile; path_ = path; offset_ = offset;
diff --git a/services/network/public/cpp/data_element.h b/services/network/public/cpp/data_element.h index 7eeb277b..1e4d1e8 100644 --- a/services/network/public/cpp/data_element.h +++ b/services/network/public/cpp/data_element.h
@@ -75,29 +75,11 @@ length_ = buf_.size(); } - // Sets TYPE_BYTES data, and clears the internal bytes buffer. - // For use with AppendBytes. - void SetToEmptyBytes() { - type_ = mojom::DataElementType::kBytes; - buf_.clear(); - length_ = 0; - } - - // Copies and appends the given data into the element. SetToEmptyBytes or - // SetToBytes must be called before this method. - void AppendBytes(const char* bytes, int bytes_len) { - DCHECK_EQ(type_, mojom::DataElementType::kBytes); - DCHECK_NE(length_, std::numeric_limits<uint64_t>::max()); - buf_.insert(buf_.end(), reinterpret_cast<const uint8_t*>(bytes), - reinterpret_cast<const uint8_t*>(bytes + bytes_len)); - length_ = buf_.size(); - } - // Sets TYPE_FILE data with range. void SetToFilePathRange(const base::FilePath& path, uint64_t offset, uint64_t length, - const base::Time& expected_modification_time); + base::Time expected_modification_time); // Sets TYPE_DATA_PIPE data. The data pipe consumer can safely wait for the // callback passed to Read() to be invoked before reading the request body.
diff --git a/services/network/public/cpp/is_potentially_trustworthy.cc b/services/network/public/cpp/is_potentially_trustworthy.cc index 87a5005..3dacd3c 100644 --- a/services/network/public/cpp/is_potentially_trustworthy.cc +++ b/services/network/public/cpp/is_potentially_trustworthy.cc
@@ -199,6 +199,27 @@ return false; } +bool IsSchemeConsideredAuthenticated(base::StringPiece scheme) { + // The code below is based on the specification at + // https://w3c.github.io/webappsec-secure-contexts/#potentially-trustworthy-origin + + // 7. If origin’s scheme component is one which the user agent considers to be + // authenticated, return "Potentially Trustworthy". + // Note: See §7.1 Packaged Applications for detail here. + // + // Note that this ignores some schemes that are considered trustworthy by + // higher layers (e.g. see GetSchemesBypassingSecureContextCheck in //chrome). + // + // See also + // - content::ContentClient::AddAdditionalSchemes and + // content::ContentClient::Schemes::local_schemes and + // content::ContentClient::Schemes::secure_schemes + // - url::AddLocalScheme + // - url::AddSecureScheme + return base::Contains(url::GetSecureSchemes(), scheme) || + base::Contains(url::GetLocalSchemes(), scheme); +} + } // namespace bool IsOriginPotentiallyTrustworthy(const url::Origin& origin) { @@ -228,27 +249,16 @@ // 6. If origin’s scheme component is file, return "Potentially Trustworthy". // - // This is somewhat redundant with the GetLocalSchemes-based check below. + // This is somewhat redundant with the GetLocalSchemes-based + // IsSchemeConsideredAuthenticated check below. if (origin.scheme() == url::kFileScheme) return true; // 7. If origin’s scheme component is one which the user agent considers to be // authenticated, return "Potentially Trustworthy". // Note: See §7.1 Packaged Applications for detail here. - // - // Note that this ignores some schemes that are considered trustworthy by - // higher layers (e.g. see GetSchemesBypassingSecureContextCheck in //chrome). - // - // See also - // - content::ContentClient::AddAdditionalSchemes and - // content::ContentClient::Schemes::local_schemes and - // content::ContentClient::Schemes::secure_schemes - // - url::AddLocalScheme - // - url::AddSecureScheme - if (base::Contains(url::GetSecureSchemes(), origin.scheme()) || - base::Contains(url::GetLocalSchemes(), origin.scheme())) { + if (IsSchemeConsideredAuthenticated(origin.scheme())) return true; - } // 8. If origin has been configured as a trustworthy origin, return // "Potentially Trustworthy". @@ -278,7 +288,15 @@ // Note: The origin of blob: and filesystem: URLs is the origin of the // context in which they were created. Therefore, blobs created in a // trustworthy origin will themselves be potentially trustworthy. - return IsOriginPotentiallyTrustworthy(url::Origin::Create(url)); + url::Origin origin = url::Origin::Create(url); + if (origin.opaque() && IsSchemeConsideredAuthenticated(url.scheme_piece())) { + // Authenticated schemes should be treated as trustworthy, even if they + // translate into an opaque origin (e.g. because some of them might also be + // registered as a no-access, like the //content-layer chrome-error:// or + // the //chrome-layer chrome-native://). + return true; + } + return IsOriginPotentiallyTrustworthy(origin); } // static
diff --git a/services/network/public/cpp/is_potentially_trustworthy_unittest.cc b/services/network/public/cpp/is_potentially_trustworthy_unittest.cc index 2b72d8fb..0f595fa2 100644 --- a/services/network/public/cpp/is_potentially_trustworthy_unittest.cc +++ b/services/network/public/cpp/is_potentially_trustworthy_unittest.cc
@@ -66,7 +66,7 @@ EXPECT_TRUE(IsUrlPotentiallyTrustworthy("about:srcdoc#ref")); EXPECT_TRUE(IsUrlPotentiallyTrustworthy("about:srcdoc?x=2#ref")); - EXPECT_FALSE(IsUrlPotentiallyTrustworthy("about:about")); + EXPECT_TRUE(IsUrlPotentiallyTrustworthy("about:mumble")); EXPECT_TRUE(IsUrlPotentiallyTrustworthy("data:test/plain;blah")); EXPECT_FALSE(IsUrlPotentiallyTrustworthy("javascript:alert('blah')")); @@ -151,37 +151,39 @@ IsUrlPotentiallyTrustworthy("quic-transport://example.com/counter")); } -// Tests the trustworthiness of an URL and origin whose scheme was added to the -// custom sets of standard and secure schemes. A scheme must be added to both -// to be considered trustworthy. -TEST(IsPotentiallyTrustworthy, CustomScheme) { - const char* custom_scheme = "custom-scheme"; - const char* custom_scheme_example = "custom-scheme://example.com"; +TEST(IsPotentiallyTrustworthy, CustomSchemes) { + url::ScopedSchemeRegistryForTests scoped_registry; + url::AddSecureScheme("sec-nonstd-scheme"); + url::AddSecureScheme("sec-std-scheme"); + url::AddStandardScheme("sec-std-scheme", url::SCHEME_WITH_HOST); + url::AddSecureScheme("sec-noaccess-scheme"); + url::AddNoAccessScheme("sec-noaccess-scheme"); + url::AddNoAccessScheme("nonsec-noaccess-scheme"); - EXPECT_FALSE(IsOriginPotentiallyTrustworthy(custom_scheme_example)); - EXPECT_FALSE(IsUrlPotentiallyTrustworthy(custom_scheme_example)); + // Unrecognized / unknown schemes are not trustworthy. + EXPECT_FALSE(IsOriginPotentiallyTrustworthy("unknown-scheme://example.com")); + EXPECT_FALSE(IsUrlPotentiallyTrustworthy("unknown-scheme://example.com")); - { - url::ScopedSchemeRegistryForTests scoped_registry; - url::AddSecureScheme(custom_scheme); - EXPECT_FALSE(IsOriginPotentiallyTrustworthy(custom_scheme_example)); - EXPECT_FALSE(IsUrlPotentiallyTrustworthy(custom_scheme_example)); - } + // Secure URLs are trustworthy, even if their scheme is also marked as + // no-access, or are not marked as standard. See also //chrome-layer + // ChromeContentClientTest.AdditionalSchemes test and + // https://crbug.com/734581. + EXPECT_TRUE(IsUrlPotentiallyTrustworthy("sec-nonstd-scheme://blah/x.js")); + EXPECT_TRUE(IsUrlPotentiallyTrustworthy("sec-std-scheme://blah/x.js")); + EXPECT_TRUE(IsUrlPotentiallyTrustworthy("sec-noaccess-scheme://blah/x.js")); + EXPECT_TRUE(IsOriginPotentiallyTrustworthy("sec-std-scheme://blah/x.js")); + // No-access and non-standard/non-local schemes translate into an + // untrustworthy, opaque origin. + // TODO(lukasza): Maybe if the spec had a notion of an origin *precursor*, + // then it could inspect the scheme of the precursor. After this, it may be + // possible to EXPECT_TRUE below... + EXPECT_FALSE(IsOriginPotentiallyTrustworthy("sec-nonstd-scheme://blah/x.js")); + EXPECT_FALSE( + IsOriginPotentiallyTrustworthy("sec-noaccess-scheme://blah/x.js")); - { - url::ScopedSchemeRegistryForTests scoped_registry; - url::AddStandardScheme(custom_scheme, url::SchemeType::SCHEME_WITH_HOST); - EXPECT_FALSE(IsOriginPotentiallyTrustworthy(custom_scheme_example)); - EXPECT_FALSE(IsUrlPotentiallyTrustworthy(custom_scheme_example)); - } - - { - url::ScopedSchemeRegistryForTests scoped_registry; - url::AddStandardScheme(custom_scheme, url::SchemeType::SCHEME_WITH_HOST); - url::AddSecureScheme(custom_scheme); - EXPECT_TRUE(IsOriginPotentiallyTrustworthy(custom_scheme_example)); - EXPECT_TRUE(IsUrlPotentiallyTrustworthy(custom_scheme_example)); - } + // No-access, non-secure schemes are untrustworthy. + EXPECT_FALSE(IsUrlPotentiallyTrustworthy("nonsec-noaccess-scheme:blah")); + EXPECT_FALSE(IsOriginPotentiallyTrustworthy("nonsec-noaccess-scheme:blah")); } // Tests that were for the removed blink::network_utils::IsOriginSecure.
diff --git a/services/network/url_loader.cc b/services/network/url_loader.cc index f33e95c..ad66e31 100644 --- a/services/network/url_loader.cc +++ b/services/network/url_loader.cc
@@ -461,6 +461,7 @@ mojom::CrossOriginEmbedderPolicyReporter* coep_reporter, uint32_t request_id, int keepalive_request_size, + bool require_network_isolation_key, scoped_refptr<ResourceSchedulerClient> resource_scheduler_client, base::WeakPtr<KeepaliveStatisticsRecorder> keepalive_statistics_recorder, base::WeakPtr<NetworkUsageAccumulator> network_usage_accumulator, @@ -561,7 +562,7 @@ origin, origin, net::SiteForCookies())); } - if (url_request_context_->require_network_isolation_key()) + if (require_network_isolation_key) DCHECK(!url_request_->isolation_info().IsEmpty()); if (factory_params_->disable_secure_dns) {
diff --git a/services/network/url_loader.h b/services/network/url_loader.h index 600dd2f..1937335 100644 --- a/services/network/url_loader.h +++ b/services/network/url_loader.h
@@ -105,6 +105,10 @@ // have the |obey_origin_policy| flag set. // |trust_token_helper_factory| must be non-null exactly when the request has // Trust Tokens parameters. + // + // TODO(mmenke): This parameter list is getting a bit excessive. Either pass + // in a struct, or just pass in a pointer to the NetworkContext or + // URLLoaderFactory directly. URLLoader( net::URLRequestContext* url_request_context, mojom::NetworkServiceClient* network_service_client, @@ -120,6 +124,7 @@ mojom::CrossOriginEmbedderPolicyReporter* reporter, uint32_t request_id, int keepalive_request_size, + bool require_network_isolation_key, scoped_refptr<ResourceSchedulerClient> resource_scheduler_client, base::WeakPtr<KeepaliveStatisticsRecorder> keepalive_statistics_recorder, base::WeakPtr<NetworkUsageAccumulator> network_usage_accumulator,
diff --git a/services/network/url_loader_factory.cc b/services/network/url_loader_factory.cc index 9d75573..adf7d7e 100644 --- a/services/network/url_loader_factory.cc +++ b/services/network/url_loader_factory.cc
@@ -292,7 +292,8 @@ std::move(data_pipe_use_tracker), static_cast<net::NetworkTrafficAnnotationTag>(traffic_annotation), params_.get(), coep_reporter_ ? coep_reporter_.get() : nullptr, - request_id, keepalive_request_size, resource_scheduler_client_, + request_id, keepalive_request_size, + context_->require_network_isolation_key(), resource_scheduler_client_, std::move(keepalive_statistics_recorder), std::move(network_usage_accumulator), header_client_.is_bound() ? header_client_.get() : nullptr,
diff --git a/services/network/url_loader_unittest.cc b/services/network/url_loader_unittest.cc index 31ae172..da9ed8f 100644 --- a/services/network/url_loader_unittest.cc +++ b/services/network/url_loader_unittest.cc
@@ -612,10 +612,11 @@ client_.CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, - nullptr /* network_usage_accumulator */, nullptr /* header_client */, - nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, - nullptr /* origin_access_list */, + 0 /* keepalive_request_size */, + false /* require_network_isolation_key */, resource_scheduler_client(), + nullptr, nullptr /* network_usage_accumulator */, + nullptr /* header_client */, nullptr /* origin_policy_manager */, + nullptr /* trust_token_helper */, nullptr /* origin_access_list */, mojo::NullRemote() /* cookie_observer */); ran_ = true; @@ -1551,7 +1552,8 @@ client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, nullptr /* origin_access_list */, @@ -1609,7 +1611,8 @@ client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, nullptr /* origin_access_list */, @@ -1668,7 +1671,8 @@ loader.BindNewPipeAndPassReceiver(), 0, request, client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, nullptr /* origin_access_list */, @@ -1749,7 +1753,8 @@ loader.BindNewPipeAndPassReceiver(), 0, request, client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, nullptr /* origin_access_list */, @@ -1819,7 +1824,8 @@ loader.BindNewPipeAndPassReceiver(), 0, request, client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, nullptr /* origin_access_list */, @@ -1884,7 +1890,8 @@ loader.BindNewPipeAndPassReceiver(), 0, request, client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, nullptr /* origin_access_list */, @@ -2140,7 +2147,8 @@ loader.BindNewPipeAndPassReceiver(), 0, request, client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, nullptr /* origin_access_list */, @@ -2271,7 +2279,8 @@ loader.BindNewPipeAndPassReceiver(), 0, request, client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, nullptr /* resource_scheduler_client */, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + nullptr /* resource_scheduler_client */, nullptr /* keepalive_statistics_reporter */, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, @@ -2322,7 +2331,8 @@ loader.BindNewPipeAndPassReceiver(), 0, request, client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, nullptr /* resource_scheduler_client */, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + nullptr /* resource_scheduler_client */, nullptr /* keepalive_statistics_reporter */, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, @@ -2435,7 +2445,8 @@ /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, nullptr /* origin_access_list */, @@ -2468,9 +2479,8 @@ loader.BindNewPipeAndPassReceiver(), mojom::kURLLoadOptionNone, request, client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, - /*coep_reporter=*/nullptr, - - 0 /* request_id */, 0 /* keepalive_request_size */, + /*coep_reporter=*/nullptr, 0 /* request_id */, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, @@ -2529,10 +2539,11 @@ client.CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, - nullptr /* network_usage_accumulator */, nullptr /* header_client */, - nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, - nullptr /* origin_access_list */, + 0 /* keepalive_request_size */, + false /* require_network_isolation_key */, resource_scheduler_client(), + nullptr, nullptr /* network_usage_accumulator */, + nullptr /* header_client */, nullptr /* origin_policy_manager */, + nullptr /* trust_token_helper */, nullptr /* origin_access_list */, mojo::NullRemote() /* cookie_observer */); client.RunUntilRedirectReceived(); @@ -2572,7 +2583,8 @@ client.CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, nullptr /* origin_access_list */, @@ -2629,7 +2641,8 @@ client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, nullptr /* origin_access_list */, @@ -2676,7 +2689,8 @@ client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, nullptr /* origin_access_list */, @@ -2727,7 +2741,8 @@ client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, nullptr /* origin_access_list */, @@ -2782,7 +2797,8 @@ client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, nullptr /* origin_access_list */, @@ -2846,7 +2862,8 @@ client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, nullptr /* origin_access_list */, @@ -2917,7 +2934,8 @@ /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, nullptr /* origin_access_list */, @@ -2954,7 +2972,8 @@ /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, nullptr /* origin_access_list */, @@ -3060,10 +3079,11 @@ client.CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, - nullptr /* network_usage_accumulator */, nullptr /* header_client */, - nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, - nullptr /* origin_access_list */, + 0 /* keepalive_request_size */, + false /* require_network_isolation_key */, resource_scheduler_client(), + nullptr, nullptr /* network_usage_accumulator */, + nullptr /* header_client */, nullptr /* origin_policy_manager */, + nullptr /* trust_token_helper */, nullptr /* origin_access_list */, mojo::NullRemote() /* cookie_observer */); loaders.emplace_back( @@ -3086,7 +3106,8 @@ client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, nullptr /* origin_access_list */, @@ -3128,7 +3149,8 @@ /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, nullptr /* origin_access_list */, @@ -3525,7 +3547,8 @@ client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, nullptr /* origin_access_list */, @@ -3573,7 +3596,8 @@ client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, nullptr /* origin_access_list */, @@ -3621,7 +3645,8 @@ client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, nullptr /* origin_access_list */, @@ -3670,7 +3695,8 @@ client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, nullptr /* origin_access_list */, @@ -3718,7 +3744,8 @@ client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, nullptr /* origin_access_list */, @@ -3763,7 +3790,8 @@ client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, nullptr /* origin_access_list */, @@ -3808,7 +3836,8 @@ client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, nullptr /* origin_access_list */, @@ -3848,7 +3877,8 @@ /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, nullptr /* origin_access_list */, @@ -3954,7 +3984,8 @@ client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, nullptr /* origin_access_list */, @@ -4008,7 +4039,8 @@ loader.BindNewPipeAndPassReceiver(), 0, request, client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, nullptr /* origin_access_list */, @@ -4053,7 +4085,8 @@ loader.BindNewPipeAndPassReceiver(), 0, request, client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, nullptr /* origin_access_list */, @@ -4098,7 +4131,8 @@ client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, nullptr /* origin_access_list */, @@ -4152,7 +4186,8 @@ client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, nullptr /* origin_access_list */, @@ -4211,7 +4246,8 @@ client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, nullptr /* origin_access_list */, @@ -4272,7 +4308,8 @@ client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, nullptr /* origin_access_list */, @@ -4314,7 +4351,8 @@ mojom::kURLLoadOptionBlockAllCookies, request, client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, nullptr /* origin_access_list */, @@ -4346,7 +4384,8 @@ client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, nullptr /* origin_access_list */, @@ -4378,7 +4417,8 @@ /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, nullptr /* origin_access_list */, @@ -4434,7 +4474,8 @@ client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, nullptr /* origin_access_list */, @@ -4492,7 +4533,8 @@ client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, nullptr /* origin_access_list */, @@ -4552,7 +4594,8 @@ client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, nullptr /* origin_access_list */, @@ -4589,10 +4632,11 @@ /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, 0 /* keepalive_request_size */, - resource_scheduler_client(), nullptr, - nullptr /* network_usage_accumulator */, nullptr /* header_client */, - nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, - nullptr /* origin_access_list */, cookie_observer.GetRemote()); + false /* require_network_isolation_key */, resource_scheduler_client(), + nullptr, nullptr /* network_usage_accumulator */, + nullptr /* header_client */, nullptr /* origin_policy_manager */, + nullptr /* trust_token_helper */, nullptr /* origin_access_list */, + cookie_observer.GetRemote()); delete_run_loop.Run(); loader_client.RunUntilComplete(); @@ -4623,10 +4667,11 @@ /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, 0 /* keepalive_request_size */, - resource_scheduler_client(), nullptr, - nullptr /* network_usage_accumulator */, nullptr /* header_client */, - nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, - nullptr /* origin_access_list */, cookie_observer.GetRemote()); + false /* require_network_isolation_key */, resource_scheduler_client(), + nullptr, nullptr /* network_usage_accumulator */, + nullptr /* header_client */, nullptr /* origin_policy_manager */, + nullptr /* trust_token_helper */, nullptr /* origin_access_list */, + cookie_observer.GetRemote()); delete_run_loop.Run(); loader_client.RunUntilComplete(); @@ -4663,7 +4708,8 @@ loader_client.CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, nullptr /* origin_access_list */, cookie_observer.GetRemote()); @@ -4709,10 +4755,11 @@ /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, 0 /* keepalive_request_size */, - resource_scheduler_client(), nullptr, - nullptr /* network_usage_accumulator */, nullptr /* header_client */, - nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, - nullptr /* origin_access_list */, cookie_observer.GetRemote()); + false /* require_network_isolation_key */, resource_scheduler_client(), + nullptr, nullptr /* network_usage_accumulator */, + nullptr /* header_client */, nullptr /* origin_policy_manager */, + nullptr /* trust_token_helper */, nullptr /* origin_access_list */, + cookie_observer.GetRemote()); loader_client.RunUntilComplete(); delete_run_loop.Run(); @@ -4756,10 +4803,10 @@ /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, 0 /* keepalive_request_size */, - resource_scheduler_client(), nullptr, - nullptr /* network_usage_accumulator */, nullptr /* header_client */, - nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, - nullptr /* origin_access_list */, + false /* require_network_isolation_key */, resource_scheduler_client(), + nullptr, nullptr /* network_usage_accumulator */, + nullptr /* header_client */, nullptr /* origin_policy_manager */, + nullptr /* trust_token_helper */, nullptr /* origin_access_list */, mojo::NullRemote() /* cookie_observer */); delete_run_loop.Run(); @@ -4810,10 +4857,10 @@ /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, 0 /* keepalive_request_size */, - resource_scheduler_client(), nullptr, - nullptr /* network_usage_accumulator */, nullptr /* header_client */, - nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, - nullptr /* origin_access_list */, + false /* require_network_isolation_key */, resource_scheduler_client(), + nullptr, nullptr /* network_usage_accumulator */, + nullptr /* header_client */, nullptr /* origin_policy_manager */, + nullptr /* trust_token_helper */, nullptr /* origin_access_list */, mojo::NullRemote() /* cookie_observer */); delete_run_loop.Run(); @@ -4856,10 +4903,10 @@ /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, 0 /* keepalive_request_size */, - resource_scheduler_client(), nullptr, - nullptr /* network_usage_accumulator */, nullptr /* header_client */, - nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, - nullptr /* origin_access_list */, + false /* require_network_isolation_key */, resource_scheduler_client(), + nullptr, nullptr /* network_usage_accumulator */, + nullptr /* header_client */, nullptr /* origin_policy_manager */, + nullptr /* trust_token_helper */, nullptr /* origin_access_list */, mojo::NullRemote() /* cookie_observer */); delete_run_loop.Run(); @@ -4906,10 +4953,10 @@ /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, 0 /* keepalive_request_size */, - resource_scheduler_client(), nullptr, - nullptr /* network_usage_accumulator */, nullptr /* header_client */, - nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, - nullptr /* origin_access_list */, + false /* require_network_isolation_key */, resource_scheduler_client(), + nullptr, nullptr /* network_usage_accumulator */, + nullptr /* header_client */, nullptr /* origin_policy_manager */, + nullptr /* trust_token_helper */, nullptr /* origin_access_list */, mojo::NullRemote() /* cookie_observer */); delete_run_loop.Run(); @@ -4955,10 +5002,11 @@ /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, - nullptr /* network_usage_accumulator */, nullptr /* header_client */, - nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, - nullptr /* origin_access_list */, + 0 /* keepalive_request_size */, + false /* require_network_isolation_key */, resource_scheduler_client(), + nullptr, nullptr /* network_usage_accumulator */, + nullptr /* header_client */, nullptr /* origin_policy_manager */, + nullptr /* trust_token_helper */, nullptr /* origin_access_list */, mojo::NullRemote() /* cookie_observer */); loader_client.RunUntilRedirectReceived(); @@ -5010,10 +5058,11 @@ /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, - nullptr /* network_usage_accumulator */, nullptr /* header_client */, - nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, - nullptr /* origin_access_list */, + 0 /* keepalive_request_size */, + false /* require_network_isolation_key */, resource_scheduler_client(), + nullptr, nullptr /* network_usage_accumulator */, + nullptr /* header_client */, nullptr /* origin_policy_manager */, + nullptr /* trust_token_helper */, nullptr /* origin_access_list */, mojo::NullRemote() /* cookie_observer */); loader_client.RunUntilRedirectReceived(); @@ -5060,10 +5109,10 @@ /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, 0 /* keepalive_request_size */, - resource_scheduler_client(), nullptr, - nullptr /* network_usage_accumulator */, nullptr /* header_client */, - nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, - nullptr /* origin_access_list */, + false /* require_network_isolation_key */, resource_scheduler_client(), + nullptr, nullptr /* network_usage_accumulator */, + nullptr /* header_client */, nullptr /* origin_policy_manager */, + nullptr /* trust_token_helper */, nullptr /* origin_access_list */, mojo::NullRemote() /* cookie_observer */); loader_client.RunUntilComplete(); @@ -5108,10 +5157,10 @@ /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, 0 /* keepalive_request_size */, - resource_scheduler_client(), nullptr, - nullptr /* network_usage_accumulator */, nullptr /* header_client */, - nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, - nullptr /* origin_access_list */, + false /* require_network_isolation_key */, resource_scheduler_client(), + nullptr, nullptr /* network_usage_accumulator */, + nullptr /* header_client */, nullptr /* origin_policy_manager */, + nullptr /* trust_token_helper */, nullptr /* origin_access_list */, mojo::NullRemote() /* cookie_observer */); loader_client.RunUntilComplete(); @@ -5153,10 +5202,10 @@ /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, 0 /* keepalive_request_size */, - resource_scheduler_client(), nullptr, - nullptr /* network_usage_accumulator */, nullptr /* header_client */, - nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, - nullptr /* origin_access_list */, + false /* require_network_isolation_key */, resource_scheduler_client(), + nullptr, nullptr /* network_usage_accumulator */, + nullptr /* header_client */, nullptr /* origin_policy_manager */, + nullptr /* trust_token_helper */, nullptr /* origin_access_list */, mojo::NullRemote() /* cookie_observer */); delete_run_loop.Run(); @@ -5210,10 +5259,11 @@ /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, 0 /* keepalive_request_size */, - resource_scheduler_client(), nullptr, - nullptr /* network_usage_accumulator */, nullptr /* header_client */, - nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, - nullptr /* origin_access_list */, cookie_observer.GetRemote()); + false /* require_network_isolation_key */, resource_scheduler_client(), + nullptr, nullptr /* network_usage_accumulator */, + nullptr /* header_client */, nullptr /* origin_policy_manager */, + nullptr /* trust_token_helper */, nullptr /* origin_access_list */, + cookie_observer.GetRemote()); delete_run_loop.Run(); loader_client.RunUntilComplete(); @@ -5267,10 +5317,11 @@ /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, 0 /* keepalive_request_size */, - resource_scheduler_client(), nullptr, - nullptr /* network_usage_accumulator */, nullptr /* header_client */, - nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, - nullptr /* origin_access_list */, cookie_observer.GetRemote()); + false /* require_network_isolation_key */, resource_scheduler_client(), + nullptr, nullptr /* network_usage_accumulator */, + nullptr /* header_client */, nullptr /* origin_policy_manager */, + nullptr /* trust_token_helper */, nullptr /* origin_access_list */, + cookie_observer.GetRemote()); delete_run_loop.Run(); loader_client.RunUntilComplete(); @@ -5311,10 +5362,11 @@ /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, 0 /* keepalive_request_size */, - resource_scheduler_client(), nullptr, - nullptr /* network_usage_accumulator */, nullptr /* header_client */, - nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, - nullptr /* origin_access_list */, cookie_observer.GetRemote()); + false /* require_network_isolation_key */, resource_scheduler_client(), + nullptr, nullptr /* network_usage_accumulator */, + nullptr /* header_client */, nullptr /* origin_policy_manager */, + nullptr /* trust_token_helper */, nullptr /* origin_access_list */, + cookie_observer.GetRemote()); delete_run_loop.Run(); loader_client.RunUntilComplete(); @@ -5405,10 +5457,11 @@ /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, - nullptr /* network_usage_accumulator */, nullptr /* header_client */, - &mock_origin_policy_manager, nullptr /* trust_token_helper */, - nullptr /* origin_access_list */, + 0 /* keepalive_request_size */, + false /* require_network_isolation_key */, resource_scheduler_client(), + nullptr, nullptr /* network_usage_accumulator */, + nullptr /* header_client */, &mock_origin_policy_manager, + nullptr /* trust_token_helper */, nullptr /* origin_access_list */, mojo::NullRemote() /* cookie_observer */); loader_client.RunUntilComplete(); @@ -5460,10 +5513,11 @@ /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, - nullptr /* network_usage_accumulator */, nullptr /* header_client */, - &mock_origin_policy_manager, nullptr /* trust_token_helper */, - nullptr /* origin_access_list */, + 0 /* keepalive_request_size */, + false /* require_network_isolation_key */, resource_scheduler_client(), + nullptr, nullptr /* network_usage_accumulator */, + nullptr /* header_client */, &mock_origin_policy_manager, + nullptr /* trust_token_helper */, nullptr /* origin_access_list */, mojo::NullRemote() /* cookie_observer */); loader_client.RunUntilComplete(); @@ -5502,10 +5556,11 @@ /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, - nullptr /* network_usage_accumulator */, nullptr /* header_client */, - &mock_origin_policy_manager, nullptr /* trust_token_helper */, - nullptr /* origin_access_list */, + 0 /* keepalive_request_size */, + false /* require_network_isolation_key */, resource_scheduler_client(), + nullptr, nullptr /* network_usage_accumulator */, + nullptr /* header_client */, &mock_origin_policy_manager, + nullptr /* trust_token_helper */, nullptr /* origin_access_list */, mojo::NullRemote() /* cookie_observer */); loader_client.RunUntilResponseBodyArrived(); @@ -5550,10 +5605,11 @@ /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, - nullptr /* network_usage_accumulator */, nullptr /* header_client */, - &mock_origin_policy_manager, nullptr /* trust_token_helper */, - nullptr /* origin_access_list */, + 0 /* keepalive_request_size */, + false /* require_network_isolation_key */, resource_scheduler_client(), + nullptr, nullptr /* network_usage_accumulator */, + nullptr /* header_client */, &mock_origin_policy_manager, + nullptr /* trust_token_helper */, nullptr /* origin_access_list */, mojo::NullRemote() /* cookie_observer */); loader_client.RunUntilComplete(); @@ -5845,7 +5901,8 @@ client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, std::make_unique<MockTrustTokenRequestHelperFactory>( @@ -5902,7 +5959,8 @@ client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, std::make_unique<MockTrustTokenRequestHelperFactory>( @@ -5947,7 +6005,8 @@ client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, std::make_unique<MockTrustTokenRequestHelperFactory>( @@ -5992,7 +6051,8 @@ client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, std::make_unique<MockTrustTokenRequestHelperFactory>( @@ -6036,7 +6096,8 @@ client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, std::make_unique<MockTrustTokenRequestHelperFactory>( @@ -6084,7 +6145,8 @@ client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, nullptr /* origin_access_list */, @@ -6133,7 +6195,8 @@ client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, nullptr /* origin_access_list */, @@ -6174,7 +6237,8 @@ client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt, TRAFFIC_ANNOTATION_FOR_TESTS, ¶ms, /*coep_reporter=*/nullptr, 0 /* request_id */, - 0 /* keepalive_request_size */, resource_scheduler_client(), nullptr, + 0 /* keepalive_request_size */, false /* require_network_isolation_key */, + resource_scheduler_client(), nullptr, nullptr /* network_usage_accumulator */, nullptr /* header_client */, nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */, nullptr /* origin_access_list */,
diff --git a/services/network/websocket.cc b/services/network/websocket.cc index 525a2c5..66406b29 100644 --- a/services/network/websocket.cc +++ b/services/network/websocket.cc
@@ -432,10 +432,6 @@ reassemble_short_messages_(base::FeatureList::IsEnabled( network::features::kWebSocketReassembleShortMessages)) { DCHECK(handshake_client_); - // If |require_network_isolation_key| is set on the URLRequestContext, - // |isolation_info| must not be empty. - DCHECK(!factory_->GetURLRequestContext()->require_network_isolation_key() || - !isolation_info.IsEmpty()); // |delay| should be zero if this connection is not throttled. DCHECK(pending_connection_tracker.has_value() || delay.is_zero()); if (auth_handler_) {
diff --git a/services/network/websocket_factory.cc b/services/network/websocket_factory.cc index 2ac4e3b..6cd881c 100644 --- a/services/network/websocket_factory.cc +++ b/services/network/websocket_factory.cc
@@ -48,6 +48,11 @@ return; } + // If |require_network_isolation_key| is set, |isolation_info| must not be + // empty. + if (context_->require_network_isolation_key()) + DCHECK(!isolation_info.IsEmpty()); + if (throttler_.HasTooManyPendingConnections(process_id)) { // Too many websockets! mojo::Remote<mojom::WebSocketHandshakeClient> handshake_client_remote(
diff --git a/services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.cc b/services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.cc index 79899d6..8b4fea1 100644 --- a/services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.cc +++ b/services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.cc
@@ -133,6 +133,8 @@ return ChromeThreadDescriptor::THREAD_MAIN; } else if (base::MatchPattern(thread_name, "Chrome*IOThread")) { return ChromeThreadDescriptor::THREAD_IO; + } else if (base::MatchPattern(thread_name, "NetworkService")) { + return ChromeThreadDescriptor::THREAD_NETWORK_SERVICE; } else if (base::MatchPattern(thread_name, "ThreadPoolForegroundWorker*")) { return ChromeThreadDescriptor::THREAD_POOL_FG_WORKER; } else if (base::MatchPattern(thread_name, "ThreadPoolBackgroundWorker*")) {
diff --git a/services/viz/public/cpp/gpu/context_provider_command_buffer.cc b/services/viz/public/cpp/gpu/context_provider_command_buffer.cc index 2a37d497..3e02b19 100644 --- a/services/viz/public/cpp/gpu/context_provider_command_buffer.cc +++ b/services/viz/public/cpp/gpu/context_provider_command_buffer.cc
@@ -377,8 +377,8 @@ class GrDirectContext* ContextProviderCommandBuffer::GrContext() { DCHECK(bind_tried_); DCHECK_EQ(bind_result_, gpu::ContextResult::kSuccess); - if (!support_grcontext_ || !ContextSupport()->HasGrContextSupport()) - return nullptr; + DCHECK(support_grcontext_); + DCHECK(ContextSupport()->HasGrContextSupport()); CheckValidThreadOrLockAcquired(); if (gr_context_)
diff --git a/testing/buildbot/chrome.json b/testing/buildbot/chrome.json index 7aa778f5b..d84809b 100644 --- a/testing/buildbot/chrome.json +++ b/testing/buildbot/chrome.json
@@ -67,7 +67,7 @@ ] }, "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "shards": 4 }, "test": "chrome_all_tast_tests", "test_id_prefix": "ninja://chromeos:chrome_all_tast_tests/" @@ -287,7 +287,7 @@ ] }, "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "shards": 4 }, "test": "chrome_all_tast_tests", "test_id_prefix": "ninja://chromeos:chrome_all_tast_tests/" @@ -1333,7 +1333,7 @@ ] }, "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "shards": 4 }, "test": "chrome_all_tast_tests", "test_id_prefix": "ninja://chromeos:chrome_all_tast_tests/" @@ -2379,7 +2379,7 @@ ] }, "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "shards": 4 }, "test": "chrome_all_tast_tests", "test_id_prefix": "ninja://chromeos:chrome_all_tast_tests/" @@ -3425,7 +3425,7 @@ ] }, "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "shards": 4 }, "test": "chrome_all_tast_tests", "test_id_prefix": "ninja://chromeos:chrome_all_tast_tests/" @@ -4471,7 +4471,7 @@ ] }, "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "shards": 4 }, "test": "chrome_all_tast_tests", "test_id_prefix": "ninja://chromeos:chrome_all_tast_tests/" @@ -5389,7 +5389,7 @@ ], "idempotent": false, "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "shards": 4 }, "test": "chrome_all_tast_tests", "test_id_prefix": "ninja://chromeos:chrome_all_tast_tests/", @@ -5541,7 +5541,7 @@ ], "idempotent": false, "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "shards": 4 }, "test": "chrome_all_tast_tests", "test_id_prefix": "ninja://chromeos:chrome_all_tast_tests/", @@ -5693,7 +5693,7 @@ ], "idempotent": false, "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "shards": 4 }, "test": "chrome_all_tast_tests", "test_id_prefix": "ninja://chromeos:chrome_all_tast_tests/", @@ -5845,7 +5845,7 @@ ], "idempotent": false, "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "shards": 4 }, "test": "chrome_all_tast_tests", "test_id_prefix": "ninja://chromeos:chrome_all_tast_tests/", @@ -5997,7 +5997,7 @@ ], "idempotent": false, "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "shards": 4 }, "test": "chrome_all_tast_tests", "test_id_prefix": "ninja://chromeos:chrome_all_tast_tests/", @@ -6149,7 +6149,7 @@ ], "idempotent": false, "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "shards": 4 }, "test": "chrome_all_tast_tests", "test_id_prefix": "ninja://chromeos:chrome_all_tast_tests/", @@ -6233,7 +6233,7 @@ ], "idempotent": false, "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "shards": 4 }, "test": "chrome_all_tast_tests", "test_id_prefix": "ninja://chromeos:chrome_all_tast_tests/", @@ -6317,7 +6317,7 @@ ], "idempotent": false, "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "shards": 4 }, "test": "chrome_all_tast_tests", "test_id_prefix": "ninja://chromeos:chrome_all_tast_tests/", @@ -6401,7 +6401,7 @@ ], "idempotent": false, "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "shards": 4 }, "test": "chrome_all_tast_tests", "test_id_prefix": "ninja://chromeos:chrome_all_tast_tests/", @@ -6485,7 +6485,7 @@ ], "idempotent": false, "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "shards": 4 }, "test": "chrome_all_tast_tests", "test_id_prefix": "ninja://chromeos:chrome_all_tast_tests/",
diff --git a/testing/buildbot/chromium.android.fyi.json b/testing/buildbot/chromium.android.fyi.json index 403b3d5..c5ede94 100644 --- a/testing/buildbot/chromium.android.fyi.json +++ b/testing/buildbot/chromium.android.fyi.json
@@ -240,11 +240,11 @@ "--bucket", "chromium-result-details", "--test-name", - "weblayer_instrumentation_test_versions_apk_Client Tests For 87.0.4280.147" + "weblayer_instrumentation_test_versions_apk_Client Tests For 87.0.4280.148" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py" }, - "name": "weblayer_instrumentation_test_versions_apk_Client Tests For 87.0.4280.147", + "name": "weblayer_instrumentation_test_versions_apk_Client Tests For 87.0.4280.148", "resultdb": { "enable": true }, @@ -254,7 +254,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M87", - "revision": "version:87.0.4280.147" + "revision": "version:87.0.4280.148" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -317,11 +317,11 @@ "--bucket", "chromium-result-details", "--test-name", - "weblayer_instrumentation_test_versions_apk_Client Tests For 88.0.4324.84" + "weblayer_instrumentation_test_versions_apk_Client Tests For 88.0.4324.85" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py" }, - "name": "weblayer_instrumentation_test_versions_apk_Client Tests For 88.0.4324.84", + "name": "weblayer_instrumentation_test_versions_apk_Client Tests For 88.0.4324.85", "resultdb": { "enable": true }, @@ -331,7 +331,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M88", - "revision": "version:88.0.4324.84" + "revision": "version:88.0.4324.85" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -394,11 +394,11 @@ "--bucket", "chromium-result-details", "--test-name", - "weblayer_instrumentation_test_versions_apk_Implementation Tests For 87.0.4280.147" + "weblayer_instrumentation_test_versions_apk_Implementation Tests For 87.0.4280.148" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py" }, - "name": "weblayer_instrumentation_test_versions_apk_Implementation Tests For 87.0.4280.147", + "name": "weblayer_instrumentation_test_versions_apk_Implementation Tests For 87.0.4280.148", "resultdb": { "enable": true }, @@ -408,7 +408,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M87", - "revision": "version:87.0.4280.147" + "revision": "version:87.0.4280.148" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -471,11 +471,11 @@ "--bucket", "chromium-result-details", "--test-name", - "weblayer_instrumentation_test_versions_apk_Implementation Tests For 88.0.4324.84" + "weblayer_instrumentation_test_versions_apk_Implementation Tests For 88.0.4324.85" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py" }, - "name": "weblayer_instrumentation_test_versions_apk_Implementation Tests For 88.0.4324.84", + "name": "weblayer_instrumentation_test_versions_apk_Implementation Tests For 88.0.4324.85", "resultdb": { "enable": true }, @@ -485,7 +485,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M88", - "revision": "version:88.0.4324.84" + "revision": "version:88.0.4324.85" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -769,11 +769,11 @@ "--bucket", "chromium-result-details", "--test-name", - "weblayer_instrumentation_test_versions_apk_Client Tests For 87.0.4280.147" + "weblayer_instrumentation_test_versions_apk_Client Tests For 87.0.4280.148" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py" }, - "name": "weblayer_instrumentation_test_versions_apk_Client Tests For 87.0.4280.147", + "name": "weblayer_instrumentation_test_versions_apk_Client Tests For 87.0.4280.148", "resultdb": { "enable": true }, @@ -783,7 +783,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M87", - "revision": "version:87.0.4280.147" + "revision": "version:87.0.4280.148" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -846,11 +846,11 @@ "--bucket", "chromium-result-details", "--test-name", - "weblayer_instrumentation_test_versions_apk_Client Tests For 88.0.4324.84" + "weblayer_instrumentation_test_versions_apk_Client Tests For 88.0.4324.85" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py" }, - "name": "weblayer_instrumentation_test_versions_apk_Client Tests For 88.0.4324.84", + "name": "weblayer_instrumentation_test_versions_apk_Client Tests For 88.0.4324.85", "resultdb": { "enable": true }, @@ -860,7 +860,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M88", - "revision": "version:88.0.4324.84" + "revision": "version:88.0.4324.85" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -923,11 +923,11 @@ "--bucket", "chromium-result-details", "--test-name", - "weblayer_instrumentation_test_versions_apk_Implementation Tests For 87.0.4280.147" + "weblayer_instrumentation_test_versions_apk_Implementation Tests For 87.0.4280.148" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py" }, - "name": "weblayer_instrumentation_test_versions_apk_Implementation Tests For 87.0.4280.147", + "name": "weblayer_instrumentation_test_versions_apk_Implementation Tests For 87.0.4280.148", "resultdb": { "enable": true }, @@ -937,7 +937,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M87", - "revision": "version:87.0.4280.147" + "revision": "version:87.0.4280.148" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -1000,11 +1000,11 @@ "--bucket", "chromium-result-details", "--test-name", - "weblayer_instrumentation_test_versions_apk_Implementation Tests For 88.0.4324.84" + "weblayer_instrumentation_test_versions_apk_Implementation Tests For 88.0.4324.85" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py" }, - "name": "weblayer_instrumentation_test_versions_apk_Implementation Tests For 88.0.4324.84", + "name": "weblayer_instrumentation_test_versions_apk_Implementation Tests For 88.0.4324.85", "resultdb": { "enable": true }, @@ -1014,7 +1014,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M88", - "revision": "version:88.0.4324.84" + "revision": "version:88.0.4324.85" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -1298,11 +1298,11 @@ "--bucket", "chromium-result-details", "--test-name", - "weblayer_instrumentation_test_versions_apk_Client Tests For 87.0.4280.147" + "weblayer_instrumentation_test_versions_apk_Client Tests For 87.0.4280.148" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py" }, - "name": "weblayer_instrumentation_test_versions_apk_Client Tests For 87.0.4280.147", + "name": "weblayer_instrumentation_test_versions_apk_Client Tests For 87.0.4280.148", "resultdb": { "enable": true }, @@ -1312,7 +1312,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M87", - "revision": "version:87.0.4280.147" + "revision": "version:87.0.4280.148" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -1375,11 +1375,11 @@ "--bucket", "chromium-result-details", "--test-name", - "weblayer_instrumentation_test_versions_apk_Client Tests For 88.0.4324.84" + "weblayer_instrumentation_test_versions_apk_Client Tests For 88.0.4324.85" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py" }, - "name": "weblayer_instrumentation_test_versions_apk_Client Tests For 88.0.4324.84", + "name": "weblayer_instrumentation_test_versions_apk_Client Tests For 88.0.4324.85", "resultdb": { "enable": true }, @@ -1389,7 +1389,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M88", - "revision": "version:88.0.4324.84" + "revision": "version:88.0.4324.85" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -1452,11 +1452,11 @@ "--bucket", "chromium-result-details", "--test-name", - "weblayer_instrumentation_test_versions_apk_Implementation Tests For 87.0.4280.147" + "weblayer_instrumentation_test_versions_apk_Implementation Tests For 87.0.4280.148" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py" }, - "name": "weblayer_instrumentation_test_versions_apk_Implementation Tests For 87.0.4280.147", + "name": "weblayer_instrumentation_test_versions_apk_Implementation Tests For 87.0.4280.148", "resultdb": { "enable": true }, @@ -1466,7 +1466,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M87", - "revision": "version:87.0.4280.147" + "revision": "version:87.0.4280.148" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -1529,11 +1529,11 @@ "--bucket", "chromium-result-details", "--test-name", - "weblayer_instrumentation_test_versions_apk_Implementation Tests For 88.0.4324.84" + "weblayer_instrumentation_test_versions_apk_Implementation Tests For 88.0.4324.85" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py" }, - "name": "weblayer_instrumentation_test_versions_apk_Implementation Tests For 88.0.4324.84", + "name": "weblayer_instrumentation_test_versions_apk_Implementation Tests For 88.0.4324.85", "resultdb": { "enable": true }, @@ -1543,7 +1543,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M88", - "revision": "version:88.0.4324.84" + "revision": "version:88.0.4324.85" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -1827,11 +1827,11 @@ "--bucket", "chromium-result-details", "--test-name", - "weblayer_instrumentation_test_versions_apk_Client Tests For 87.0.4280.147" + "weblayer_instrumentation_test_versions_apk_Client Tests For 87.0.4280.148" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py" }, - "name": "weblayer_instrumentation_test_versions_apk_Client Tests For 87.0.4280.147", + "name": "weblayer_instrumentation_test_versions_apk_Client Tests For 87.0.4280.148", "resultdb": { "enable": true }, @@ -1841,7 +1841,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M87", - "revision": "version:87.0.4280.147" + "revision": "version:87.0.4280.148" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -1904,11 +1904,11 @@ "--bucket", "chromium-result-details", "--test-name", - "weblayer_instrumentation_test_versions_apk_Client Tests For 88.0.4324.84" + "weblayer_instrumentation_test_versions_apk_Client Tests For 88.0.4324.85" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py" }, - "name": "weblayer_instrumentation_test_versions_apk_Client Tests For 88.0.4324.84", + "name": "weblayer_instrumentation_test_versions_apk_Client Tests For 88.0.4324.85", "resultdb": { "enable": true }, @@ -1918,7 +1918,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M88", - "revision": "version:88.0.4324.84" + "revision": "version:88.0.4324.85" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -1981,11 +1981,11 @@ "--bucket", "chromium-result-details", "--test-name", - "weblayer_instrumentation_test_versions_apk_Implementation Tests For 87.0.4280.147" + "weblayer_instrumentation_test_versions_apk_Implementation Tests For 87.0.4280.148" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py" }, - "name": "weblayer_instrumentation_test_versions_apk_Implementation Tests For 87.0.4280.147", + "name": "weblayer_instrumentation_test_versions_apk_Implementation Tests For 87.0.4280.148", "resultdb": { "enable": true }, @@ -1995,7 +1995,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M87", - "revision": "version:87.0.4280.147" + "revision": "version:87.0.4280.148" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -2058,11 +2058,11 @@ "--bucket", "chromium-result-details", "--test-name", - "weblayer_instrumentation_test_versions_apk_Implementation Tests For 88.0.4324.84" + "weblayer_instrumentation_test_versions_apk_Implementation Tests For 88.0.4324.85" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py" }, - "name": "weblayer_instrumentation_test_versions_apk_Implementation Tests For 88.0.4324.84", + "name": "weblayer_instrumentation_test_versions_apk_Implementation Tests For 88.0.4324.85", "resultdb": { "enable": true }, @@ -2072,7 +2072,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M88", - "revision": "version:88.0.4324.84" + "revision": "version:88.0.4324.85" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json index 422168a..c89a5238 100644 --- a/testing/buildbot/chromium.chromiumos.json +++ b/testing/buildbot/chromium.chromiumos.json
@@ -232,7 +232,7 @@ ] }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "shards": 4 }, "test": "chrome_all_tast_tests", "test_id_prefix": "ninja://chromeos:chrome_all_tast_tests/" @@ -1208,7 +1208,7 @@ ], "idempotent": false, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "shards": 4 }, "test": "chrome_all_tast_tests", "test_id_prefix": "ninja://chromeos:chrome_all_tast_tests/",
diff --git a/testing/buildbot/chromium.mac.json b/testing/buildbot/chromium.mac.json index 1aef999..be65779 100644 --- a/testing/buildbot/chromium.mac.json +++ b/testing/buildbot/chromium.mac.json
@@ -5654,7 +5654,7 @@ }, { "args": [ - "--test-launcher-jobs=1" + "--test-launcher-jobs=2" ], "merge": { "args": [],
diff --git a/testing/buildbot/chromium.perf.fyi.json b/testing/buildbot/chromium.perf.fyi.json index 19567905..ef832f8 100644 --- a/testing/buildbot/chromium.perf.fyi.json +++ b/testing/buildbot/chromium.perf.fyi.json
@@ -266,6 +266,52 @@ } ] }, + "lacros-eve-perf-fyi": { + "isolated_scripts": [ + { + "args": [ + "-v", + "--browser=lacros-chrome", + "--upload-results", + "--test-shard-map-filename=lacros-eve-perf-fyi_map.json", + "--remote=variable_chromeos_device_hostname" + ], + "isolate_name": "performance_test_suite", + "merge": { + "script": "//tools/perf/process_perf_results.py" + }, + "name": "performance_test_suite", + "override_compile_targets": [ + "performance_test_suite" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "device_type": "eve", + "gpu": null, + "os": "ChromeOS", + "pool": "chrome.tests" + } + ], + "expiration": 7200, + "hard_timeout": 21600, + "ignore_task_failure": false, + "io_timeout": 21600, + "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 1 + }, + "trigger_script": { + "args": [ + "--multiple-dimension-script-verbose", + "True" + ], + "requires_simultaneous_shard_dispatch": true, + "script": "//testing/trigger_scripts/perf_device_trigger.py" + } + } + ] + }, "linux-perf-fyi": { "isolated_scripts": [ {
diff --git a/testing/buildbot/internal.chromeos.fyi.json b/testing/buildbot/internal.chromeos.fyi.json index 43cf64b..5fa8a3b 100644 --- a/testing/buildbot/internal.chromeos.fyi.json +++ b/testing/buildbot/internal.chromeos.fyi.json
@@ -52,7 +52,7 @@ ], "idempotent": false, "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "shards": 4 }, "test": "chrome_all_tast_tests", "test_id_prefix": "ninja://chromeos:chrome_all_tast_tests/" @@ -258,7 +258,7 @@ ] }, "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "shards": 4 }, "test": "chrome_all_tast_tests", "test_id_prefix": "ninja://chromeos:chrome_all_tast_tests/" @@ -1173,7 +1173,7 @@ ], "idempotent": false, "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "shards": 4 }, "test": "chrome_all_tast_tests", "test_id_prefix": "ninja://chromeos:chrome_all_tast_tests/",
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index e8bbabd..dd06abf 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -523,7 +523,7 @@ 'Mac10.13 Tests (dbg)': { # https://crbug.com/1152770 'args': [ - '--test-launcher-jobs=1', + '--test-launcher-jobs=2', ], 'swarming': { 'shards': 20,
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index 407885f..6052412f 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -458,7 +458,7 @@ 'chrome_all_tast_tests': { 'swarming': { 'idempotent': False, # https://crbug.com/923426#c27 - 'shards': 2, + 'shards': 4, }, 'resultdb': { 'enable': True,
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl index 45e49019..d4b12e4 100644 --- a/testing/buildbot/variants.pyl +++ b/testing/buildbot/variants.pyl
@@ -319,13 +319,13 @@ '../../weblayer/browser/android/javatests/skew/expectations.txt', '--impl-version=88', ], - 'identifier': 'Implementation Tests For 88.0.4324.84', + 'identifier': 'Implementation Tests For 88.0.4324.85', 'swarming': { 'cipd_packages': [ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M88', - 'revision': 'version:88.0.4324.84', + 'revision': 'version:88.0.4324.85', } ], }, @@ -342,13 +342,13 @@ '../../weblayer/browser/android/javatests/skew/expectations.txt', '--impl-version=87', ], - 'identifier': 'Implementation Tests For 87.0.4280.147', + 'identifier': 'Implementation Tests For 87.0.4280.148', 'swarming': { 'cipd_packages': [ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M87', - 'revision': 'version:87.0.4280.147', + 'revision': 'version:87.0.4280.148', } ], }, @@ -388,13 +388,13 @@ '../../weblayer/browser/android/javatests/skew/expectations.txt', '--client-version=88', ], - 'identifier': 'Client Tests For 88.0.4324.84', + 'identifier': 'Client Tests For 88.0.4324.85', 'swarming': { 'cipd_packages': [ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M88', - 'revision': 'version:88.0.4324.84', + 'revision': 'version:88.0.4324.85', } ], }, @@ -411,13 +411,13 @@ '../../weblayer/browser/android/javatests/skew/expectations.txt', '--client-version=87', ], - 'identifier': 'Client Tests For 87.0.4280.147', + 'identifier': 'Client Tests For 87.0.4280.148', 'swarming': { 'cipd_packages': [ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M87', - 'revision': 'version:87.0.4280.147', + 'revision': 'version:87.0.4280.148', } ], },
diff --git a/third_party/blink/public/mojom/web_feature/web_feature.mojom b/third_party/blink/public/mojom/web_feature/web_feature.mojom index 075f4cb..86badee 100644 --- a/third_party/blink/public/mojom/web_feature/web_feature.mojom +++ b/third_party/blink/public/mojom/web_feature/web_feature.mojom
@@ -3069,6 +3069,7 @@ kSamePartyCookieInclusionOverruledSameSite = 3748, kEmbedElementWithoutTypeSrcChanged = 3749, kPaymentHandlerStandardizedPaymentMethodIdentifier = 3750, + kWebCodecsAudioEncoder = 3751, // Add new features immediately above this line. Don't change assigned // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/blink/public/web/web_ax_object.h b/third_party/blink/public/web/web_ax_object.h index 6813404..6091eeb 100644 --- a/third_party/blink/public/web/web_ax_object.h +++ b/third_party/blink/public/web/web_ax_object.h
@@ -81,9 +81,7 @@ BLINK_EXPORT bool operator>(const WebAXObject& other) const; BLINK_EXPORT bool operator>=(const WebAXObject& other) const; BLINK_EXPORT static WebAXObject FromWebNode(const WebNode&); - BLINK_EXPORT static WebAXObject FromWebDocument( - const WebDocument&, - bool update_layout_if_necessary = true); + BLINK_EXPORT static WebAXObject FromWebDocument(const WebDocument&); BLINK_EXPORT static WebAXObject FromWebDocumentByID(const WebDocument&, int); BLINK_EXPORT static WebAXObject FromWebDocumentFocused( const WebDocument&,
diff --git a/third_party/blink/renderer/bindings/generated_in_modules.gni b/third_party/blink/renderer/bindings/generated_in_modules.gni index 058fadc..1402bb1 100644 --- a/third_party/blink/renderer/bindings/generated_in_modules.gni +++ b/third_party/blink/renderer/bindings/generated_in_modules.gni
@@ -13,6 +13,8 @@ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_animator_constructor.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_frame_output_callback.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_frame_output_callback.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_encoded_audio_chunk_output_callback.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_encoded_audio_chunk_output_callback.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_blink_audio_worklet_process_callback.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_blink_audio_worklet_process_callback.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_blink_audio_worklet_processor_constructor.cc", @@ -107,6 +109,10 @@ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_android_pay_method_data.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_app_banner_prompt_result.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_app_banner_prompt_result.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_encoder_config.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_encoder_config.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_encoder_init.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_encoder_init.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_buffer_options.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_buffer_options.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_buffer_source_options.cc", @@ -1239,6 +1245,8 @@ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_context.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_decoder.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_decoder.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_encoder.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_encoder.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_destination_node.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_destination_node.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_frame.cc",
diff --git a/third_party/blink/renderer/bindings/idl_in_modules.gni b/third_party/blink/renderer/bindings/idl_in_modules.gni index 96f53b886..29ef3b5 100644 --- a/third_party/blink/renderer/bindings/idl_in_modules.gni +++ b/third_party/blink/renderer/bindings/idl_in_modules.gni
@@ -743,6 +743,9 @@ "//third_party/blink/renderer/modules/webcodecs/audio_decoder.idl", "//third_party/blink/renderer/modules/webcodecs/audio_decoder_config.idl", "//third_party/blink/renderer/modules/webcodecs/audio_decoder_init.idl", + "//third_party/blink/renderer/modules/webcodecs/audio_encoder.idl", + "//third_party/blink/renderer/modules/webcodecs/audio_encoder_config.idl", + "//third_party/blink/renderer/modules/webcodecs/audio_encoder_init.idl", "//third_party/blink/renderer/modules/webcodecs/audio_frame.idl", "//third_party/blink/renderer/modules/webcodecs/audio_frame_init.idl", "//third_party/blink/renderer/modules/webcodecs/audio_frame_output_callback.idl", @@ -756,6 +759,7 @@ "//third_party/blink/renderer/modules/webcodecs/encoded_audio_chunk_init.idl", "//third_party/blink/renderer/modules/webcodecs/encoded_video_chunk.idl", "//third_party/blink/renderer/modules/webcodecs/encoded_video_chunk_init.idl", + "//third_party/blink/renderer/modules/webcodecs/encoded_audio_chunk_output_callback.idl", "//third_party/blink/renderer/modules/webcodecs/image_decoder.idl", "//third_party/blink/renderer/modules/webcodecs/image_decoder_init.idl", "//third_party/blink/renderer/modules/webcodecs/image_frame.idl",
diff --git a/third_party/blink/renderer/bindings/modules/v8/generated.gni b/third_party/blink/renderer/bindings/modules/v8/generated.gni index 5600b9d..3a75dbe 100644 --- a/third_party/blink/renderer/bindings/modules/v8/generated.gni +++ b/third_party/blink/renderer/bindings/modules/v8/generated.gni
@@ -148,6 +148,8 @@ "$bindings_modules_v8_output_dir/v8_decode_error_callback.h", "$bindings_modules_v8_output_dir/v8_decode_success_callback.cc", "$bindings_modules_v8_output_dir/v8_decode_success_callback.h", + "$bindings_modules_v8_output_dir/v8_encoded_audio_chunk_output_callback.cc", + "$bindings_modules_v8_output_dir/v8_encoded_audio_chunk_output_callback.h", "$bindings_modules_v8_output_dir/v8_idb_observer_callback.cc", "$bindings_modules_v8_output_dir/v8_idb_observer_callback.h", "$bindings_modules_v8_output_dir/v8_launch_consumer.cc",
diff --git a/third_party/blink/renderer/core/animation/scroll_timeline.cc b/third_party/blink/renderer/core/animation/scroll_timeline.cc index be41cab..259917a 100644 --- a/third_party/blink/renderer/core/animation/scroll_timeline.cc +++ b/third_party/blink/renderer/core/animation/scroll_timeline.cc
@@ -270,7 +270,6 @@ } resolved_offsets.push_back(resolved_offset.value()); } - // TODO(crbug.com/1094014): Implement clamping for overlapping offsets. DCHECK_GE(resolved_offsets.size(), 2u); return true; }
diff --git a/third_party/blink/renderer/core/animation/scroll_timeline.h b/third_party/blink/renderer/core/animation/scroll_timeline.h index f214ffc..5c6f0ec 100644 --- a/third_party/blink/renderer/core/animation/scroll_timeline.h +++ b/third_party/blink/renderer/core/animation/scroll_timeline.h
@@ -129,6 +129,7 @@ size_t AttachedAnimationsCount() const { return scroll_animations_.size(); } private: + FRIEND_TEST_ALL_PREFIXES(ScrollTimelineTest, MultipleScrollOffsetsClamping); // https://wicg.github.io/scroll-animations/#avoiding-cycles // Snapshots scroll timeline current time and phase. // Called once per animation frame.
diff --git a/third_party/blink/renderer/core/animation/scroll_timeline_test.cc b/third_party/blink/renderer/core/animation/scroll_timeline_test.cc index 3d4b21cd..46176b7 100644 --- a/third_party/blink/renderer/core/animation/scroll_timeline_test.cc +++ b/third_party/blink/renderer/core/animation/scroll_timeline_test.cc
@@ -878,4 +878,68 @@ EXPECT_EQ(100, scroll_timeline->CurrentTimeMilliseconds().value()); } +TEST_F(ScrollTimelineTest, OverlappingScrollOffsets) { + SetBodyInnerHTML(R"HTML( + <style> + #scroller { overflow: scroll; width: 100px; height: 100px; } + #spacer { height: 1000px; } + </style> + <div id='scroller'> + <div id ='spacer'></div> + </div> + )HTML"); + + auto* scroller = + To<LayoutBoxModelObject>(GetLayoutObjectByElementId("scroller")); + ASSERT_TRUE(scroller); + PaintLayerScrollableArea* scrollable_area = scroller->GetScrollableArea(); + ASSERT_TRUE(scrollable_area); + double time_range = 100.0; + ScrollTimelineOptions* options = ScrollTimelineOptions::Create(); + options->setTimeRange( + DoubleOrScrollTimelineAutoKeyword::FromDouble(time_range)); + options->setScrollSource(GetElementById("scroller")); + HeapVector<ScrollTimelineOffsetValue> scroll_offsets = { + OffsetFromString("90px"), OffsetFromString("40px"), + OffsetFromString("10px")}; + options->setScrollOffsets(scroll_offsets); + + ScrollTimeline* scroll_timeline = + ScrollTimeline::Create(GetDocument(), options, ASSERT_NO_EXCEPTION); + + scrollable_area->SetScrollOffset(ScrollOffset(0, 80), + mojom::blink::ScrollType::kProgrammatic); + SimulateFrame(); + EXPECT_EQ(0, scroll_timeline->CurrentTimeMilliseconds().value()); + + scrollable_area->SetScrollOffset(ScrollOffset(0, 95), + mojom::blink::ScrollType::kProgrammatic); + SimulateFrame(); + EXPECT_EQ(100, scroll_timeline->CurrentTimeMilliseconds().value()); + + scroll_offsets = {OffsetFromString("0px"), OffsetFromString("100px"), + OffsetFromString("50px")}; + options->setScrollOffsets(scroll_offsets); + + scroll_timeline = + ScrollTimeline::Create(GetDocument(), options, ASSERT_NO_EXCEPTION); + + scrollable_area->SetScrollOffset(ScrollOffset(0, 40), + mojom::blink::ScrollType::kProgrammatic); + SimulateFrame(); + EXPECT_EQ(20, scroll_timeline->CurrentTimeMilliseconds().value()); + + scroll_offsets = {OffsetFromString("50px"), OffsetFromString("0px"), + OffsetFromString("100px")}; + options->setScrollOffsets(scroll_offsets); + + scroll_timeline = + ScrollTimeline::Create(GetDocument(), options, ASSERT_NO_EXCEPTION); + + scrollable_area->SetScrollOffset(ScrollOffset(0, 60), + mojom::blink::ScrollType::kProgrammatic); + SimulateFrame(); + EXPECT_EQ(80, scroll_timeline->CurrentTimeMilliseconds().value()); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/css/view-source.css b/third_party/blink/renderer/core/css/view-source.css index 17b08a6..a54f79a9 100644 --- a/third_party/blink/renderer/core/css/view-source.css +++ b/third_party/blink/renderer/core/css/view-source.css
@@ -40,7 +40,8 @@ .line-wrap { width: 100%; white-space: pre-wrap !important; - word-break: break-word; + word-break: normal; + overflow-wrap: anywhere; } .line-wrap-control {
diff --git a/third_party/blink/renderer/core/editing/frame_selection.cc b/third_party/blink/renderer/core/editing/frame_selection.cc index f813916f..e8e2867 100644 --- a/third_party/blink/renderer/core/editing/frame_selection.cc +++ b/third_party/blink/renderer/core/editing/frame_selection.cc
@@ -1293,6 +1293,11 @@ return layout_selection_->ComputeSelectionStateForCursor(position); } +SelectionState FrameSelection::ComputeLayoutSelectionStateForInlineTextBox( + const InlineTextBox& text_box) const { + return layout_selection_->ComputeSelectionStateForInlineTextBox(text_box); +} + bool FrameSelection::IsDirectional() const { return is_directional_; }
diff --git a/third_party/blink/renderer/core/editing/frame_selection.h b/third_party/blink/renderer/core/editing/frame_selection.h index 5ca1f29..2b302c46 100644 --- a/third_party/blink/renderer/core/editing/frame_selection.h +++ b/third_party/blink/renderer/core/editing/frame_selection.h
@@ -44,6 +44,7 @@ class CaretDisplayItemClient; class Element; +class InlineTextBox; class LayoutBlock; class LayoutText; class LocalFrame; @@ -240,6 +241,7 @@ void PageActivationChanged(); bool IsHandleVisible() const { return is_handle_visible_; } + void SetHandleVisibleForTesting() { is_handle_visible_ = true; } bool ShouldShrinkNextTap() const { return should_shrink_next_tap_; } // Returns true if a word is selected. @@ -288,6 +290,8 @@ const NGInlineCursor& cursor) const; SelectionState ComputeLayoutSelectionStateForCursor( const NGInlineCursorPosition& position) const; + SelectionState ComputeLayoutSelectionStateForInlineTextBox( + const InlineTextBox& text_box) const; void Trace(Visitor*) const override;
diff --git a/third_party/blink/renderer/core/editing/layout_selection.cc b/third_party/blink/renderer/core/editing/layout_selection.cc index 8785a43..ee69daa 100644 --- a/third_party/blink/renderer/core/editing/layout_selection.cc +++ b/third_party/blink/renderer/core/editing/layout_selection.cc
@@ -30,9 +30,11 @@ #include "third_party/blink/renderer/core/editing/visible_position.h" #include "third_party/blink/renderer/core/editing/visible_units.h" #include "third_party/blink/renderer/core/html/forms/text_control_element.h" +#include "third_party/blink/renderer/core/layout/api/line_layout_api_shim.h" #include "third_party/blink/renderer/core/layout/layout_text.h" #include "third_party/blink/renderer/core/layout/layout_text_fragment.h" #include "third_party/blink/renderer/core/layout/layout_view.h" +#include "third_party/blink/renderer/core/layout/line/inline_text_box.h" #include "third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h" #include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h" #include "third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.h" @@ -708,40 +710,34 @@ } } -SelectionState LayoutSelection::ComputeSelectionStateForCursor( - const NGInlineCursorPosition& position) const { - if (!position) - return SelectionState::kNone; - - DCHECK(position.IsText()); - - // Selection on ellipsis is not supported. - if (position.IsEllipsis()) - return SelectionState::kNone; - - const NGTextOffset offset = position.TextOffset(); - const unsigned start_offset = offset.start; - const unsigned end_offset = offset.end; - // Determine the state of the overall selection, relative to the LayoutObject - // associated with the current cursor position. This state will allow us know - // which offset comparisons are valid, and determine if the selection - // endpoints fall within the current cursor position. - switch (GetSelectionStateFor(position)) { +// Given |state| that describes the provided offsets relationship to the +// |paint_range_| (and thus which comparisons are valid), returns a +// SelectionState that reflects where the endpoints of the selection fall, +// relative to the range expressed by the offsets. +SelectionState LayoutSelection::ComputeSelectionStateFromOffsets( + SelectionState state, + unsigned start_offset, + unsigned end_offset) const { + switch (state) { case SelectionState::kStart: { - const unsigned start_in_block = paint_range_->start_offset.value(); + const unsigned start_in_block = + paint_range_->start_offset.value_or(start_offset); return start_offset <= start_in_block && start_in_block <= end_offset ? SelectionState::kStart : SelectionState::kNone; } case SelectionState::kEnd: { - const unsigned end_in_block = paint_range_->end_offset.value(); + const unsigned end_in_block = + paint_range_->end_offset.value_or(end_offset); return start_offset <= end_in_block && end_in_block <= end_offset ? SelectionState::kEnd : SelectionState::kNone; } case SelectionState::kStartAndEnd: { - const unsigned start_in_block = paint_range_->start_offset.value(); - const unsigned end_in_block = paint_range_->end_offset.value(); + const unsigned start_in_block = + paint_range_->start_offset.value_or(start_offset); + const unsigned end_in_block = + paint_range_->end_offset.value_or(end_offset); const bool is_start_in_current_cursor = start_offset <= start_in_block && start_in_block <= end_offset; const bool is_end_in_current_cursor = @@ -763,6 +759,42 @@ } } +SelectionState LayoutSelection::ComputeSelectionStateForCursor( + const NGInlineCursorPosition& position) const { + if (!position) + return SelectionState::kNone; + + DCHECK(position.IsText()); + + // Selection on ellipsis is not supported. + if (position.IsEllipsis()) + return SelectionState::kNone; + + const NGTextOffset offset = position.TextOffset(); + const unsigned start_offset = offset.start; + const unsigned end_offset = offset.end; + // Determine the state of the overall selection, relative to the LayoutObject + // associated with the current cursor position. This state will allow us know + // which offset comparisons are valid, and determine if the selection + // endpoints fall within the current cursor position. + SelectionState state = GetSelectionStateFor(position); + return ComputeSelectionStateFromOffsets(state, start_offset, end_offset); +} + +SelectionState LayoutSelection::ComputeSelectionStateForInlineTextBox( + const InlineTextBox& text_box) const { + AssertIsValid(); + unsigned start_offset = static_cast<unsigned>(text_box.CaretMinOffset()); + unsigned end_offset = static_cast<unsigned>(text_box.CaretMaxOffset()); + // Determine the state of the overall selection, relative to the + // InlineTextBox. This state will allow us know which offset comparisons are + // valid, and determine if the selection endpoints fall within InlineTextBox. + const LayoutText* text = To<LayoutText>( + LineLayoutAPIShim::ConstLayoutObjectFrom(text_box.GetLineLayoutItem())); + SelectionState state = GetSelectionStateFor(*text); + return ComputeSelectionStateFromOffsets(state, start_offset, end_offset); +} + static NewPaintRangeAndSelectedNodes CalcSelectionRangeAndSetSelectionState( const FrameSelection& frame_selection) { const SelectionInDOMTree& selection_in_dom =
diff --git a/third_party/blink/renderer/core/editing/layout_selection.h b/third_party/blink/renderer/core/editing/layout_selection.h index ee941a0..a29df9a 100644 --- a/third_party/blink/renderer/core/editing/layout_selection.h +++ b/third_party/blink/renderer/core/editing/layout_selection.h
@@ -29,6 +29,7 @@ namespace blink { +class InlineTextBox; class IntRect; class LayoutObject; class LayoutText; @@ -61,6 +62,14 @@ SelectionState ComputeSelectionStateForCursor( const NGInlineCursorPosition&) const; + // Compute the layout selection state relative to the InlineTextBox. + // E.g. a state of kStart means that the selection starts within the line + // (and ends elsewhere), where kStartAndEnd means the selection both starts + // and ends within the line. This information is used at paint time to + // determine the edges of the layout selection. + SelectionState ComputeSelectionStateForInlineTextBox( + const InlineTextBox&) const; + static bool IsSelected(const LayoutObject&); void ContextDestroyed(); @@ -68,6 +77,10 @@ void Trace(Visitor*) const; private: + SelectionState ComputeSelectionStateFromOffsets(SelectionState state, + unsigned start_offset, + unsigned end_offset) const; + void AssertIsValid() const; Member<FrameSelection> frame_selection_;
diff --git a/third_party/blink/renderer/core/editing/layout_selection_test.cc b/third_party/blink/renderer/core/editing/layout_selection_test.cc index 6a044580..5acd68b 100644 --- a/third_party/blink/renderer/core/editing/layout_selection_test.cc +++ b/third_party/blink/renderer/core/editing/layout_selection_test.cc
@@ -12,6 +12,7 @@ #include "third_party/blink/renderer/core/layout/layout_object.h" #include "third_party/blink/renderer/core/layout/layout_text.h" #include "third_party/blink/renderer/core/layout/layout_text_fragment.h" +#include "third_party/blink/renderer/core/layout/line/inline_text_box.h" #include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h" #include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" @@ -943,6 +944,69 @@ DumpSelectionInfo()); } +TEST_P(LayoutSelectionTest, StartAndEndSelectionState) { + if (LayoutNGEnabled()) + return; + + Selection().SetSelectionAndEndTyping( + SetSelectionTextToBody("<div>f^oo|</div><div>bar</div>")); + UpdateAllLifecyclePhasesForTest(); + Node* foo_div = GetDocument().body()->firstChild(); + auto& foo_text = *To<LayoutText>(foo_div->firstChild()->GetLayoutObject()); + InlineTextBox* text_box = foo_text.FirstTextBox(); + + EXPECT_EQ(SelectionState::kStartAndEnd, + Selection().ComputeLayoutSelectionStateForInlineTextBox(*text_box)); + + Node* bar_div = GetDocument().body()->lastChild(); + auto& bar_text = *To<LayoutText>(bar_div->firstChild()->GetLayoutObject()); + text_box = bar_text.FirstTextBox(); + EXPECT_EQ(SelectionState::kNone, + Selection().ComputeLayoutSelectionStateForInlineTextBox(*text_box)); +} + +TEST_P(LayoutSelectionTest, StartAndEndMultilineSelectionState) { + if (LayoutNGEnabled()) + return; + + Selection().SetSelectionAndEndTyping(SetSelectionTextToBody( + "<div style='white-space:pre'>f^oo\nbar\nba|z</div>")); + UpdateAllLifecyclePhasesForTest(); + auto& div_text = *To<LayoutText>( + GetDocument().body()->firstChild()->firstChild()->GetLayoutObject()); + for (const InlineTextBox* box : div_text.TextBoxes()) { + SelectionState state = + Selection().ComputeLayoutSelectionStateForInlineTextBox(*box); + if (box == div_text.FirstTextBox()) + EXPECT_EQ(SelectionState::kStart, state); + else if (box == div_text.LastTextBox()) + EXPECT_EQ(SelectionState::kEnd, state); + else + EXPECT_EQ(SelectionState::kInside, state); + } +} + +TEST_P(LayoutSelectionTest, StartAndEndBR) { + if (LayoutNGEnabled()) + return; + + Selection().SetSelectionAndEndTyping(SetSelectionTextToBody( + "<div style='white-space:pre'>^<br>foo<br>|</div>")); + UpdateAllLifecyclePhasesForTest(); + auto& first_br_text = *To<LayoutText>( + GetDocument().body()->firstChild()->firstChild()->GetLayoutObject()); + const InlineTextBox* box = first_br_text.FirstTextBox(); + SelectionState state = + Selection().ComputeLayoutSelectionStateForInlineTextBox(*box); + EXPECT_EQ(SelectionState::kStart, state); + auto& last_br_text = *To<LayoutText>( + GetDocument().body()->firstChild()->lastChild()->GetLayoutObject()); + + box = last_br_text.FirstTextBox(); + state = Selection().ComputeLayoutSelectionStateForInlineTextBox(*box); + EXPECT_EQ(SelectionState::kEnd, state); +} + class NGLayoutSelectionTest : public LayoutSelectionTestBase, private ScopedLayoutNGForTest,
diff --git a/third_party/blink/renderer/core/html/html_view_source_document.cc b/third_party/blink/renderer/core/html/html_view_source_document.cc index d5e4af46..0b4d0a6 100644 --- a/third_party/blink/renderer/core/html/html_view_source_document.cc +++ b/third_party/blink/renderer/core/html/html_view_source_document.cc
@@ -30,6 +30,7 @@ #include "third_party/blink/renderer/core/dom/events/native_event_listener.h" #include "third_party/blink/renderer/core/dom/text.h" #include "third_party/blink/renderer/core/events/mouse_event.h" +#include "third_party/blink/renderer/core/html/forms/html_form_element.h" #include "third_party/blink/renderer/core/html/forms/html_input_element.h" #include "third_party/blink/renderer/core/html/forms/html_label_element.h" #include "third_party/blink/renderer/core/html/html_anchor_element.h" @@ -57,8 +58,7 @@ : table_(table), checkbox_(checkbox) {} void Invoke(ExecutionContext*, Event* event) override { - DCHECK(DynamicTo<MouseEvent>(event)); - DCHECK_EQ(event->type(), event_type_names::kClick); + DCHECK_EQ(event->type(), event_type_names::kChange); table_->setAttribute(html_names::kClassAttr, checkbox_->checked() ? "line-wrap" : ""); } @@ -108,28 +108,32 @@ line_number_ = 0; // Create a checkbox to control line wrapping. - auto* label = MakeGarbageCollected<HTMLLabelElement>(*this); - label->setAttribute(html_names::kClassAttr, "line-wrap-control"); auto* checkbox = MakeGarbageCollected<HTMLInputElement>(*this, CreateElementFlags()); checkbox->setAttribute(html_names::kTypeAttr, "checkbox"); - label->ParserAppendChild(checkbox); + checkbox->addEventListener( + event_type_names::kChange, + MakeGarbageCollected<ViewSourceEventListener>(table, checkbox), + /*use_capture=*/false); + auto* label = MakeGarbageCollected<HTMLLabelElement>(*this); label->ParserAppendChild( Text::Create(*this, WTF::AtomicString(Locale::DefaultLocale().QueryString( IDS_VIEW_SOURCE_LINE_WRAP)))); + label->setAttribute(html_names::kClassAttr, "line-wrap-control"); + label->ParserAppendChild(checkbox); + // Add the checkbox to a form with autocomplete=off, to avoid form + // restoration from changing the value of the checkbox. + auto* form = MakeGarbageCollected<HTMLFormElement>(*this); + form->setAttribute(html_names::kAutocompleteAttr, "off"); + form->ParserAppendChild(label); auto* tr = MakeGarbageCollected<HTMLTableRowElement>(*this); auto* td = MakeGarbageCollected<HTMLTableCellElement>(html_names::kTdTag, *this); td->setAttribute(html_names::kColspanAttr, "2"); td->setAttribute(html_names::kClassAttr, "line-wrap-cell"); - td->ParserAppendChild(label); + td->ParserAppendChild(form); tr->ParserAppendChild(td); tbody_->ParserAppendChild(tr); - - auto* listener = - MakeGarbageCollected<ViewSourceEventListener>(table, checkbox); - checkbox->addEventListener(event_type_names::kClick, listener, - /*use_capture=*/false); } void HTMLViewSourceDocument::AddSource(const String& source, HTMLToken& token) {
diff --git a/third_party/blink/renderer/core/html/html_view_source_document_test.cc b/third_party/blink/renderer/core/html/html_view_source_document_test.cc index 8c8665b..5a507e73 100644 --- a/third_party/blink/renderer/core/html/html_view_source_document_test.cc +++ b/third_party/blink/renderer/core/html/html_view_source_document_test.cc
@@ -39,8 +39,10 @@ GetDocument().documentElement()->outerHTML(), "<html><head></head><body><div " "class=\"line-gutter-backdrop\"></div><table><tbody><tr><td " - "colspan=\"2\" class=\"line-wrap-cell\"><label " - "class=\"line-wrap-control\"><input type=\"checkbox\"></label>" + "colspan=\"2\" class=\"line-wrap-cell\"><form " + "autocomplete=\"off\"><label " + "class=\"line-wrap-control\"><input " + "type=\"checkbox\"></label></form>" "</td></tr><tr><td class=\"line-number\" value=\"1\"></td><td " "class=\"line-content\"><br></td></tr><tr><td class=\"line-number\" " "value=\"2\"></td><td class=\"line-content\"> <span " @@ -94,8 +96,10 @@ GetDocument().documentElement()->outerHTML(), "<html><head></head><body><div " "class=\"line-gutter-backdrop\"></div><table><tbody><tr><td " - "colspan=\"2\" class=\"line-wrap-cell\"><label " - "class=\"line-wrap-control\"><input type=\"checkbox\"></label>" + "colspan=\"2\" class=\"line-wrap-cell\"><form " + "autocomplete=\"off\"><label " + "class=\"line-wrap-control\"><input " + "type=\"checkbox\"></label></form>" "</td></tr><tr><td class=\"line-number\" value=\"1\"></td><td " "class=\"line-content\"><br></td></tr><tr><td class=\"line-number\" " "value=\"2\"></td><td class=\"line-content\"> <span " @@ -148,8 +152,10 @@ GetDocument().documentElement()->outerHTML(), "<html><head></head><body><div " "class=\"line-gutter-backdrop\"></div><table><tbody><tr><td " - "colspan=\"2\" class=\"line-wrap-cell\"><label " - "class=\"line-wrap-control\"><input type=\"checkbox\"></label>" + "colspan=\"2\" class=\"line-wrap-cell\"><form " + "autocomplete=\"off\"><label " + "class=\"line-wrap-control\"><input " + "type=\"checkbox\"></label></form>" "</td></tr><tr><td class=\"line-number\" value=\"1\"></td><td " "class=\"line-content\"><br></td></tr><tr><td class=\"line-number\" " "value=\"2\"></td><td class=\"line-content\"> <span " @@ -215,8 +221,10 @@ GetDocument().documentElement()->outerHTML(), "<html><head></head><body><div " "class=\"line-gutter-backdrop\"></div><table><tbody><tr><td " - "colspan=\"2\" class=\"line-wrap-cell\"><label " - "class=\"line-wrap-control\"><input type=\"checkbox\"></label>" + "colspan=\"2\" class=\"line-wrap-cell\"><form " + "autocomplete=\"off\"><label " + "class=\"line-wrap-control\"><input " + "type=\"checkbox\"></label></form>" "</td></tr><tr><td class=\"line-number\" value=\"1\"></td><td " "class=\"line-content\"><br></td></tr><tr><td class=\"line-number\" " "value=\"2\"></td><td class=\"line-content\"> <span " @@ -285,8 +293,10 @@ GetDocument().documentElement()->outerHTML(), "<html><head></head><body><div " "class=\"line-gutter-backdrop\"></div><table><tbody><tr><td " - "colspan=\"2\" class=\"line-wrap-cell\"><label " - "class=\"line-wrap-control\"><input type=\"checkbox\"></label>" + "colspan=\"2\" class=\"line-wrap-cell\"><form " + "autocomplete=\"off\"><label " + "class=\"line-wrap-control\"><input " + "type=\"checkbox\"></label></form>" "</td></tr><tr><td class=\"line-number\" value=\"1\"></td><td " "class=\"line-content\"><br></td></tr><tr><td class=\"line-number\" " "value=\"2\"></td><td class=\"line-content\"><br></td></tr><tr><td " @@ -319,8 +329,10 @@ std::string expected_beginning( "<html><head></head><body><div " "class=\"line-gutter-backdrop\"></div><table><tbody><tr><td " - "colspan=\"2\" class=\"line-wrap-cell\"><label " - "class=\"line-wrap-control\"><input type=\"checkbox\"></label>" + "colspan=\"2\" class=\"line-wrap-cell\"><form " + "autocomplete=\"off\"><label " + "class=\"line-wrap-control\"><input " + "type=\"checkbox\"></label></form>" "</td></tr><tr><td class=\"line-number\" value=\"1\">" "</td><td class=\"line-content\"> "); std::string expected_ending( @@ -337,8 +349,10 @@ EXPECT_EQ(GetDocument().documentElement()->outerHTML(), "<html><head></head><body><div " "class=\"line-gutter-backdrop\"></div><table><tbody><tr><td " - "colspan=\"2\" class=\"line-wrap-cell\"><label " - "class=\"line-wrap-control\"><input type=\"checkbox\"></label>" + "colspan=\"2\" class=\"line-wrap-cell\"><form " + "autocomplete=\"off\"><label " + "class=\"line-wrap-control\"><input " + "type=\"checkbox\"></label></form>" "</td></tr><tr><td class=\"line-number\" value=\"1\"></td><td " "class=\"line-content\">1234567<span " "class=\"html-end-of-file\"></span></td></tr></tbody></table></" @@ -361,8 +375,10 @@ GetDocument().documentElement()->outerHTML(), "<html><head></head><body><div " "class=\"line-gutter-backdrop\"></div><table><tbody><tr><td " - "colspan=\"2\" class=\"line-wrap-cell\"><label " - "class=\"line-wrap-control\"><input type=\"checkbox\"></label></td></tr>" + "colspan=\"2\" class=\"line-wrap-cell\"><form " + "autocomplete=\"off\"><label " + "class=\"line-wrap-control\"><input " + "type=\"checkbox\"></label></form></td></tr>" "<tr><td class=\"line-number\" value=\"1\"></td><td " "class=\"line-content\"><br></td></tr><tr><td class=\"line-number\" " "value=\"2\"></td><td class=\"line-content\"> <span " @@ -430,8 +446,10 @@ GetDocument().documentElement()->outerHTML(), "<html><head></head><body><div " "class=\"line-gutter-backdrop\"></div><table><tbody><tr><td " - "colspan=\"2\" class=\"line-wrap-cell\"><label " - "class=\"line-wrap-control\"><input type=\"checkbox\"></label>" + "colspan=\"2\" class=\"line-wrap-cell\"><form " + "autocomplete=\"off\"><label " + "class=\"line-wrap-control\"><input " + "type=\"checkbox\"></label></form>" "</td></tr><tr><td class=\"line-number\" value=\"1\"></td><td " "class=\"line-content\"><br></td></tr><tr><td class=\"line-number\" " "value=\"2\"></td><td class=\"line-content\"> <span " @@ -463,9 +481,11 @@ GetDocument().documentElement()->outerHTML(), "<html><head></head><body><div " "class=\"line-gutter-backdrop\"></div><table><tbody><tr><td " - "colspan=\"2\" class=\"line-wrap-cell\"><label " - "class=\"line-wrap-control\"><input type=\"checkbox\">" - "</label></td></tr><tr><td class=\"line-number\" value=\"1\"></td><td " + "colspan=\"2\" class=\"line-wrap-cell\"><form " + "autocomplete=\"off\"><label " + "class=\"line-wrap-control\"><input " + "type=\"checkbox\"></label></form>" + "</td></tr><tr><td class=\"line-number\" value=\"1\"></td><td " "class=\"line-content\"><br></td></tr><tr><td class=\"line-number\" " "value=\"2\"></td><td class=\"line-content\"> Incomplete token " "test</td></tr><tr><td class=\"line-number\" value=\"3\"></td><td " @@ -487,8 +507,10 @@ GetDocument().documentElement()->outerHTML(), "<html><head></head><body><div " "class=\"line-gutter-backdrop\"></div><table><tbody><tr><td " - "colspan=\"2\" class=\"line-wrap-cell\"><label " - "class=\"line-wrap-control\"><input type=\"checkbox\"></label>" + "colspan=\"2\" class=\"line-wrap-cell\"><form " + "autocomplete=\"off\"><label " + "class=\"line-wrap-control\"><input " + "type=\"checkbox\"></label></form>" "</td></tr><tr><td class=\"line-number\" value=\"1\"></td>" "<td class=\"line-content\"><span " "class=\"html-tag\"><textarea></span>foobar in " @@ -505,8 +527,10 @@ GetDocument().documentElement()->outerHTML(), "<html><head></head><body><div " "class=\"line-gutter-backdrop\"></div><table><tbody><tr><td " - "colspan=\"2\" class=\"line-wrap-cell\"><label " - "class=\"line-wrap-control\"><input type=\"checkbox\"></label>" + "colspan=\"2\" class=\"line-wrap-cell\"><form " + "autocomplete=\"off\"><label " + "class=\"line-wrap-control\"><input " + "type=\"checkbox\"></label></form>" "</td></tr><tr><td class=\"line-number\" value=\"1\"></td>" "<td class=\"line-content\"><span " "class=\"html-tag\"><script></span>foobar in "
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_node.h b/third_party/blink/renderer/core/layout/ng/ng_block_node.h index cf5d13b..302adc9 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_block_node.h +++ b/third_party/blink/renderer/core/layout/ng/ng_block_node.h
@@ -283,10 +283,10 @@ } static blink::NGBlockNode EmptyValue() { return nullptr; } static void ConstructDeletedValue(blink::NGBlockNode& slot, bool) { - slot = nullptr; + slot = blink::NGBlockNode(reinterpret_cast<blink::LayoutBox*>(-1)); } static bool IsDeletedValue(const blink::NGBlockNode& value) { - return IsEmptyValue(value); + return value.GetLayoutBox() == reinterpret_cast<blink::LayoutBox*>(-1); } };
diff --git a/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc index 6898faa5..3a4a398 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc
@@ -304,8 +304,6 @@ // out at the outermost context. If this multicol has OOF positioned // elements pending layout, store its node for later use. if (container_builder_.HasOutOfFlowFragmentainerDescendants()) { - // TODO(almaher): Run layout on the pending OOFs once we hit the - // outermost fragmentation context. container_builder_.AddMulticolWithPendingOOFs(Node()); } }
diff --git a/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.cc b/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.cc index 5fcea1d..981d0a115 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.cc
@@ -312,9 +312,6 @@ } const WritingModeConverter converter(GetWritingDirection(), fragment.Size()); - const WritingModeConverter empty_outer_size(GetWritingDirection(), - PhysicalSize()); - const auto& out_of_flow_fragmentainer_descendants = box_fragment->OutOfFlowPositionedFragmentainerDescendants(); for (const auto& descendant : out_of_flow_fragmentainer_descendants) { @@ -323,8 +320,8 @@ if (!containing_block_fragment) containing_block_fragment = box_fragment; - LogicalOffset containing_block_offset = - converter.ToLogical(descendant.containing_block_offset, PhysicalSize()); + LogicalOffset containing_block_offset = converter.ToLogical( + descendant.containing_block_offset, containing_block_fragment->Size()); if (!fragment.IsFragmentainerBox()) containing_block_offset.block_offset += offset.block_offset; if (IsBlockFragmentationContextRoot()) { @@ -332,8 +329,12 @@ fragmentainer_consumed_block_size_; } + // The static position should remain relative to its containing block + // fragment. + const WritingModeConverter containing_block_converter( + GetWritingDirection(), containing_block_fragment->Size()); NGLogicalStaticPosition static_position = - descendant.static_position.ConvertToLogical(empty_outer_size); + descendant.static_position.ConvertToLogical(containing_block_converter); AddOutOfFlowFragmentainerDescendant( {descendant.node, static_position, descendant.inline_container, /* needs_block_offset_adjustment */ false, containing_block_offset,
diff --git a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc index 663db7d..f9e6582 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc
@@ -135,14 +135,23 @@ void NGOutOfFlowLayoutPart::Run(const LayoutBox* only_layout) { if (container_builder_->IsBlockFragmentationContextRoot() && - !has_block_fragmentation_ && - container_builder_->HasOutOfFlowFragmentainerDescendants()) { - Vector<NGLogicalOutOfFlowPositionedNode> fragmentainer_descendants; - container_builder_->SwapOutOfFlowFragmentainerDescendants( - &fragmentainer_descendants); - - if (!fragmentainer_descendants.IsEmpty()) + !has_block_fragmentation_) { + if (container_builder_->HasOutOfFlowFragmentainerDescendants()) { + Vector<NGLogicalOutOfFlowPositionedNode> fragmentainer_descendants; + container_builder_->SwapOutOfFlowFragmentainerDescendants( + &fragmentainer_descendants); + DCHECK(!fragmentainer_descendants.IsEmpty()); LayoutFragmentainerDescendants(&fragmentainer_descendants); + } + + if (container_builder_->HasMulticolsWithPendingOOFs()) { + HashSet<NGBlockNode> multicols_with_pending_oofs; + container_builder_->SwapMulticolsWithPendingOOFs( + &multicols_with_pending_oofs); + DCHECK(!multicols_with_pending_oofs.IsEmpty()); + for (const NGBlockNode& multicol : multicols_with_pending_oofs) + LayoutOOFsInMulticol(multicol); + } } const LayoutObject* current_container = container_builder_->GetLayoutObject(); @@ -630,6 +639,60 @@ } while (true); } +// TODO(almaher): Look into moving this to NGColumnLayoutAlgorithm instead. +void NGOutOfFlowLayoutPart::LayoutOOFsInMulticol(const NGBlockNode& multicol) { + Vector<NGLogicalOutOfFlowPositionedNode> oof_nodes_to_layout; + + // Accumulate all of the pending OOF positioned nodes that are stored inside + // |multicol|. + for (auto& multicol_fragment : multicol.GetLayoutBox()->PhysicalFragments()) { + const NGPhysicalBoxFragment* multicol_box_fragment = + To<NGPhysicalBoxFragment>(&multicol_fragment); + if (!multicol_box_fragment + ->HasOutOfFlowPositionedFragmentainerDescendants()) + continue; + + WritingDirectionMode writing_direction = + multicol_box_fragment->Style().GetWritingDirection(); + const WritingModeConverter converter(writing_direction, + multicol_box_fragment->Size()); + + // Convert the OOF fragmentainer descendants to the logical coordinate space + // and store the resulting nodes inside |oof_nodes_to_layout|. + for (const auto& descendant : + multicol_box_fragment->OutOfFlowPositionedFragmentainerDescendants()) { + const NGPhysicalContainerFragment* containing_block_fragment = + descendant.containing_block_fragment.get(); + LogicalOffset containing_block_offset = + converter.ToLogical(descendant.containing_block_offset, + containing_block_fragment->Size()); + + // The static position should remain relative to its containing block + // fragment. + const WritingModeConverter containing_block_converter( + writing_direction, containing_block_fragment->Size()); + NGLogicalStaticPosition static_position = + descendant.static_position.ConvertToLogical( + containing_block_converter); + + NGLogicalOutOfFlowPositionedNode node = { + descendant.node, + static_position, + descendant.inline_container, + /* needs_block_offset_adjustment */ false, + containing_block_offset, + containing_block_fragment}; + oof_nodes_to_layout.push_back(node); + } + } + DCHECK(!oof_nodes_to_layout.IsEmpty()); + + // TODO(almaher): This lays out the OOF nodes in the outer fragmentation + // context. We want to lay these out inside the column children of |multicol| + // instead. + LayoutFragmentainerDescendants(&oof_nodes_to_layout); +} + void NGOutOfFlowLayoutPart::LayoutFragmentainerDescendants( Vector<NGLogicalOutOfFlowPositionedNode>* descendants) { original_column_block_size_ =
diff --git a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.h b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.h index 5b48d0d..357634b 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.h +++ b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.h
@@ -102,6 +102,8 @@ const NGLogicalOutOfFlowPositionedNode&, const LayoutBox* only_layout); + void LayoutOOFsInMulticol(const NGBlockNode& multicol); + void LayoutFragmentainerDescendants( Vector<NGLogicalOutOfFlowPositionedNode>* descendants);
diff --git a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part_test.cc b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part_test.cc index 74756ba..2b31d23f 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part_test.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part_test.cc
@@ -1305,9 +1305,7 @@ } // Fragmented OOF element inside a nested multi-column. -// TODO(almaher): Re-enable once layout is run on the pending OOFs of inner -// multicols inside a nested fragmentation context. -TEST_F(NGOutOfFlowLayoutPartTest, DISABLED_AbsposNestedFragmentation) { +TEST_F(NGOutOfFlowLayoutPartTest, AbsposNestedFragmentation) { SetBodyInnerHTML( R"HTML( <style> @@ -1335,9 +1333,10 @@ )HTML"); String dump = DumpFragmentTree(GetElementById("container")); - // TODO(almaher): There should be two abspos fragments with height 60 in the - // first outer column, and two with height 100/30 in the second outer column. - // There should not be a third outer column. + // TODO(almaher): The abspos element should be placed in the inner multicol + // rather than the outer multicol. The offset is also incorrectly computed due + // to the fact that the containing block offset is now relative to the inner + // multicol rather than the outer. String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. offset:unplaced size:1000x100 offset:0,0 size:1000x100 @@ -1350,7 +1349,7 @@ offset:250,0 size:250x60 offset:0,0 size:55x60 offset:0,0 size:25x60 - offset:0,40 size:5x60 + offset:0,0 size:5x100 offset:500,0 size:500x100 offset:0,0 size:500x100 offset:0,0 size:250x100 @@ -1361,7 +1360,62 @@ offset:0,0 size:25x30 offset:0,0 size:5x100 offset:1000,0 size:500x100 - offset:0,0 size:5x90 + offset:0,0 size:5x50 +)DUMP"; + EXPECT_EQ(expectation, dump); +} + +// Test the static position of a fragmented OOF element inside a nested +// multi-column. +TEST_F(NGOutOfFlowLayoutPartTest, AbsposNestedFragmentationStaticPos) { + SetBodyInnerHTML( + R"HTML( + <style> + .multicol { + columns:2; column-fill:auto; column-gap:0px; + } + .rel { + position: relative; width:55px; + } + .abs { + position:absolute; width:5px; height:70px; + } + </style> + <div id="container"> + <div class="multicol" id="outer" style="height:100px;"> + <div class="multicol" id="inner"> + <div class="rel"> + <div style="height:250px; width:25px;"></div> + <div class="abs"></div> + </div> + </div> + </div> + </div> + )HTML"); + String dump = DumpFragmentTree(GetElementById("container")); + + // TODO(almaher): The abspos element should be placed in the inner multicol + // rather than the outer multicol. The static offset is also incorrectly + // computed due to the fact that the containing block offset is now relative + // to the inner multicol rather than the outer. + String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. + offset:unplaced size:1000x100 + offset:0,0 size:1000x100 + offset:0,0 size:500x100 + offset:0,0 size:500x100 + offset:0,0 size:250x100 + offset:0,0 size:55x100 + offset:0,0 size:25x100 + offset:250,0 size:250x100 + offset:0,0 size:55x100 + offset:0,0 size:25x100 + offset:0,50 size:5x50 + offset:500,0 size:500x100 + offset:0,0 size:500x100 + offset:0,0 size:250x100 + offset:0,0 size:55x50 + offset:0,0 size:25x50 + offset:0,0 size:5x20 )DUMP"; EXPECT_EQ(expectation, dump); }
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm.cc index 2b5982e2..445cb7f 100644 --- a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm.cc
@@ -31,14 +31,6 @@ namespace { -// TODO(atotic, ikilpatrick) -// Copy of ShouldScaleColumnsForParent from table_layout_algorithm_auto.cc -// The real fix would be for containers to understand that -// Table max really means: max should be trimmed to available inline size. -bool ShouldIgnorePercentagesForMinMax(const LayoutBox& table) { - return false; -} - NGTableTypes::Caption ComputeCaptionConstraint( const ComputedStyle& table_style, const NGTableGroupedChildren& grouped_children) { @@ -99,7 +91,7 @@ // standard: https://www.w3.org/TR/css-tables-3/#computing-the-table-width LayoutUnit ComputeAssignableTableInlineSize( - const NGBlockNode& table, + const NGTableNode& table, const NGConstraintSpace& space, const NGTableTypes::Columns& column_constraints, const NGTableTypes::Caption& caption_constraint, @@ -113,8 +105,8 @@ const MinMaxSizes grid_min_max = NGTableAlgorithmHelpers::ComputeGridInlineMinMax( - column_constraints, undistributable_space, is_fixed_layout, - /* containing_block_expects_minmax_without_percentages */ false, + table, column_constraints, undistributable_space, is_fixed_layout, + /* allow_column_percentages */ true, /* skip_collapsed_columns */ false); // Standard: "used width of the table". @@ -499,12 +491,11 @@ MinMaxSizesResult NGTableLayoutAlgorithm::ComputeMinMaxSizes( const MinMaxSizesInput& input) const { - LayoutNGTable* layout_table = To<LayoutNGTable>(Node().GetLayoutBox()); const bool is_fixed_layout = Style().IsFixedTableLayout(); // Tables need autosizer. base::Optional<TextAutosizer::TableLayoutScope> text_autosizer; if (!is_fixed_layout) - text_autosizer.emplace(layout_table); + text_autosizer.emplace(To<LayoutNGTable>(Node().GetLayoutBox())); const LogicalSize border_spacing = Style().TableBorderSpacing(); NGTableGroupedChildren grouped_children(Node()); @@ -523,8 +514,8 @@ const MinMaxSizes grid_min_max = NGTableAlgorithmHelpers::ComputeGridInlineMinMax( - *column_constraints, undistributable_space, is_fixed_layout, - ShouldIgnorePercentagesForMinMax(*layout_table), + Node(), *column_constraints, undistributable_space, is_fixed_layout, + /* allow_column_percentages */ false, /* skip_collapsed_columns */ true); MinMaxSizes min_max{
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers.cc b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers.cc index 6c68e26..2f43e53f 100644 --- a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers.cc +++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers.cc
@@ -5,6 +5,7 @@ #include "third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers.h" #include "third_party/blink/renderer/core/layout/geometry/logical_size.h" +#include "third_party/blink/renderer/core/layout/ng/table/ng_table_node.h" namespace blink { @@ -823,12 +824,13 @@ } // namespace MinMaxSizes NGTableAlgorithmHelpers::ComputeGridInlineMinMax( + const NGTableNode& node, const NGTableTypes::Columns& column_constraints, LayoutUnit undistributable_space, bool is_fixed_layout, - bool containing_block_expects_minmax_without_percentages, + bool allow_column_percentages, bool skip_collapsed_columns) { - MinMaxSizes minmax; + MinMaxSizes min_max; // https://www.w3.org/TR/css-tables-3/#computing-the-table-width // Compute standard GRID_MIN/GRID_MAX. They are sum of column_constraints. // @@ -847,9 +849,9 @@ // T% * MINSUM + M = MINSUM. // Minimum total size estimate based on column's min_inline_size and percent. - LayoutUnit percent_maxsize_estimate; + LayoutUnit percent_max_size_estimate; // Sum of max_inline_sizes of non-percentage columns. - LayoutUnit non_percent_maxsize_sum; + LayoutUnit non_percent_max_size_sum; float percent_sum = 0; for (const NGTableTypes::Column& column : column_constraints.data) { if (skip_collapsed_columns && column.is_collapsed) @@ -858,50 +860,50 @@ // In fixed layout, constrained cells minimum inline size is their // maximum. if (is_fixed_layout && column.IsFixed()) { - minmax.min_size += *column.max_inline_size; + min_max.min_size += *column.max_inline_size; } else { - minmax.min_size += *column.min_inline_size; + min_max.min_size += *column.min_inline_size; } if (column.percent && *column.percent > 0) { if (*column.max_inline_size > LayoutUnit()) { LayoutUnit estimate = LayoutUnit( 100 / *column.percent * (*column.max_inline_size - column.percent_border_padding)); - percent_maxsize_estimate = - std::max(percent_maxsize_estimate, estimate); + percent_max_size_estimate = + std::max(percent_max_size_estimate, estimate); } } else { - non_percent_maxsize_sum += *column.max_inline_size; + non_percent_max_size_sum += *column.max_inline_size; } } if (column.max_inline_size) - minmax.max_size += *column.max_inline_size; + min_max.max_size += *column.max_inline_size; if (column.percent) percent_sum += *column.percent; } DCHECK_LE(percent_sum, 100.0f); - // Table max inline size constraint can be computed from: - // total column percentage combined with max_inline_size of nonpercent - // columns. - if (percent_sum > 0 && !containing_block_expects_minmax_without_percentages) { + // Table max inline size constraint can be computed from the total column + // percentage combined with max_inline_size of non-percent columns. + if (percent_sum > 0 && + (allow_column_percentages || node.AllowColumnPercentages())) { LayoutUnit size_from_percent_and_fixed; DCHECK_GE(percent_sum, 0.0f); - if (non_percent_maxsize_sum != LayoutUnit()) { + if (non_percent_max_size_sum != LayoutUnit()) { if (percent_sum == 100.0f) { size_from_percent_and_fixed = NGTableTypes::kTableMaxInlineSize; } else { size_from_percent_and_fixed = - LayoutUnit((100 / (100 - percent_sum)) * non_percent_maxsize_sum); + LayoutUnit((100 / (100 - percent_sum)) * non_percent_max_size_sum); } } - minmax.max_size = std::max(minmax.max_size, size_from_percent_and_fixed); - minmax.max_size = std::max(minmax.max_size, percent_maxsize_estimate); + min_max.max_size = std::max(min_max.max_size, size_from_percent_and_fixed); + min_max.max_size = std::max(min_max.max_size, percent_max_size_estimate); } - minmax.max_size = std::max(minmax.min_size, minmax.max_size); - minmax += undistributable_space; - return minmax; + min_max.max_size = std::max(min_max.min_size, min_max.max_size); + min_max += undistributable_space; + return min_max; } void NGTableAlgorithmHelpers::DistributeColspanCellsToColumns(
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers.h b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers.h index cf41e4a5..895533ba 100644 --- a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers.h +++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers.h
@@ -10,6 +10,8 @@ namespace blink { +class NGTableNode; + // Table size distribution algorithms. class CORE_EXPORT NGTableAlgorithmHelpers { public: @@ -24,17 +26,18 @@ return current_column + 1; } - // Flex/grid containing blocks need Table minmax size to be computed without - // using percentages. - // |containing_block_expects_minmax_without_percentages| is used to do - // this. + // Flex/grid/table-cell containing blocks require that the table min/max + // sizes be computed without percentages. |allow_column_percentages| is used + // to change this behaviour. + // // |undistributable_space| is size of space not occupied by cells // (borders, border spacing). static MinMaxSizes ComputeGridInlineMinMax( + const NGTableNode& node, const NGTableTypes::Columns& column_constraints, LayoutUnit undistributable_space, bool is_fixed_layout, - bool containing_block_expects_minmax_without_percentages, + bool allow_column_percentages, bool skip_collapsed_columns); static void DistributeColspanCellsToColumns(
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers_test.cc b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers_test.cc index a05e941f..ba846d75 100644 --- a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers_test.cc +++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers_test.cc
@@ -5,12 +5,12 @@ #include "third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/core/layout/ng/table/ng_table_node.h" +#include "third_party/blink/renderer/core/testing/core_unit_test_helper.h" namespace blink { -class NGTableAlgorithmHelpersTest : public testing::Test { - void SetUp() override {} - +class NGTableAlgorithmHelpersTest : public RenderingTest { public: NGTableTypes::Column MakeColumn(int min_width, int max_width, @@ -179,12 +179,19 @@ } TEST_F(NGTableAlgorithmHelpersTest, ComputeGridInlineMinMax) { + SetBodyInnerHTML(R"HTML( + <div style="display: flex;"> + <table id=target></table> + <div> + )HTML"); + NGTableNode node(To<LayoutBox>(GetLayoutObjectByElementId("target"))); + scoped_refptr<NGTableTypes::Columns> column_constraints = base::MakeRefCounted<NGTableTypes::Columns>(); LayoutUnit undistributable_space; bool is_fixed_layout = false; - bool containing_block_expects_minmax_without_percentages = false; + bool allow_column_percentages = true; bool skip_collapsed_columns = false; // No percentages, just sums up min/max. @@ -193,9 +200,8 @@ column_constraints->data.push_back(MakeColumn(30, 300)); MinMaxSizes minmax = NGTableAlgorithmHelpers::ComputeGridInlineMinMax( - *column_constraints, undistributable_space, is_fixed_layout, - containing_block_expects_minmax_without_percentages, - skip_collapsed_columns); + node, *column_constraints, undistributable_space, is_fixed_layout, + allow_column_percentages, skip_collapsed_columns); EXPECT_EQ(minmax.min_size, LayoutUnit(60)); EXPECT_EQ(minmax.max_size, LayoutUnit(600)); @@ -206,32 +212,28 @@ column_constraints->data.push_back(MakeColumn(10, 10)); column_constraints->data.push_back(MakeColumn(10, 10)); minmax = NGTableAlgorithmHelpers::ComputeGridInlineMinMax( - *column_constraints, undistributable_space, is_fixed_layout, - containing_block_expects_minmax_without_percentages, - skip_collapsed_columns); + node, *column_constraints, undistributable_space, is_fixed_layout, + allow_column_percentages, skip_collapsed_columns); EXPECT_EQ(minmax.min_size, LayoutUnit(30)); EXPECT_EQ(minmax.max_size, LayoutUnit(990)); - // Without percent, minmax ignores percent - containing_block_expects_minmax_without_percentages = true; + allow_column_percentages = false; minmax = NGTableAlgorithmHelpers::ComputeGridInlineMinMax( - *column_constraints, undistributable_space, is_fixed_layout, - containing_block_expects_minmax_without_percentages, - skip_collapsed_columns); + node, *column_constraints, undistributable_space, is_fixed_layout, + allow_column_percentages, skip_collapsed_columns); EXPECT_EQ(minmax.min_size, LayoutUnit(30)); EXPECT_EQ(minmax.max_size, LayoutUnit(119)); // Percentage: total percentage of 20%, and non-percent width of 800 => // table max size of 800 + (20% * 800/80%) = 1000 - containing_block_expects_minmax_without_percentages = false; + allow_column_percentages = true; column_constraints->data.Shrink(0); column_constraints->data.push_back(MakeColumn(10, 100, 10)); column_constraints->data.push_back(MakeColumn(10, 10, 10)); column_constraints->data.push_back(MakeColumn(10, 800)); minmax = NGTableAlgorithmHelpers::ComputeGridInlineMinMax( - *column_constraints, undistributable_space, is_fixed_layout, - containing_block_expects_minmax_without_percentages, - skip_collapsed_columns); + node, *column_constraints, undistributable_space, is_fixed_layout, + allow_column_percentages, skip_collapsed_columns); EXPECT_EQ(minmax.min_size, LayoutUnit(30)); EXPECT_EQ(minmax.max_size, LayoutUnit(1000)); }
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_node.cc b/third_party/blink/renderer/core/layout/ng/table/ng_table_node.cc index 18b8ccd5..f4bd80b 100644 --- a/third_party/blink/renderer/core/layout/ng/table/ng_table_node.cc +++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_node.cc
@@ -46,4 +46,21 @@ border_padding); } +bool NGTableNode::AllowColumnPercentages() const { + // TODO(layout-dev): This function breaks the rule of "no tree-walks". + // However for this specific case it adds a lot of overhead for little gain. + // In the future, we could have a bit on a LayoutObject which indicates if we + // should allow column percentages, and maintain this when adding/removing + // from the tree. + const LayoutBlock* block = box_->ContainingBlock(); + while (!block->IsLayoutView()) { + if (block->IsTableCell() || block->IsFlexibleBoxIncludingNG() || + block->IsLayoutGrid()) + return false; + + block = block->ContainingBlock(); + } + return true; +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_node.h b/third_party/blink/renderer/core/layout/ng/table/ng_table_node.h index 01a7eff..31f7d7a 100644 --- a/third_party/blink/renderer/core/layout/ng/table/ng_table_node.h +++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_node.h
@@ -27,6 +27,16 @@ LayoutUnit ComputeTableInlineSize(const NGConstraintSpace&, const NGBoxStrut& border_padding) const; + + // Tables are special in that their max intrinsic-size can be "infinite" + // (they should consume as much space as possible). However a lot of layout + // modes (flex/grid) don't deal well with "infinite" max intrinsic-size, so + // we disable this behaviour whenever we are an arbitrary descendant of one + // of these layout modes. + // + // TODO(layout-dev): This isn't ideal, as we may have a fixed inline-size + // parent where an "infinite" size would be fine. + bool AllowColumnPercentages() const; }; template <>
diff --git a/third_party/blink/renderer/core/paint/box_painter_base.cc b/third_party/blink/renderer/core/paint/box_painter_base.cc index ae02a2a..0d26ffb 100644 --- a/third_party/blink/renderer/core/paint/box_painter_base.cc +++ b/third_party/blink/renderer/core/paint/box_painter_base.cc
@@ -136,10 +136,13 @@ } } - // Draw only the shadow. - context.SetShadow(shadow_offset, shadow_blur, shadow_color, - DrawLooperBuilder::kShadowRespectsTransforms, - DrawLooperBuilder::kShadowIgnoresAlpha, kDrawShadowOnly); + // Draw only the shadow. If the color of the shadow is transparent we will + // set an empty draw looper. + DrawLooperBuilder draw_looper_builder; + draw_looper_builder.AddShadow(shadow_offset, shadow_blur, shadow_color, + DrawLooperBuilder::kShadowRespectsTransforms, + DrawLooperBuilder::kShadowIgnoresAlpha); + context.SetDrawLooper(draw_looper_builder.DetachDrawLooper()); if (has_border_radius) { FloatRoundedRect rounded_fill_rect = border;
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.cc b/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.cc index 18dbf5e..36ace737 100644 --- a/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.cc +++ b/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.cc
@@ -356,25 +356,28 @@ bool CompositingReasonFinder::RequiresCompositingForScrollDependentPosition( const PaintLayer& layer) { - const auto& layout_object = layer.GetLayoutObject(); - if (!layout_object.StyleRef().HasViewportConstrainedPosition() && - !layout_object.StyleRef().HasStickyConstrainedPosition()) - return false; - // Don't promote fixed position elements that are descendants of a non-view // container, e.g. transformed elements. They will stay fixed wrt the // container rather than the enclosing frame. - EPosition position = layout_object.StyleRef().GetPosition(); - if (position == EPosition::kFixed) { - return layer.FixedToViewport() && - layout_object.GetFrameView()->LayoutViewport()->ScrollsOverflow(); + if (layer.FixedToViewport()) { + // We check for |HasOverflow| instead of |ScrollsOverflow| to ensure fixed + // position elements are composited under overflow: hidden, which can still + // have smooth scroll animations. + LocalFrameView* frame_view = layer.GetLayoutObject().GetFrameView(); + return frame_view->LayoutViewport()->HasOverflow(); } - DCHECK_EQ(position, EPosition::kSticky); // Don't promote sticky position elements that cannot move with scrolls. - if (!layer.SticksToScroller()) - return false; - return layer.AncestorScrollContainerLayer()->ScrollsOverflow(); + if (layer.SticksToScroller()) { + // We check for |HasOverflow| instead of |ScrollsOverflow| to ensure sticky + // position elements are composited under overflow: hidden, which can still + // have smooth scroll animations. + return layer.AncestorScrollContainerLayer() + ->GetScrollableArea() + ->HasOverflow(); + } + + return false; } } // namespace blink
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder_test.cc b/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder_test.cc index ca9787a1..44f8635 100644 --- a/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder_test.cc +++ b/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder_test.cc
@@ -102,9 +102,25 @@ TEST_F(CompositingReasonFinderTest, OnlyScrollingStickyPositionPromoted) { SetBodyInnerHTML(R"HTML( - <style>.scroller {width: 400px; height: 400px; overflow: auto; - will-change: transform;} - .sticky { position: sticky; top: 0; width: 10px; height: 10px;} + <style> + .scroller { + width: 400px; + height: 400px; + overflow: auto; + will-change: transform; + } + .sticky { + position: sticky; + top: 0; + width: 10px; + height: 10px; + } + .overflow-hidden { + width: 400px; + height: 400px; + overflow: hidden; + will-change: transform; + } </style> <div class='scroller'> <div id='sticky-scrolling' class='sticky'></div> @@ -113,14 +129,49 @@ <div class='scroller'> <div id='sticky-no-scrolling' class='sticky'></div> </div> + <div class='overflow-hidden'> + <div id='overflow-hidden-scrolling' class='sticky'></div> + <div style='height: 2000px;'></div> + </div> + <div class='overflow-hidden'> + <div id='overflow-hidden-no-scrolling' class='sticky'></div> + </div> )HTML"); - EXPECT_EQ( - kPaintsIntoOwnBacking, - GetPaintLayerByElementId("sticky-scrolling")->GetCompositingState()); - EXPECT_EQ( - kNotComposited, - GetPaintLayerByElementId("sticky-no-scrolling")->GetCompositingState()); + auto& sticky_scrolling = + *To<LayoutBoxModelObject>(GetLayoutObjectByElementId("sticky-scrolling")); + EXPECT_TRUE( + CompositingReasonFinder::RequiresCompositingForScrollDependentPosition( + *sticky_scrolling.Layer())); + + auto& sticky_no_scrolling = *To<LayoutBoxModelObject>( + GetLayoutObjectByElementId("sticky-no-scrolling")); + EXPECT_FALSE( + CompositingReasonFinder::RequiresCompositingForScrollDependentPosition( + *sticky_no_scrolling.Layer())); + + auto& overflow_hidden_scrolling = *To<LayoutBoxModelObject>( + GetLayoutObjectByElementId("overflow-hidden-scrolling")); + EXPECT_TRUE( + CompositingReasonFinder::RequiresCompositingForScrollDependentPosition( + *overflow_hidden_scrolling.Layer())); + + auto& overflow_hidden_no_scrolling = *To<LayoutBoxModelObject>( + GetLayoutObjectByElementId("overflow-hidden-no-scrolling")); + EXPECT_FALSE( + CompositingReasonFinder::RequiresCompositingForScrollDependentPosition( + *overflow_hidden_no_scrolling.Layer())); + + if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) { + EXPECT_EQ(kPaintsIntoOwnBacking, + sticky_scrolling.Layer()->GetCompositingState()); + EXPECT_EQ(kNotComposited, + sticky_no_scrolling.Layer()->GetCompositingState()); + EXPECT_EQ(kPaintsIntoOwnBacking, + overflow_hidden_scrolling.Layer()->GetCompositingState()); + EXPECT_EQ(kNotComposited, + overflow_hidden_no_scrolling.Layer()->GetCompositingState()); + } } void CompositingReasonFinderTest::CheckCompositingReasonsForAnimation(
diff --git a/third_party/blink/renderer/core/paint/inline_text_box_painter.cc b/third_party/blink/renderer/core/paint/inline_text_box_painter.cc index 081b466..9eb2f32 100644 --- a/third_party/blink/renderer/core/paint/inline_text_box_painter.cc +++ b/third_party/blink/renderer/core/paint/inline_text_box_painter.cc
@@ -22,6 +22,7 @@ #include "third_party/blink/renderer/core/paint/highlight_painting_utils.h" #include "third_party/blink/renderer/core/paint/paint_info.h" #include "third_party/blink/renderer/core/paint/paint_timing_detector.h" +#include "third_party/blink/renderer/core/paint/selection_bounds_recorder.h" #include "third_party/blink/renderer/core/paint/text_decoration_info.h" #include "third_party/blink/renderer/core/paint/text_painter.h" #include "third_party/blink/renderer/platform/graphics/dom_node_id.h" @@ -153,18 +154,6 @@ physical_overflow.Move(paint_offset); IntRect visual_rect = EnclosingIntRect(physical_overflow); - // The text clip phase already has a DrawingRecorder. Text clips are initiated - // only in BoxPainter::PaintFillLayer, which is already within a - // DrawingRecorder. - base::Optional<DrawingRecorder> recorder; - if (paint_info.phase != PaintPhase::kTextClip) { - if (DrawingRecorder::UseCachedDrawingIfPossible( - paint_info.context, inline_text_box_, paint_info.phase)) - return; - recorder.emplace(paint_info.context, inline_text_box_, paint_info.phase, - visual_rect); - } - GraphicsContext& context = paint_info.context; PhysicalOffset box_origin = inline_text_box_.PhysicalLocation() + paint_offset; @@ -182,6 +171,35 @@ PhysicalSize(inline_text_box_.LogicalWidth(), inline_text_box_.LogicalHeight())); + base::Optional<SelectionBoundsRecorder> selection_recorder; + if (have_selection && paint_info.phase == PaintPhase::kForeground && + !is_printing) { + const FrameSelection& frame_selection = + InlineLayoutObject().GetFrame()->Selection(); + SelectionState selection_state = + frame_selection.ComputeLayoutSelectionStateForInlineTextBox( + inline_text_box_); + if (SelectionBoundsRecorder::ShouldRecordSelection(frame_selection, + selection_state)) { + PhysicalRect selection_rect = + GetSelectionRect<InlineTextBoxPainter::PaintOptions::kNormal>( + context, box_rect, style_to_use, style_to_use.GetFont()); + selection_recorder.emplace(selection_state, selection_rect, + context.GetPaintController()); + } + } + + // The text clip phase already has a DrawingRecorder. Text clips are initiated + // only in BoxPainter::PaintFillLayer, which is already within a + // DrawingRecorder. + base::Optional<DrawingRecorder> recorder; + if (paint_info.phase != PaintPhase::kTextClip) { + if (DrawingRecorder::UseCachedDrawingIfPossible(context, inline_text_box_, + paint_info.phase)) + return; + recorder.emplace(context, inline_text_box_, paint_info.phase, visual_rect); + } + unsigned length = inline_text_box_.Len(); const String& layout_item_string = inline_text_box_.GetLineLayoutItem().GetText();
diff --git a/third_party/blink/renderer/core/paint/inline_text_box_painter_test.cc b/third_party/blink/renderer/core/paint/inline_text_box_painter_test.cc index 9754276f..1b505e57 100644 --- a/third_party/blink/renderer/core/paint/inline_text_box_painter_test.cc +++ b/third_party/blink/renderer/core/paint/inline_text_box_painter_test.cc
@@ -6,6 +6,7 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/core/editing/testing/selection_sample.h" #include "third_party/blink/renderer/core/paint/paint_controller_paint_test.h" using testing::ElementsAre; @@ -27,4 +28,64 @@ EXPECT_EQ(6u, ContentDisplayItems().size()); } +class InlineTextBoxPainterNonNGTest : public PaintControllerPaintTest, + public ScopedLayoutNGForTest { + public: + InlineTextBoxPainterNonNGTest() : ScopedLayoutNGForTest(false) {} +}; + +INSTANTIATE_PAINT_TEST_SUITE_P(InlineTextBoxPainterNonNGTest); + +TEST_P(InlineTextBoxPainterNonNGTest, RecordedSelectionAll) { + if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) + return; + SetBodyInnerHTML("<span>A<br>B<br>C</span>"); + + GetDocument().GetFrame()->Selection().SetHandleVisibleForTesting(); + GetDocument().GetFrame()->Selection().SelectAll(); + UpdateAllLifecyclePhasesForTest(); + + auto chunks = ContentPaintChunks(); + EXPECT_EQ(chunks.size(), 1u); + EXPECT_TRUE(chunks.begin()->layer_selection_data->start.has_value()); + EXPECT_TRUE(chunks.begin()->layer_selection_data->end.has_value()); + PaintedSelectionBound start = + chunks.begin()->layer_selection_data->start.value(); + EXPECT_EQ(start.type, gfx::SelectionBound::LEFT); + EXPECT_EQ(start.edge_start, IntPoint(8, 8)); + EXPECT_EQ(start.edge_end, IntPoint(8, 9)); + + PaintedSelectionBound end = chunks.begin()->layer_selection_data->end.value(); + EXPECT_EQ(end.type, gfx::SelectionBound::RIGHT); + EXPECT_EQ(end.edge_start, IntPoint(9, 10)); + EXPECT_EQ(end.edge_end, IntPoint(9, 11)); +} + +TEST_P(InlineTextBoxPainterNonNGTest, RecordedSelectionMultiline) { + if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) + return; + + GetDocument().GetFrame()->Selection().SetSelectionAndEndTyping( + SelectionSample::SetSelectionText( + GetDocument().body(), + "<div style='white-space:pre'>f^oo\nbar\nb|az</div>")); + GetDocument().GetFrame()->Selection().SetHandleVisibleForTesting(); + UpdateAllLifecyclePhasesForTest(); + + auto chunks = ContentPaintChunks(); + EXPECT_EQ(chunks.size(), 1u); + EXPECT_TRUE(chunks.begin()->layer_selection_data->start.has_value()); + EXPECT_TRUE(chunks.begin()->layer_selection_data->end.has_value()); + PaintedSelectionBound start = + chunks.begin()->layer_selection_data->start.value(); + EXPECT_EQ(start.type, gfx::SelectionBound::LEFT); + EXPECT_EQ(start.edge_start, IntPoint(8, 8)); + EXPECT_EQ(start.edge_end, IntPoint(8, 9)); + + PaintedSelectionBound end = chunks.begin()->layer_selection_data->end.value(); + EXPECT_EQ(end.type, gfx::SelectionBound::RIGHT); + EXPECT_EQ(end.edge_start, IntPoint(9, 10)); + EXPECT_EQ(end.edge_end, IntPoint(9, 11)); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc b/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc index 0b1a6df..9b6f31e 100644 --- a/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc +++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc
@@ -5909,7 +5909,7 @@ EXPECT_EQ(3u, NumFragments(fixed)); for (int i = 0; i < 3; i++) { const auto& fragment = FragmentAt(fixed, i); - EXPECT_EQ(PhysicalOffset(20, -180 + i * 400), fragment.PaintOffset()); + EXPECT_EQ(PhysicalOffset(0, 0), fragment.PaintOffset()); EXPECT_EQ(LayoutUnit(400 * i), fragment.LogicalTopInFlowThread()); } @@ -5917,7 +5917,7 @@ EXPECT_EQ(3u, NumFragments(fixed_child)); for (int i = 0; i < 3; i++) { const auto& fragment = FragmentAt(fixed_child, i); - EXPECT_EQ(PhysicalOffset(20, -170 + i * 400), fragment.PaintOffset()); + EXPECT_EQ(PhysicalOffset(0, 10), fragment.PaintOffset()); EXPECT_EQ(LayoutUnit(i * 400), fragment.LogicalTopInFlowThread()); }
diff --git a/third_party/blink/renderer/core/paint/paint_timing_detector.cc b/third_party/blink/renderer/core/paint/paint_timing_detector.cc index 94839d6..7842dfc 100644 --- a/third_party/blink/renderer/core/paint/paint_timing_detector.cc +++ b/third_party/blink/renderer/core/paint/paint_timing_detector.cc
@@ -440,7 +440,6 @@ visitor->Trace(frame_view_); visitor->Trace(largest_contentful_paint_calculator_); visitor->Trace(callback_manager_); - visitor->Trace(visualizer_); } void PaintTimingCallbackManagerImpl::
diff --git a/third_party/blink/renderer/core/paint/text_paint_timing_detector.cc b/third_party/blink/renderer/core/paint/text_paint_timing_detector.cc index 134f8ea..a894531 100644 --- a/third_party/blink/renderer/core/paint/text_paint_timing_detector.cc +++ b/third_party/blink/renderer/core/paint/text_paint_timing_detector.cc
@@ -257,7 +257,7 @@ } void TextRecordsManager::CleanUpLargestTextPaint() { - ltp_manager_.reset(); + ltp_manager_.Clear(); } void TextRecordsManager::RemoveInvisibleRecord(const LayoutObject& object) { @@ -370,9 +370,10 @@ TextRecordsManager::TextRecordsManager( LocalFrameView* frame_view, - PaintTimingDetector* paint_timing_detector) { - ltp_manager_.emplace(frame_view, paint_timing_detector); -} + PaintTimingDetector* paint_timing_detector) + : ltp_manager_(MakeGarbageCollected<LargestTextPaintManager>( + frame_view, + paint_timing_detector)) {} void TextRecordsManager::Trace(Visitor* visitor) const { visitor->Trace(text_element_timing_);
diff --git a/third_party/blink/renderer/core/paint/text_paint_timing_detector.h b/third_party/blink/renderer/core/paint/text_paint_timing_detector.h index cfac87e..02e075f2 100644 --- a/third_party/blink/renderer/core/paint/text_paint_timing_detector.h +++ b/third_party/blink/renderer/core/paint/text_paint_timing_detector.h
@@ -47,8 +47,8 @@ base::TimeTicks paint_time = base::TimeTicks(); }; -class CORE_EXPORT LargestTextPaintManager { - DISALLOW_NEW(); +class CORE_EXPORT LargestTextPaintManager final + : public GarbageCollected<LargestTextPaintManager> { using TextRecordSetComparator = bool (*)(const base::WeakPtr<TextRecord>&, const base::WeakPtr<TextRecord>&); using TextRecordSet = @@ -173,9 +173,7 @@ // candidate. void ReportLargestIgnoredText(); - inline bool IsRecordingLargestTextPaint() const { - return ltp_manager_.has_value(); - } + inline bool IsRecordingLargestTextPaint() const { return ltp_manager_; } void Trace(Visitor*) const; @@ -198,7 +196,7 @@ // LCP computations, even if the size of the text itself is not 0. They are // considered invisible objects by Largest Contentful Paint. Deque<std::unique_ptr<TextRecord>> size_zero_texts_queued_for_paint_time_; - base::Optional<LargestTextPaintManager> ltp_manager_; + Member<LargestTextPaintManager> ltp_manager_; Member<TextElementTiming> text_element_timing_; };
diff --git a/third_party/blink/renderer/core/paint/text_paint_timing_detector_test.cc b/third_party/blink/renderer/core/paint/text_paint_timing_detector_test.cc index b1d297f..01e3ead 100644 --- a/third_party/blink/renderer/core/paint/text_paint_timing_detector_test.cc +++ b/third_party/blink/renderer/core/paint/text_paint_timing_detector_test.cc
@@ -73,7 +73,7 @@ .GetTextPaintTimingDetector(); } - base::Optional<LargestTextPaintManager>& GetLargestTextPaintManager() { + LargestTextPaintManager* GetLargestTextPaintManager() { return GetTextPaintTimingDetector()->records_manager_.ltp_manager_; }
diff --git a/third_party/blink/renderer/core/testing/dictionary_test.cc b/third_party/blink/renderer/core/testing/dictionary_test.cc index 15f6ecf..f8e2116 100644 --- a/third_party/blink/renderer/core/testing/dictionary_test.cc +++ b/third_party/blink/renderer/core/testing/dictionary_test.cc
@@ -66,8 +66,10 @@ enum_or_null_member_ = testing_dictionary->enumOrNullMember(); if (testing_dictionary->hasElementMember()) element_member_ = testing_dictionary->elementMember(); - if (testing_dictionary->hasElementOrNullMember()) + if (testing_dictionary->hasElementOrNullMember()) { element_or_null_member_ = testing_dictionary->elementOrNullMember(); + has_element_or_null_member_ = true; + } if (testing_dictionary->hasObjectMember()) object_member_ = testing_dictionary->objectMember(); object_or_null_member_with_default_ = @@ -75,7 +77,9 @@ if (testing_dictionary->hasDoubleOrStringMember()) double_or_string_member_ = testing_dictionary->doubleOrStringMember(); if (testing_dictionary->hasDoubleOrStringSequenceMember()) { - double_or_string_sequence_member_ = + double_or_string_sequence_or_null_member_ = + MakeGarbageCollected<HeapVector<DoubleOrString>>(); + *double_or_string_sequence_or_null_member_ = testing_dictionary->doubleOrStringSequenceMember(); } // eventTargetOrNullMember has a default null value. @@ -149,10 +153,12 @@ enum_member_with_default_ = String(); enum_or_null_member_ = base::nullopt; element_member_ = nullptr; - element_or_null_member_.reset(); + element_or_null_member_.Clear(); + has_element_or_null_member_ = false; object_member_ = ScriptValue(); object_or_null_member_with_default_ = ScriptValue(); double_or_string_member_ = DoubleOrString(); + double_or_string_sequence_or_null_member_ = nullptr; event_target_or_null_member_ = nullptr; derived_string_member_ = base::nullopt; derived_string_member_with_default_ = String(); @@ -211,15 +217,15 @@ dict->setEnumOrNullMember(enum_or_null_member_.value()); if (element_member_) dict->setElementMember(element_member_); - if (element_or_null_member_.has_value()) - dict->setElementOrNullMember(element_or_null_member_.value()); + if (has_element_or_null_member_) + dict->setElementOrNullMember(element_or_null_member_); dict->setObjectMember(object_member_); dict->setObjectOrNullMemberWithDefault(object_or_null_member_with_default_); if (!double_or_string_member_.IsNull()) dict->setDoubleOrStringMember(double_or_string_member_); - if (double_or_string_sequence_member_) { + if (double_or_string_sequence_or_null_member_) { dict->setDoubleOrStringSequenceMember( - double_or_string_sequence_member_.value()); + *double_or_string_sequence_or_null_member_); } dict->setEventTargetOrNullMember(event_target_or_null_member_); dict->setInternalEnumOrInternalEnumSequenceMember( @@ -251,7 +257,7 @@ visitor->Trace(element_or_null_member_); visitor->Trace(object_member_); visitor->Trace(object_or_null_member_with_default_); - visitor->Trace(double_or_string_sequence_member_); + visitor->Trace(double_or_string_sequence_or_null_member_); visitor->Trace(event_target_or_null_member_); visitor->Trace(any_member_); visitor->Trace(callback_function_member_);
diff --git a/third_party/blink/renderer/core/testing/dictionary_test.h b/third_party/blink/renderer/core/testing/dictionary_test.h index 1840a36..5bbd24c5 100644 --- a/third_party/blink/renderer/core/testing/dictionary_test.h +++ b/third_party/blink/renderer/core/testing/dictionary_test.h
@@ -56,6 +56,8 @@ // Some members are not wrapped with Optional because: // - |longMemberWithDefault| has a non-null default value // - String and PtrTypes can express whether they are null + // - base::Optional does not work with GarbageCollected types when used on + // heap. base::Optional<int> long_member_; base::Optional<int> long_member_with_clamp_; base::Optional<int> long_member_with_enforce_range_; @@ -82,11 +84,12 @@ base::Optional<String> enum_or_null_member_; #endif Member<Element> element_member_; - base::Optional<Member<Element>> element_or_null_member_; + Member<Element> element_or_null_member_; + bool has_element_or_null_member_ = false; ScriptValue object_member_; ScriptValue object_or_null_member_with_default_; DoubleOrString double_or_string_member_; - base::Optional<HeapVector<DoubleOrString>> double_or_string_sequence_member_; + Member<HeapVector<DoubleOrString>> double_or_string_sequence_or_null_member_; Member<EventTarget> event_target_or_null_member_; base::Optional<String> derived_string_member_; String derived_string_member_with_default_;
diff --git a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc index b060f21..fe114147 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
@@ -1495,21 +1495,6 @@ return kExpandedUndefined; } -bool AXNodeObject::IsModal() const { - if (RoleValue() != ax::mojom::blink::Role::kDialog && - RoleValue() != ax::mojom::blink::Role::kAlertDialog) - return false; - - bool modal = false; - if (HasAOMPropertyOrARIAAttribute(AOMBooleanProperty::kModal, modal)) - return modal; - - if (GetNode() && IsA<HTMLDialogElement>(*GetNode())) - return To<Element>(GetNode())->IsInTopLayer(); - - return false; -} - bool AXNodeObject::IsRequired() const { auto* form_control = DynamicTo<HTMLFormControlElement>(GetNode()); if (form_control && form_control->IsRequired())
diff --git a/third_party/blink/renderer/modules/accessibility/ax_node_object.h b/third_party/blink/renderer/modules/accessibility/ax_node_object.h index 124ca76..9df431f 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_node_object.h +++ b/third_party/blink/renderer/modules/accessibility/ax_node_object.h
@@ -119,7 +119,6 @@ // Check object state. bool IsClickable() const final; AccessibilityExpanded IsExpanded() const override; - bool IsModal() const final; bool IsRequired() const final; bool IsControl() const override; AXRestriction Restriction() const override;
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.cc b/third_party/blink/renderer/modules/accessibility/ax_object.cc index b4aeb2fd..7a0b5ab6 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_object.cc
@@ -1690,6 +1690,22 @@ return false; } +bool AXObject::IsModal() const { + if (RoleValue() != ax::mojom::blink::Role::kDialog && + RoleValue() != ax::mojom::blink::Role::kAlertDialog) + return false; + + bool modal = false; + if (HasAOMPropertyOrARIAAttribute(AOMBooleanProperty::kModal, modal)) { + return modal; + } + + if (GetNode() && IsA<HTMLDialogElement>(*GetNode())) + return To<Element>(GetNode())->IsInTopLayer(); + + return false; +} + bool AXObject::IsBlockedByAriaModalDialog( IgnoredReasons* ignored_reasons) const { AXObject* active_aria_modal_dialog =
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.h b/third_party/blink/renderer/modules/accessibility/ax_object.h index 926e219..61e7017 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object.h +++ b/third_party/blink/renderer/modules/accessibility/ax_object.h
@@ -473,7 +473,7 @@ virtual bool IsLineBreakingObject() const { return false; } virtual bool IsLinked() const { return false; } virtual bool IsLoaded() const { return false; } - virtual bool IsModal() const { return false; } + virtual bool IsModal() const; virtual bool IsMultiSelectable() const { return false; } virtual bool IsOffScreen() const { return false; } virtual bool IsRequired() const { return false; }
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.h b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.h index 2510f01..237a1a8a 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.h +++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.h
@@ -24,6 +24,12 @@ class CSSValue; class Element; +enum ShadowMode { + kDrawShadowAndForeground, + kDrawShadowOnly, + kDrawForegroundOnly +}; + class CanvasRenderingContext2DState final : public GarbageCollected<CanvasRenderingContext2DState>, public FontSelectorClient {
diff --git a/third_party/blink/renderer/modules/exported/web_ax_object.cc b/third_party/blink/renderer/modules/exported/web_ax_object.cc index 0bb1729..886a782 100644 --- a/third_party/blink/renderer/modules/exported/web_ax_object.cc +++ b/third_party/blink/renderer/modules/exported/web_ax_object.cc
@@ -1443,12 +1443,9 @@ } // static -WebAXObject WebAXObject::FromWebDocument(const WebDocument& web_document, - bool update_layout_if_necessary) { - if (update_layout_if_necessary && - !MaybeUpdateLayoutAndCheckValidity(web_document)) { +WebAXObject WebAXObject::FromWebDocument(const WebDocument& web_document) { + if (!MaybeUpdateLayoutAndCheckValidity(web_document)) return WebAXObject(); - } const Document* document = web_document.ConstUnwrap<Document>(); auto* cache = To<AXObjectCacheImpl>(document->ExistingAXObjectCache()); return cache ? WebAXObject(cache->GetOrCreate(document->GetLayoutView()))
diff --git a/third_party/blink/renderer/modules/mediasource/media_source.cc b/third_party/blink/renderer/modules/mediasource/media_source.cc index 8a61a4e..db69f38 100644 --- a/third_party/blink/renderer/modules/mediasource/media_source.cc +++ b/third_party/blink/renderer/modules/mediasource/media_source.cc
@@ -133,7 +133,9 @@ active_source_buffers_( MakeGarbageCollected<SourceBufferList>(GetExecutionContext(), async_event_queue_.Get())), - live_seekable_range_(MakeGarbageCollected<TimeRanges>()) { + has_live_seekable_range_(false), + live_seekable_range_start_(0.0), + live_seekable_range_end_(0.0) { DVLOG(1) << __func__ << " this=" << this; DCHECK(RuntimeEnabledFeatures::MediaSourceInWorkersEnabled() || @@ -667,11 +669,13 @@ void MediaSource::Trace(Visitor* visitor) const { visitor->Trace(async_event_queue_); - { - MutexLocker lock(attachment_link_lock_); - visitor->Trace(attachment_tracer_); - visitor->Trace(live_seekable_range_); - } + + // |attachment_tracer_| is only set when this object is owned by the main + // thread and is possibly involved in a SameThreadMediaSourceAttachment. + // Therefore, it is thread-safe to access it here without taking the + // |attachment_link_lock_|. + visitor->Trace(TS_UNCHECKED_READ(attachment_tracer_)); + visitor->Trace(source_buffers_); visitor->Trace(active_source_buffers_); EventTargetWithInlineData::Trace(visitor); @@ -800,29 +804,26 @@ { // If cross-thread, protect against concurrent usage of - // |live_seekable_range_|, since that member is updated without taking the + // |*live_seekable_range*|, since those are updated without taking the // attachment's internal |attachment_state_lock_|. MutexLocker lock(attachment_link_lock_); // 1. If live seekable range is not empty: - if (live_seekable_range_->length() != 0) { + if (has_live_seekable_range_) { // 1.1. Let union ranges be the union of live seekable range and the // HTMLMediaElement.buffered attribute. // 1.2. Return a single range with a start time equal to the // earliest start time in union ranges and an end time equal to // the highest end time in union ranges and abort these steps. if (buffered.empty()) { - ranges.emplace_back( - live_seekable_range_->start(0, ASSERT_NO_EXCEPTION), - live_seekable_range_->end(0, ASSERT_NO_EXCEPTION)); + ranges.emplace_back(live_seekable_range_start_, + live_seekable_range_end_); return ranges; } ranges.emplace_back( - std::min(live_seekable_range_->start(0, ASSERT_NO_EXCEPTION), - buffered.front().start), - std::max(live_seekable_range_->end(0, ASSERT_NO_EXCEPTION), - buffered.back().end)); + std::min(live_seekable_range_start_, buffered.front().start), + std::max(live_seekable_range_end_, buffered.back().end)); return ranges; } } @@ -1089,10 +1090,12 @@ // SeekableInternal simultaneously, if attached fully. Here, for simplicity, // we don't need to take the full attachment exclusive // |attachment_state_lock_| so long as we - // fully protect access to |live_seekable_range_| read/write with + // fully protect access to |*live_seekable_range*| read/write with // |attachment_link_lock_|. MutexLocker lock(attachment_link_lock_); - live_seekable_range_ = MakeGarbageCollected<TimeRanges>(start, end); + has_live_seekable_range_ = true; + live_seekable_range_start_ = start; + live_seekable_range_end_ = end; } } @@ -1116,12 +1119,15 @@ // If we are cross-thread, then main thread could be running // SeekableInternal simultaneously, if attached fully. Here, for simplicity, // we don't need to take the full attachment exclusive - // |attachment_state_lock_|so long as we - // fully protect access to |live_seekable_range_| read/write with + // |attachment_state_lock_| so long as we + // fully protect access to |*live_seekable_range*| read/write with // |attachment_link_lock_|. MutexLocker lock(attachment_link_lock_); - if (live_seekable_range_->length() != 0) - live_seekable_range_ = MakeGarbageCollected<TimeRanges>(); + if (has_live_seekable_range_) { + has_live_seekable_range_ = false; + live_seekable_range_start_ = 0.0; + live_seekable_range_end_ = 0.0; + } } }
diff --git a/third_party/blink/renderer/modules/mediasource/media_source.h b/third_party/blink/renderer/modules/mediasource/media_source.h index e9e4f62..2866b90 100644 --- a/third_party/blink/renderer/modules/mediasource/media_source.h +++ b/third_party/blink/renderer/modules/mediasource/media_source.h
@@ -264,7 +264,7 @@ // |attachment_link_lock_| protects read/write of |media_source_attachment_|, // |attachment_tracer_|, |context_already_destroyed_|, and - // |live_seekable_range_|. It is only truly necessary for + // |*live_seekable_range*_|. It is only truly necessary for // CrossThreadAttachment usage of worker MSE, to prevent read/write collision // on main thread versus worker thread. Note that |attachment_link_lock_| must // be released before attempting CrossThreadMediaSourceAttachment @@ -289,7 +289,11 @@ Member<SourceBufferList> source_buffers_; Member<SourceBufferList> active_source_buffers_; - Member<TimeRanges> live_seekable_range_ GUARDED_BY(attachment_link_lock_); + // These are kept as raw data (not an Oilpan managed GC-able TimeRange) to + // avoid need to take lock during ::Trace, which could lead to deadlock. + bool has_live_seekable_range_ GUARDED_BY(attachment_link_lock_); + double live_seekable_range_start_ GUARDED_BY(attachment_link_lock_); + double live_seekable_range_end_ GUARDED_BY(attachment_link_lock_); }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/mediasource/track_default_list.cc b/third_party/blink/renderer/modules/mediasource/track_default_list.cc index 4a4bb665..a1c58cab 100644 --- a/third_party/blink/renderer/modules/mediasource/track_default_list.cc +++ b/third_party/blink/renderer/modules/mediasource/track_default_list.cc
@@ -59,8 +59,6 @@ return track_defaults_[index].Get(); } -TrackDefaultList::TrackDefaultList() = default; - TrackDefaultList::TrackDefaultList( const HeapVector<Member<TrackDefault>>& track_defaults) : track_defaults_(track_defaults) {}
diff --git a/third_party/blink/renderer/modules/mediasource/track_default_list.h b/third_party/blink/renderer/modules/mediasource/track_default_list.h index a3d7b4a..e558f6d 100644 --- a/third_party/blink/renderer/modules/mediasource/track_default_list.h +++ b/third_party/blink/renderer/modules/mediasource/track_default_list.h
@@ -21,7 +21,7 @@ static TrackDefaultList* Create(const HeapVector<Member<TrackDefault>>&, ExceptionState&); - TrackDefaultList(); + TrackDefaultList() = default; explicit TrackDefaultList(const HeapVector<Member<TrackDefault>>&); unsigned length() const { return track_defaults_.size(); } @@ -30,7 +30,7 @@ void Trace(Visitor*) const override; private: - const HeapVector<Member<TrackDefault>> track_defaults_; + const HeapVector<Member<TrackDefault>> track_defaults_{}; }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/webcodecs/BUILD.gn b/third_party/blink/renderer/modules/webcodecs/BUILD.gn index 5ad6f8c5..834d7c1 100644 --- a/third_party/blink/renderer/modules/webcodecs/BUILD.gn +++ b/third_party/blink/renderer/modules/webcodecs/BUILD.gn
@@ -13,6 +13,8 @@ "audio_decoder.h", "audio_decoder_broker.cc", "audio_decoder_broker.h", + "audio_encoder.cc", + "audio_encoder.h", "audio_frame.cc", "audio_frame.h", "codec_config_eval.h",
diff --git a/third_party/blink/renderer/modules/webcodecs/audio_decoder.cc b/third_party/blink/renderer/modules/webcodecs/audio_decoder.cc index 38014a9..629c57b1 100644 --- a/third_party/blink/renderer/modules/webcodecs/audio_decoder.cc +++ b/third_party/blink/renderer/modules/webcodecs/audio_decoder.cc
@@ -14,6 +14,7 @@ #include "media/base/supported_types.h" #include "media/base/waiting.h" #include "third_party/blink/public/mojom/web_feature/web_feature.mojom-blink.h" +#include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_audio_decoder_config.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_audio_decoder_init.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_encoded_audio_chunk.h" @@ -27,6 +28,28 @@ namespace blink { +bool IsValidConfig(const AudioDecoderConfig& config, + media::AudioType& out_audio_type, + String& out_console_message) { + media::AudioCodec codec = media::kUnknownAudioCodec; + bool is_codec_ambiguous = true; + bool parse_succeeded = ParseAudioCodecString("", config.codec().Utf8(), + &is_codec_ambiguous, &codec); + + if (!parse_succeeded) { + out_console_message = "Failed to parse codec string."; + return false; + } + + if (is_codec_ambiguous) { + out_console_message = "Codec string is ambiguous."; + return false; + } + + out_audio_type = {codec}; + return true; +} + // static std::unique_ptr<AudioDecoderTraits::MediaDecoderType> AudioDecoderTraits::CreateDecoder( @@ -82,29 +105,30 @@ } // static +ScriptPromise AudioDecoder::isConfigSupported(ScriptState* script_state, + const AudioDecoderConfig* config, + ExceptionState& exception_state) { + media::AudioType audio_type; + String console_message; + + if (!IsValidConfig(*config, audio_type, console_message)) { + exception_state.ThrowTypeError(console_message); + return ScriptPromise(); + } + + bool is_supported = media::IsSupportedAudioType(audio_type); + return ScriptPromise::Cast(script_state, ToV8(is_supported, script_state)); +} + +// static CodecConfigEval AudioDecoder::MakeMediaAudioDecoderConfig( const ConfigType& config, MediaConfigType& out_media_config, String& out_console_message) { - media::AudioCodec codec = media::kUnknownAudioCodec; - bool is_codec_ambiguous = true; - bool parse_succeeded = ParseAudioCodecString("", config.codec().Utf8(), - &is_codec_ambiguous, &codec); + media::AudioType audio_type; - if (!parse_succeeded) { - out_console_message = "Failed to parse codec string."; + if (!IsValidConfig(config, audio_type, out_console_message)) return CodecConfigEval::kInvalid; - } - - if (is_codec_ambiguous) { - out_console_message = "Codec string is ambiguous."; - return CodecConfigEval::kInvalid; - } - - if (!media::IsSupportedAudioType({codec})) { - out_console_message = "Configuration is not supported."; - return CodecConfigEval::kUnsupported; - } std::vector<uint8_t> extra_data; if (config.hasDescription()) { @@ -131,8 +155,8 @@ // TODO(chcunningham): Add sample format to IDL. out_media_config.Initialize( - codec, media::kSampleFormatPlanarF32, channel_layout, config.sampleRate(), - extra_data, media::EncryptionScheme::kUnencrypted, + audio_type.codec, media::kSampleFormatPlanarF32, channel_layout, + config.sampleRate(), extra_data, media::EncryptionScheme::kUnencrypted, base::TimeDelta() /* seek preroll */, 0 /* codec delay */); return CodecConfigEval::kSupported;
diff --git a/third_party/blink/renderer/modules/webcodecs/audio_decoder.h b/third_party/blink/renderer/modules/webcodecs/audio_decoder.h index e6417a7..c148d102 100644 --- a/third_party/blink/renderer/modules/webcodecs/audio_decoder.h +++ b/third_party/blink/renderer/modules/webcodecs/audio_decoder.h
@@ -12,7 +12,6 @@ #include "media/base/status.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" -#include "third_party/blink/renderer/bindings/modules/v8/v8_video_frame_output_callback.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_webcodecs_error_callback.h" #include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/modules/webcodecs/codec_config_eval.h" @@ -38,6 +37,7 @@ class EncodedAudioChunk; class ExceptionState; class AudioDecoderInit; +class ScriptPromise; class V8AudioFrameOutputCallback; class MODULES_EXPORT AudioDecoderTraits { @@ -77,6 +77,10 @@ const AudioDecoderInit*, ExceptionState&); + static ScriptPromise isConfigSupported(ScriptState*, + const AudioDecoderConfig*, + ExceptionState&); + // For use by MediaSource and by ::MakeMediaConfig. static CodecConfigEval MakeMediaAudioDecoderConfig( const ConfigType& config,
diff --git a/third_party/blink/renderer/modules/webcodecs/audio_decoder.idl b/third_party/blink/renderer/modules/webcodecs/audio_decoder.idl index 7201cd2..7f03b2a5 100644 --- a/third_party/blink/renderer/modules/webcodecs/audio_decoder.idl +++ b/third_party/blink/renderer/modules/webcodecs/audio_decoder.idl
@@ -23,6 +23,9 @@ // |decodeQueueSize| is greater than a constant. readonly attribute long decodeQueueSize; + // Which state the decoder is in, indicating which methods can be called. + readonly attribute CodecState state; + // Set the stream configuration for future decode() requests. // // The next decode request must be for a keyframe. @@ -57,6 +60,7 @@ // Not recoverable: make a new AudioDecoder if needed. [RaisesException] void close(); - // Which state the decoder is in, indicating which methods can be called. - readonly attribute CodecState state; + // Call prior to configure() to determine whether config will be supported. + [CallWith=ScriptState, RaisesException] + static Promise<boolean> isConfigSupported(AudioDecoderConfig config); };
diff --git a/third_party/blink/renderer/modules/webcodecs/audio_encoder.cc b/third_party/blink/renderer/modules/webcodecs/audio_encoder.cc new file mode 100644 index 0000000..de3cb2b --- /dev/null +++ b/third_party/blink/renderer/modules/webcodecs/audio_encoder.cc
@@ -0,0 +1,50 @@ +// 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 "third_party/blink/renderer/modules/webcodecs/audio_encoder.h" + +namespace blink { + +AudioEncoder* AudioEncoder::Create(ScriptState* script_state, + const AudioEncoderInit* init, + ExceptionState& exception_state) { + return MakeGarbageCollected<AudioEncoder>(script_state, init, + exception_state); +} + +AudioEncoder::AudioEncoder(ScriptState* script_state, + const AudioEncoderInit* init, + ExceptionState& exception_state) + : ExecutionContextLifecycleObserver(ExecutionContext::From(script_state)) {} + +AudioEncoder::~AudioEncoder() = default; + +int32_t AudioEncoder::encodeQueueSize() { + return 0; +} + +void AudioEncoder::encode(AudioFrame* frame, ExceptionState&) {} + +void AudioEncoder::configure(const AudioEncoderConfig*, ExceptionState&) {} + +ScriptPromise AudioEncoder::flush(ExceptionState&) { + return ScriptPromise(); +} + +void AudioEncoder::reset(ExceptionState&) {} + +void AudioEncoder::close(ExceptionState&) {} + +String AudioEncoder::state() { + return ""; +} + +void AudioEncoder::ContextDestroyed() {} + +void AudioEncoder::Trace(Visitor* visitor) const { + ScriptWrappable::Trace(visitor); + ExecutionContextLifecycleObserver::Trace(visitor); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/modules/webcodecs/audio_encoder.h b/third_party/blink/renderer/modules/webcodecs/audio_encoder.h new file mode 100644 index 0000000..c44a2e4 --- /dev/null +++ b/third_party/blink/renderer/modules/webcodecs/audio_encoder.h
@@ -0,0 +1,66 @@ +// 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 THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_AUDIO_ENCODER_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_AUDIO_ENCODER_H_ + +#include <memory> + +#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h" +#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_codec_state.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_encoded_audio_chunk_output_callback.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_video_encoder_output_callback.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_webcodecs_error_callback.h" +#include "third_party/blink/renderer/modules/modules_export.h" +#include "third_party/blink/renderer/modules/webcodecs/audio_frame.h" +#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" + +namespace blink { + +class ExceptionState; +class AudioEncoderConfig; +class AudioEncoderInit; + +class MODULES_EXPORT AudioEncoder final + : public ScriptWrappable, + public ActiveScriptWrappable<AudioEncoder>, + public ExecutionContextLifecycleObserver { + DEFINE_WRAPPERTYPEINFO(); + + public: + static AudioEncoder* Create(ScriptState*, + const AudioEncoderInit*, + ExceptionState&); + AudioEncoder(ScriptState*, const AudioEncoderInit*, ExceptionState&); + ~AudioEncoder() override; + + // audio_encoder.idl implementation. + int32_t encodeQueueSize(); + + void encode(AudioFrame* frame, ExceptionState&); + + void configure(const AudioEncoderConfig*, ExceptionState&); + + ScriptPromise flush(ExceptionState&); + + void reset(ExceptionState&); + + void close(ExceptionState&); + + String state(); + + // ExecutionContextLifecycleObserver override. + void ContextDestroyed() override; + + // ScriptWrappable override. + bool HasPendingActivity() const override { return false; } + + // GarbageCollected override. + void Trace(Visitor*) const override; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_AUDIO_ENCODER_H_
diff --git a/third_party/blink/renderer/modules/webcodecs/audio_encoder.idl b/third_party/blink/renderer/modules/webcodecs/audio_encoder.idl new file mode 100644 index 0000000..cfec86c3 --- /dev/null +++ b/third_party/blink/renderer/modules/webcodecs/audio_encoder.idl
@@ -0,0 +1,50 @@ +// 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. + +// https://github.com/WICG/web-codecs + +[ + Exposed=(Window,DedicatedWorker), + RuntimeEnabled=WebCodecs, + ActiveScriptWrappable +] interface AudioEncoder { + [CallWith=ScriptState, RaisesException, MeasureAs=WebCodecsAudioEncoder] + constructor(AudioEncoderInit init); + + // The number of pending encode requests. This does not include requests + // that have been sent to the underlying codec. + readonly attribute long encodeQueueSize; + + // Enqueues a control message to configure the audio encoder for encoding + // audio frames as described by config. + [RaisesException] + void configure(AudioEncoderConfig config); + + // Enqueues a request to encode a frame. + // Results of the encoding (EncodedAudioChunk) are returned via + // the output callback provided in configure(). + [RaisesException] + void encode(AudioFrame frame); + + + // Enqueues a request to produce outputs for all already encoded frames. + // Resolved after emitting outputs for all previously encoded frames. + [RaisesException] + Promise<void> flush(); + + // Discard all pending work and current encoder configuration. + // + // Output for earlier encoding requests will not be emitted. + // The next encoded frame will be a keyframe. + // Requires configure() to be call to set configuration once again. + [RaisesException] + void reset(); + + // Enqueues a request to shut down the encoder and free its resources. + [RaisesException] + void close(); + + // Which state the encoder is in, indicating which methods can be called. + readonly attribute CodecState state; +};
diff --git a/third_party/blink/renderer/modules/webcodecs/audio_encoder_config.idl b/third_party/blink/renderer/modules/webcodecs/audio_encoder_config.idl new file mode 100644 index 0000000..c832f43 --- /dev/null +++ b/third_party/blink/renderer/modules/webcodecs/audio_encoder_config.idl
@@ -0,0 +1,16 @@ +// 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. + +// https://github.com/WICG/web-codecs + +dictionary AudioEncoderConfig { + // TODO(chcunningham): reference spec registry. + required DOMString codec; + + // Rate of samples per second. 44100, 48000, etc. + required unsigned long sampleRate; + + // 1, 2, etc. + required unsigned long numberOfChannels; +};
diff --git a/third_party/blink/renderer/modules/webcodecs/audio_encoder_init.idl b/third_party/blink/renderer/modules/webcodecs/audio_encoder_init.idl new file mode 100644 index 0000000..cc6b93d1 --- /dev/null +++ b/third_party/blink/renderer/modules/webcodecs/audio_encoder_init.idl
@@ -0,0 +1,10 @@ +// 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. + +// https://github.com/WICG/web-codecs + +dictionary AudioEncoderInit { + required EncodedAudioChunkOutputCallback output; + required WebCodecsErrorCallback error; +};
diff --git a/third_party/blink/renderer/modules/webcodecs/decoder_template.cc b/third_party/blink/renderer/modules/webcodecs/decoder_template.cc index f98282c..5a7af56e 100644 --- a/third_party/blink/renderer/modules/webcodecs/decoder_template.cc +++ b/third_party/blink/renderer/modules/webcodecs/decoder_template.cc
@@ -269,9 +269,9 @@ decoder_ = Traits::CreateDecoder(*ExecutionContext::From(script_state_), gpu_factories_, logger_->log()); if (!decoder_) { - Shutdown(logger_->MakeException( - "Configuration error: Could not create decoder.", - media::StatusCode::kDecoderCreationFailed)); + Shutdown( + logger_->MakeException("Internal error: Could not create decoder.", + media::StatusCode::kDecoderCreationFailed)); return false; } @@ -468,7 +468,9 @@ DCHECK_EQ(pending_request_->type, Request::Type::kConfigure); if (!status.is_ok()) { - Shutdown(logger_->MakeException("Configuration error.", status)); + Shutdown(logger_->MakeException( + "Internal error: failed to flush out frames from previous config.", + status)); return; } @@ -490,7 +492,13 @@ DCHECK_EQ(pending_request_->type, Request::Type::kConfigure); if (!status.is_ok()) { - Shutdown(logger_->MakeException("Decoder initialization error.", status)); + std::string error_message = "Decoder initialization error."; + if (status.code() == media::StatusCode::kDecoderUnsupportedConfig) { + error_message = + "Unsupported configuration. Check isConfigSupported() prior to " + "calling configure()."; + } + Shutdown(logger_->MakeException(error_message, status)); return; }
diff --git a/third_party/blink/renderer/modules/webcodecs/encoded_audio_chunk_output_callback.idl b/third_party/blink/renderer/modules/webcodecs/encoded_audio_chunk_output_callback.idl new file mode 100644 index 0000000..0b55be9 --- /dev/null +++ b/third_party/blink/renderer/modules/webcodecs/encoded_audio_chunk_output_callback.idl
@@ -0,0 +1,8 @@ +// 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. + +// https://github.com/WICG/web-codecs + +[RuntimeEnabled=WebCodecs] +callback EncodedAudioChunkOutputCallback = void(EncodedAudioChunk output);
diff --git a/third_party/blink/renderer/modules/webcodecs/idls.gni b/third_party/blink/renderer/modules/webcodecs/idls.gni index 808d696..7acc6fa3 100644 --- a/third_party/blink/renderer/modules/webcodecs/idls.gni +++ b/third_party/blink/renderer/modules/webcodecs/idls.gni
@@ -4,6 +4,7 @@ modules_idl_files = [ "audio_decoder.idl", + "audio_encoder.idl", "audio_frame.idl", "encoded_video_chunk.idl", "encoded_audio_chunk.idl", @@ -17,6 +18,7 @@ modules_callback_function_idl_files = [ "audio_frame_output_callback.idl", + "encoded_audio_chunk_output_callback.idl", "video_encoder_output_callback.idl", "video_frame_output_callback.idl", "webcodecs_error_callback.idl", @@ -25,6 +27,8 @@ modules_dictionary_idl_files = [ "audio_decoder_config.idl", "audio_decoder_init.idl", + "audio_encoder_config.idl", + "audio_encoder_init.idl", "avc_encoder_config.idl", "encoded_video_chunk_init.idl", "encoded_audio_chunk_init.idl",
diff --git a/third_party/blink/renderer/modules/webcodecs/video_encoder.idl b/third_party/blink/renderer/modules/webcodecs/video_encoder.idl index e8f2683..94ee06f 100644 --- a/third_party/blink/renderer/modules/webcodecs/video_encoder.idl +++ b/third_party/blink/renderer/modules/webcodecs/video_encoder.idl
@@ -12,26 +12,18 @@ [CallWith=ScriptState, RaisesException, MeasureAs=WebCodecsVideoEncoder] constructor(VideoEncoderInit init); - // The number of pending encode requests. This does not include requests that - // have been sent to the underlying codec. - // - // Applications can minimize underflow by enqueueing encode requests until - // |encodeQueueSize| is greater than a constant. + // The number of pending encode requests. This does not include requests + // that have been sent to the underlying codec. readonly attribute long encodeQueueSize; - // Performs original configuration of the encoder. - // Resolved after configuration is done. It should be called only - // once per encoder instance, before calling any other methods. + // Enqueues a control message to configure the video encoder for encoding + // frames as described by config. [RaisesException] void configure(VideoEncoderConfig config); // Enqueues a request to encode a frame. // Results of the encoding (EncodedVideoChunk) are returned via // the output callback provided in configure(). - // Resolved when encoded processed the given frame. - // The output callback can be called before or after the result is resolved. - // Several encoded requests can be resolved before even a single output - // is produced. [RaisesException] void encode(VideoFrame frame, optional VideoEncoderEncodeOptions options = {}); @@ -46,13 +38,11 @@ // // Output for earlier encoding requests will not be emitted. // The next encoded frame will be a keyframe. - // Required a configure() to be call to set configuration once again. + // Requires configure() to be call to set configuration once again. [RaisesException] void reset(); // Enqueues a request to shut down the encoder and free its resources. - // Resolved after all resources are released and all following requests - // rejected. [RaisesException] void close();
diff --git a/third_party/blink/renderer/modules/xr/xr_render_state.cc b/third_party/blink/renderer/modules/xr/xr_render_state.cc index 0691efd67..9299d921 100644 --- a/third_party/blink/renderer/modules/xr/xr_render_state.cc +++ b/third_party/blink/renderer/modules/xr/xr_render_state.cc
@@ -63,7 +63,6 @@ void XRRenderState::Trace(Visitor* visitor) const { visitor->Trace(base_layer_); - visitor->Trace(inline_vertical_fov_); ScriptWrappable::Trace(visitor); }
diff --git a/third_party/blink/renderer/platform/bindings/script_state.cc b/third_party/blink/renderer/platform/bindings/script_state.cc index 982aa765..d9a9ad1 100644 --- a/third_party/blink/renderer/platform/bindings/script_state.cc +++ b/third_party/blink/renderer/platform/bindings/script_state.cc
@@ -17,7 +17,7 @@ : isolate_(context->GetIsolate()), context_(isolate_, context), world_(std::move(world)), - per_context_data_(std::make_unique<V8PerContextData>(context)), + per_context_data_(MakeGarbageCollected<V8PerContextData>(context)), reference_from_v8_context_(PERSISTENT_FROM_HERE, this) { DCHECK(world_); context_.SetWeak(this, &OnV8ContextCollectedCallback); @@ -34,12 +34,17 @@ RendererResourceCoordinator::Get()->OnScriptStateDestroyed(this); } +void ScriptState::Trace(Visitor* visitor) const { + visitor->Trace(per_context_data_); +} + void ScriptState::DetachGlobalObject() { DCHECK(!context_.IsEmpty()); GetContext()->DetachGlobal(); } void ScriptState::DisposePerContextData() { + per_context_data_->Dispose(); per_context_data_ = nullptr; InstanceCounters::IncrementCounter( InstanceCounters::kDetachedScriptStateCounter);
diff --git a/third_party/blink/renderer/platform/bindings/script_state.h b/third_party/blink/renderer/platform/bindings/script_state.h index 2a1897e..738b754 100644 --- a/third_party/blink/renderer/platform/bindings/script_state.h +++ b/third_party/blink/renderer/platform/bindings/script_state.h
@@ -130,7 +130,7 @@ ExecutionContext* execution_context); ~ScriptState(); - void Trace(Visitor*) const {} + void Trace(Visitor*) const; static ScriptState* Current(v8::Isolate* isolate) { // DEPRECATED return From(isolate->GetCurrentContext()); @@ -190,7 +190,7 @@ } void DetachGlobalObject(); - V8PerContextData* PerContextData() const { return per_context_data_.get(); } + V8PerContextData* PerContextData() const { return per_context_data_.Get(); } void DisposePerContextData(); // This method is expected to be called only from @@ -217,7 +217,7 @@ // So you must explicitly clear the std::unique_ptr by calling // disposePerContextData() once you no longer need V8PerContextData. // Otherwise, the v8::Context will leak. - std::unique_ptr<V8PerContextData> per_context_data_; + Member<V8PerContextData> per_context_data_; // v8::Context has an internal field to this ScriptState* as a raw pointer, // which is out of scope of Blink GC, but it must be a strong reference. We
diff --git a/third_party/blink/renderer/platform/bindings/v8_per_context_data.cc b/third_party/blink/renderer/platform/bindings/v8_per_context_data.cc index 5d02a38..8d92ce43 100644 --- a/third_party/blink/renderer/platform/bindings/v8_per_context_data.cc +++ b/third_party/blink/renderer/platform/bindings/v8_per_context_data.cc
@@ -46,21 +46,15 @@ namespace { -constexpr char kWrapperBoilerplatesLabel[] = - "V8PerContextData::wrapper_boilerplates_"; -constexpr char kConstructorMapLabel[] = "V8PerContextData::constructor_map_"; constexpr char kContextLabel[] = "V8PerContextData::context_"; } // namespace V8PerContextData::V8PerContextData(v8::Local<v8::Context> context) : isolate_(context->GetIsolate()), - wrapper_boilerplates_(isolate_, kWrapperBoilerplatesLabel), - constructor_map_(isolate_, kConstructorMapLabel), context_holder_(std::make_unique<gin::ContextHolder>(isolate_)), context_(isolate_, context), - activity_logger_(nullptr), - data_map_(MakeGarbageCollected<DataMap>()) { + activity_logger_(nullptr) { context_holder_->SetContext(context); context_.Get().AnnotateStrongRetainer(kContextLabel); @@ -77,24 +71,47 @@ } } +void V8PerContextData::Dispose() { + // These fields are not traced by the garbage collector and could contain + // strong GC roots that prevent `this` from otherwise being collected, so + // explicitly break any potential cycles in the ownership graph now. + context_holder_ = nullptr; + if (!context_.IsEmpty()) + context_.SetPhantom(); + if (!private_custom_element_definition_id_.IsEmpty()) + private_custom_element_definition_id_.SetPhantom(); +} + +void V8PerContextData::Trace(Visitor* visitor) const { + visitor->Trace(wrapper_boilerplates_); + visitor->Trace(constructor_map_); + visitor->Trace(data_map_); +} + V8PerContextData* V8PerContextData::From(v8::Local<v8::Context> context) { return ScriptState::From(context)->PerContextData(); } v8::Local<v8::Object> V8PerContextData::CreateWrapperFromCacheSlowCase( const WrapperTypeInfo* type) { + DCHECK(!wrapper_boilerplates_.Contains(type)); v8::Context::Scope scope(GetContext()); v8::Local<v8::Function> interface_object = ConstructorForType(type); CHECK(!interface_object.IsEmpty()); v8::Local<v8::Object> instance_template = V8ObjectConstructor::NewInstance(isolate_, interface_object) .ToLocalChecked(); - wrapper_boilerplates_.Set(type, instance_template); + + TraceWrapperV8Reference<v8::Object> traced_wrapper; + traced_wrapper.Set(isolate_, instance_template); + wrapper_boilerplates_.insert(type, traced_wrapper); + return instance_template->Clone(); } v8::Local<v8::Function> V8PerContextData::ConstructorForTypeSlowCase( const WrapperTypeInfo* type) { + DCHECK(!constructor_map_.Contains(type)); v8::Local<v8::Context> context = GetContext(); v8::Context::Scope scope(context); @@ -109,7 +126,10 @@ type, context, world, isolate_, parent_interface_object, V8ObjectConstructor::CreationMode::kInstallConditionalFeatures); - constructor_map_.Set(type, interface_object); + TraceWrapperV8Reference<v8::Function> traced_wrapper; + traced_wrapper.Set(isolate_, interface_object); + constructor_map_.insert(type, traced_wrapper); + return interface_object; } @@ -130,26 +150,28 @@ const WrapperTypeInfo* type, v8::Local<v8::Object>* prototype_object, v8::Local<v8::Function>* interface_object) { - *interface_object = constructor_map_.Get(type); - if (interface_object->IsEmpty()) { - *prototype_object = v8::Local<v8::Object>(); + auto it = constructor_map_.find(type); + if (it == constructor_map_.end()) { + interface_object->Clear(); + prototype_object->Clear(); return false; } + *interface_object = it->value.NewLocal(isolate_); *prototype_object = PrototypeForType(type); DCHECK(!prototype_object->IsEmpty()); return true; } void V8PerContextData::AddData(const char* key, Data* data) { - data_map_->Set(key, data); + data_map_.Set(key, data); } void V8PerContextData::ClearData(const char* key) { - data_map_->erase(key); + data_map_.erase(key); } V8PerContextData::Data* V8PerContextData::GetData(const char* key) { - return data_map_->at(key); + return data_map_.at(key); } } // namespace blink
diff --git a/third_party/blink/renderer/platform/bindings/v8_per_context_data.h b/third_party/blink/renderer/platform/bindings/v8_per_context_data.h index 6c7db2f7..bf10ab6 100644 --- a/third_party/blink/renderer/platform/bindings/v8_per_context_data.h +++ b/third_party/blink/renderer/platform/bindings/v8_per_context_data.h
@@ -36,11 +36,11 @@ #include "gin/public/context_holder.h" #include "gin/public/gin_embedders.h" #include "third_party/blink/renderer/platform/bindings/scoped_persistent.h" -#include "third_party/blink/renderer/platform/bindings/v8_global_value_map.h" +#include "third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h" #include "third_party/blink/renderer/platform/heap/handle.h" +#include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/heap/persistent.h" #include "third_party/blink/renderer/platform/platform_export.h" -#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" #include "third_party/blink/renderer/platform/wtf/hash_map.h" #include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" #include "third_party/blink/renderer/platform/wtf/text/atomic_string_hash.h" @@ -55,9 +55,8 @@ // Used to hold data that is associated with a single v8::Context object, and // has a 1:1 relationship with v8::Context. -class PLATFORM_EXPORT V8PerContextData final { - USING_FAST_MALLOC(V8PerContextData); - +class PLATFORM_EXPORT V8PerContextData final + : public GarbageCollected<V8PerContextData> { public: explicit V8PerContextData(v8::Local<v8::Context>); @@ -65,23 +64,27 @@ ~V8PerContextData(); + void Trace(Visitor* visitor) const; + void Dispose(); + v8::Local<v8::Context> GetContext() { return context_.NewLocal(isolate_); } // To create JS Wrapper objects, we create a cache of a 'boiler plate' // object, and then simply Clone that object each time we need a new one. // This is faster than going through the full object creation process. v8::Local<v8::Object> CreateWrapperFromCache(const WrapperTypeInfo* type) { - v8::Local<v8::Object> boilerplate = wrapper_boilerplates_.Get(type); - return !boilerplate.IsEmpty() ? boilerplate->Clone() - : CreateWrapperFromCacheSlowCase(type); + auto it = wrapper_boilerplates_.find(type); + return it != wrapper_boilerplates_.end() + ? it->value.Get()->Clone() + : CreateWrapperFromCacheSlowCase(type); } // Returns the interface object that is appropriately initialized (e.g. // context-dependent properties are installed). v8::Local<v8::Function> ConstructorForType(const WrapperTypeInfo* type) { - v8::Local<v8::Function> interface_object = constructor_map_.Get(type); - return (!interface_object.IsEmpty()) ? interface_object - : ConstructorForTypeSlowCase(type); + auto it = constructor_map_.find(type); + return it != constructor_map_.end() ? it->value.NewLocal(isolate_) + : ConstructorForTypeSlowCase(type); } v8::Local<v8::Object> PrototypeForType(const WrapperTypeInfo*); @@ -127,13 +130,15 @@ v8::Local<v8::Object> CreateWrapperFromCacheSlowCase(const WrapperTypeInfo*); v8::Local<v8::Function> ConstructorForTypeSlowCase(const WrapperTypeInfo*); - v8::Isolate* isolate_; + v8::Isolate* const isolate_; // For each possible type of wrapper, we keep a boilerplate object. // The boilerplate is used to create additional wrappers of the same type. - V8GlobalValueMap<const WrapperTypeInfo*, v8::Object> wrapper_boilerplates_; + HeapHashMap<const WrapperTypeInfo*, TraceWrapperV8Reference<v8::Object>> + wrapper_boilerplates_; - V8GlobalValueMap<const WrapperTypeInfo*, v8::Function> constructor_map_; + HeapHashMap<const WrapperTypeInfo*, TraceWrapperV8Reference<v8::Function>> + constructor_map_; std::unique_ptr<gin::ContextHolder> context_holder_; @@ -145,7 +150,7 @@ V8DOMActivityLogger* activity_logger_; using DataMap = HeapHashMap<const char*, Member<Data>>; - Persistent<DataMap> data_map_; + DataMap data_map_; DISALLOW_COPY_AND_ASSIGN(V8PerContextData); };
diff --git a/third_party/blink/renderer/platform/fonts/shaping/shaping_line_breaker.cc b/third_party/blink/renderer/platform/fonts/shaping/shaping_line_breaker.cc index 76b953d1..3e7a6a0 100644 --- a/third_party/blink/renderer/platform/fonts/shaping/shaping_line_breaker.cc +++ b/third_party/blink/renderer/platform/fonts/shaping/shaping_line_breaker.cc
@@ -50,11 +50,18 @@ .IsAllSpecialCharacters<IsBreakableSpace>(); } -bool ShouldHyphenate(const String& text, unsigned start, unsigned end) { +bool ShouldHyphenate(const String& text, + unsigned word_start, + unsigned word_end, + unsigned line_start) { + // If this is the first word in this line, allow to hyphenate. Otherwise the + // word will overflow. + if (word_start <= line_start) + return true; // Do not hyphenate the last word in a paragraph, except when it's a single // word paragraph. - if (IsAllSpaces(text, end, text.length())) - return IsAllSpaces(text, 0, start); + if (IsAllSpaces(text, word_end, text.length())) + return IsAllSpaces(text, 0, word_start); return true; } @@ -141,7 +148,7 @@ LazyLineBreakIterator::IsBreakableSpace(text[word_start])) word_start++; if (offset >= word_start && - ShouldHyphenate(text, previous_break_opportunity, word_end)) { + ShouldHyphenate(text, previous_break_opportunity, word_end, start)) { unsigned prefix_length = Hyphenate(offset, word_start, word_end, backwards); if (prefix_length) return {word_start + prefix_length, true};
diff --git a/third_party/blink/renderer/platform/graphics/dark_mode_filter.cc b/third_party/blink/renderer/platform/graphics/dark_mode_filter.cc index 4450500d..9839dd8 100644 --- a/third_party/blink/renderer/platform/graphics/dark_mode_filter.cc +++ b/third_party/blink/renderer/platform/graphics/dark_mode_filter.cc
@@ -158,7 +158,12 @@ cc::PaintFlags dark_mode_flags = flags; if (flags.HasShader()) { - dark_mode_flags.setColorFilter(immutable_.color_filter->ToSkColorFilter()); + PaintShader::Type shader_type = flags.getShader()->shader_type(); + if (shader_type != PaintShader::Type::kImage && + shader_type != PaintShader::Type::kPaintRecord) { + dark_mode_flags.setColorFilter( + immutable_.color_filter->ToSkColorFilter()); + } } else if (ShouldApplyToColor(flags.getColor(), role)) { dark_mode_flags.setColor(inverted_color_cache_->GetInvertedColor( immutable_.color_filter.get(), flags.getColor()));
diff --git a/third_party/blink/renderer/platform/graphics/graphics_context.cc b/third_party/blink/renderer/platform/graphics/graphics_context.cc index 4fa9a11..a4b57960 100644 --- a/third_party/blink/renderer/platform/graphics/graphics_context.cc +++ b/third_party/blink/renderer/platform/graphics/graphics_context.cc
@@ -223,32 +223,6 @@ return dom_node_id_; } -void GraphicsContext::SetShadow( - const FloatSize& offset, - float blur, - const Color& color, - DrawLooperBuilder::ShadowTransformMode shadow_transform_mode, - DrawLooperBuilder::ShadowAlphaMode shadow_alpha_mode, - ShadowMode shadow_mode) { - DrawLooperBuilder draw_looper_builder; - if (!color.Alpha()) { - // When shadow-only but there is no shadow, we use an empty draw looper - // to disable rendering of the source primitive. When not shadow-only, we - // clear the looper. - SetDrawLooper(shadow_mode != kDrawShadowOnly - ? nullptr - : draw_looper_builder.DetachDrawLooper()); - return; - } - - draw_looper_builder.AddShadow(offset, blur, color, shadow_transform_mode, - shadow_alpha_mode); - if (shadow_mode == kDrawShadowAndForeground) { - draw_looper_builder.AddUnmodifiedContent(); - } - SetDrawLooper(draw_looper_builder.DetachDrawLooper()); -} - void GraphicsContext::SetDrawLooper(sk_sp<SkDrawLooper> draw_looper) { MutableState()->SetDrawLooper(std::move(draw_looper)); }
diff --git a/third_party/blink/renderer/platform/graphics/graphics_context.h b/third_party/blink/renderer/platform/graphics/graphics_context.h index 809469b1..f7c07b9 100644 --- a/third_party/blink/renderer/platform/graphics/graphics_context.h +++ b/third_party/blink/renderer/platform/graphics/graphics_context.h
@@ -348,15 +348,6 @@ // not necessarily non-empty), even when the context is disabled. sk_sp<PaintRecord> EndRecording(); - void SetShadow(const FloatSize& offset, - float blur, - const Color&, - DrawLooperBuilder::ShadowTransformMode = - DrawLooperBuilder::kShadowRespectsTransforms, - DrawLooperBuilder::ShadowAlphaMode = - DrawLooperBuilder::kShadowRespectsAlpha, - ShadowMode = kDrawShadowAndForeground); - void SetDrawLooper(sk_sp<SkDrawLooper>); void DrawFocusRing(const Vector<IntRect>&,
diff --git a/third_party/blink/renderer/platform/graphics/graphics_types.h b/third_party/blink/renderer/platform/graphics/graphics_types.h index 3890907..c7258df 100644 --- a/third_party/blink/renderer/platform/graphics/graphics_types.h +++ b/third_party/blink/renderer/platform/graphics/graphics_types.h
@@ -134,14 +134,6 @@ kOrderingBarrier, }; -// TODO(junov): crbug.com/453113 Relocate ShadowMode to -// CanvasRenderingContext2DState.h once GraphicsContext no longer uses it. -enum ShadowMode { - kDrawShadowAndForeground, - kDrawShadowOnly, - kDrawForegroundOnly -}; - enum AntiAliasingMode { kNotAntiAliased, kAntiAliased }; enum GradientSpreadMethod {
diff --git a/third_party/blink/renderer/platform/heap/collection_support/heap_vector.h b/third_party/blink/renderer/platform/heap/collection_support/heap_vector.h index b0f439e..71ea2a6 100644 --- a/third_party/blink/renderer/platform/heap/collection_support/heap_vector.h +++ b/third_party/blink/renderer/platform/heap/collection_support/heap_vector.h
@@ -5,6 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_COLLECTION_SUPPORT_HEAP_VECTOR_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_COLLECTION_SUPPORT_HEAP_VECTOR_H_ +#include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/heap/heap_allocator_impl.h" #include "third_party/blink/renderer/platform/wtf/type_traits.h" #include "third_party/blink/renderer/platform/wtf/vector.h" @@ -12,11 +13,49 @@ namespace blink { template <typename T, wtf_size_t inlineCapacity = 0> -class HeapVector final : public Vector<T, inlineCapacity, HeapAllocator> { - IS_GARBAGE_COLLECTED_CONTAINER_TYPE(); +class HeapVector final : public GarbageCollected<HeapVector<T, inlineCapacity>>, + public Vector<T, inlineCapacity, HeapAllocator> { DISALLOW_NEW(); - static void CheckType() { + public: + HeapVector() = default; + + explicit HeapVector(wtf_size_t size) + : Vector<T, inlineCapacity, HeapAllocator>(size) {} + + HeapVector(wtf_size_t size, const T& val) + : Vector<T, inlineCapacity, HeapAllocator>(size, val) {} + + template <wtf_size_t otherCapacity> + HeapVector(const HeapVector<T, otherCapacity>& other) // NOLINT + : Vector<T, inlineCapacity, HeapAllocator>(other) {} + + HeapVector(const HeapVector& other) + : Vector<T, inlineCapacity, HeapAllocator>(other) {} + + HeapVector& operator=(const HeapVector& other) { + Vector<T, inlineCapacity, HeapAllocator>::operator=(other); + return *this; + } + + HeapVector(HeapVector&& other) noexcept + : Vector<T, inlineCapacity, HeapAllocator>(std::move(other)) {} + + HeapVector& operator=(HeapVector&& other) noexcept { + Vector<T, inlineCapacity, HeapAllocator>::operator=(std::move(other)); + return *this; + } + + HeapVector(std::initializer_list<T> elements) + : Vector<T, inlineCapacity, HeapAllocator>(elements) {} + + void Trace(Visitor* visitor) const { + CheckType(); + Vector<T, inlineCapacity, HeapAllocator>::Trace(visitor); + } + + private: + static constexpr void CheckType() { static_assert( std::is_trivially_destructible<HeapVector>::value || inlineCapacity, "HeapVector must be trivially destructible."); @@ -28,60 +67,6 @@ static_assert(WTF::IsTraceableInCollectionTrait<VectorTraits<T>>::value, "Type must be traceable in collection"); } - - public: - template <typename> - static void* AllocateObject(size_t size) { - // On-heap HeapVectors generally should not have inline capacity, but it is - // hard to avoid when using a type alias. Hence we only disallow the - // VectorTraits<T>::kNeedsDestruction case for now. - static_assert(inlineCapacity == 0 || !VectorTraits<T>::kNeedsDestruction, - "on-heap HeapVector<> should not have an inline capacity"); - return ThreadHeap::Allocate<HeapVector<T, inlineCapacity>>(size); - } - - HeapVector() { CheckType(); } - - explicit HeapVector(wtf_size_t size) - : Vector<T, inlineCapacity, HeapAllocator>(size) { - CheckType(); - } - - HeapVector(wtf_size_t size, const T& val) - : Vector<T, inlineCapacity, HeapAllocator>(size, val) { - CheckType(); - } - - template <wtf_size_t otherCapacity> - HeapVector(const HeapVector<T, otherCapacity>& other) // NOLINT - : Vector<T, inlineCapacity, HeapAllocator>(other) { - CheckType(); - } - - HeapVector(const HeapVector& other) - : Vector<T, inlineCapacity, HeapAllocator>(other) { - CheckType(); - } - - HeapVector& operator=(const HeapVector& other) { - Vector<T, inlineCapacity, HeapAllocator>::operator=(other); - return *this; - } - - HeapVector(HeapVector&& other) noexcept - : Vector<T, inlineCapacity, HeapAllocator>(std::move(other)) { - CheckType(); - } - - HeapVector& operator=(HeapVector&& other) noexcept { - Vector<T, inlineCapacity, HeapAllocator>::operator=(std::move(other)); - return *this; - } - - HeapVector(std::initializer_list<T> elements) - : Vector<T, inlineCapacity, HeapAllocator>(elements) { - CheckType(); - } }; template <typename T, wtf_size_t inlineCapacity>
diff --git a/third_party/blink/renderer/platform/heap/impl/trace_traits.h b/third_party/blink/renderer/platform/heap/impl/trace_traits.h index 44ae3c94..86d19b7 100644 --- a/third_party/blink/renderer/platform/heap/impl/trace_traits.h +++ b/third_party/blink/renderer/platform/heap/impl/trace_traits.h
@@ -186,22 +186,6 @@ } }; -// While using base::Optional<T> with garbage-collected types is generally -// disallowed by the OptionalGarbageCollected check in blink_gc_plugin, -// garbage-collected containers such as HeapVector are allowed and need to be -// traced. -template <typename T> -struct TraceTrait<base::Optional<T>> { - STATIC_ONLY(TraceTrait); - - public: - static void Trace(Visitor* visitor, const base::Optional<T>* optional) { - if (*optional != base::nullopt) { - TraceIfNeeded<T>::Trace(visitor, optional->value()); - } - } -}; - // Helper for processing ephemerons represented as KeyValuePair. Reorders // parameters if needed so that KeyType is always weak. template <typename _KeyType,
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc index d7c1ee70..b9e9369c 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc
@@ -288,6 +288,52 @@ } } + // Helper for posting several tasks to specific queues. |task_descriptor| is a + // string with space delimited task identifiers. The first letter of each task + // identifier specifies the task queue: + // - 'L': Loading task queue + // - 'T': Throttleable task queue + // - 'P': Pausable task queue + // - 'U': Unpausable task queue + // - 'D': Deferrable task queue + void PostTestTasksToQueuesWithTrait(Vector<String>* run_order, + const String& task_descriptor) { + std::istringstream stream(task_descriptor.Utf8()); + while (!stream.eof()) { + std::string task; + stream >> task; + switch (task[0]) { + case 'L': + LoadingTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask( + FROM_HERE, base::BindOnce(&AppendToVectorTestTask, run_order, + String::FromUTF8(task))); + break; + case 'T': + ThrottleableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask( + FROM_HERE, base::BindOnce(&AppendToVectorTestTask, run_order, + String::FromUTF8(task))); + break; + case 'P': + PausableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask( + FROM_HERE, base::BindOnce(&AppendToVectorTestTask, run_order, + String::FromUTF8(task))); + break; + case 'U': + UnpausableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask( + FROM_HERE, base::BindOnce(&AppendToVectorTestTask, run_order, + String::FromUTF8(task))); + break; + case 'D': + DeferrableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask( + FROM_HERE, base::BindOnce(&AppendToVectorTestTask, run_order, + String::FromUTF8(task))); + break; + default: + NOTREACHED(); + } + } + } + static void ResetForNavigation(FrameSchedulerImpl* frame_scheduler) { frame_scheduler->ResetForNavigation(); } @@ -489,10 +535,6 @@ ++*counter; } -void RecordQueueName(String name, Vector<String>* tasks) { - tasks->push_back(std::move(name)); -} - // Simulate running a task of a particular length by fast forwarding the task // environment clock, which is used to determine the wall time of a task. void RunTaskOfLength(base::test::TaskEnvironment* task_environment, @@ -963,27 +1005,7 @@ TEST_F(FrameSchedulerImplTest, PageFreezeWithKeepActive) { Vector<String> tasks; - LoadingTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask( - FROM_HERE, - base::BindOnce(&RecordQueueName, - LoadingTaskQueue()->GetTaskQueue()->GetName(), &tasks)); - ThrottleableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask( - FROM_HERE, - base::BindOnce(&RecordQueueName, - ThrottleableTaskQueue()->GetTaskQueue()->GetName(), - &tasks)); - DeferrableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask( - FROM_HERE, - base::BindOnce(&RecordQueueName, - DeferrableTaskQueue()->GetTaskQueue()->GetName(), &tasks)); - PausableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask( - FROM_HERE, - base::BindOnce(&RecordQueueName, - PausableTaskQueue()->GetTaskQueue()->GetName(), &tasks)); - UnpausableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask( - FROM_HERE, - base::BindOnce(&RecordQueueName, - UnpausableTaskQueue()->GetTaskQueue()->GetName(), &tasks)); + PostTestTasksToQueuesWithTrait(&tasks, "L1 T1 D1 P1 U1"); page_scheduler_->SetKeepActive(true); // say we have a Service Worker page_scheduler_->SetPageVisible(false); @@ -992,30 +1014,19 @@ EXPECT_THAT(tasks, UnorderedElementsAre()); base::RunLoop().RunUntilIdle(); // Everything runs except throttleable tasks (timers) - EXPECT_THAT(tasks, - UnorderedElementsAre( - String(LoadingTaskQueue()->GetTaskQueue()->GetName()), - String(DeferrableTaskQueue()->GetTaskQueue()->GetName()), - String(PausableTaskQueue()->GetTaskQueue()->GetName()), - String(UnpausableTaskQueue()->GetTaskQueue()->GetName()))); + EXPECT_THAT(tasks, UnorderedElementsAre("L1", "D1", "P1", "U1")); tasks.clear(); - LoadingTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask( - FROM_HERE, - base::BindOnce(&RecordQueueName, - LoadingTaskQueue()->GetTaskQueue()->GetName(), &tasks)); + PostTestTasksToQueuesWithTrait(&tasks, "L1"); EXPECT_THAT(tasks, UnorderedElementsAre()); base::RunLoop().RunUntilIdle(); // loading task runs - EXPECT_THAT(tasks, UnorderedElementsAre(String( - LoadingTaskQueue()->GetTaskQueue()->GetName()))); + EXPECT_THAT(tasks, UnorderedElementsAre("L1")); tasks.clear(); - LoadingTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask( - FROM_HERE, - base::BindOnce(&RecordQueueName, - LoadingTaskQueue()->GetTaskQueue()->GetName(), &tasks)); + PostTestTasksToQueuesWithTrait(&tasks, "L1"); + // KeepActive is false when Service Worker stops. page_scheduler_->SetKeepActive(false); EXPECT_THAT(tasks, UnorderedElementsAre()); @@ -1027,8 +1038,7 @@ EXPECT_THAT(tasks, UnorderedElementsAre()); base::RunLoop().RunUntilIdle(); // loading task runs - EXPECT_THAT(tasks, UnorderedElementsAre(String( - LoadingTaskQueue()->GetTaskQueue()->GetName()))); + EXPECT_THAT(tasks, UnorderedElementsAre("L1")); } class FrameSchedulerImplTestWithUnfreezableLoading
diff --git a/third_party/blink/renderer/platform/scheduler/test/queueing_time_estimator_perf_test.cc b/third_party/blink/renderer/platform/scheduler/test/queueing_time_estimator_perf_test.cc index eed45db..e69de29 100644 --- a/third_party/blink/renderer/platform/scheduler/test/queueing_time_estimator_perf_test.cc +++ b/third_party/blink/renderer/platform/scheduler/test/queueing_time_estimator_perf_test.cc
@@ -1,56 +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. - -#include "base/timer/lap_timer.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "testing/perf/perf_test.h" -#include "third_party/blink/renderer/platform/scheduler/test/test_queueing_time_estimator_client.h" - -namespace blink { -namespace scheduler { - -namespace { - -static constexpr base::TimeDelta kTimeLimit = - base::TimeDelta::FromMilliseconds(2000); -static const int kWarmupRuns = 50; -static const int kCheckInterval = 100; - -class QueueingTimeEstimatorTestPerfTest : public testing::Test { - public: - QueueingTimeEstimatorTestPerfTest() - : timer_(kWarmupRuns, kTimeLimit, kCheckInterval) {} - base::LapTimer timer_; - base::TimeTicks time; - TestQueueingTimeEstimatorClient client; -}; - -} // namespace - -TEST_F(QueueingTimeEstimatorTestPerfTest, DISABLED_ManyTasks) { - const int num_tests = 3; - base::TimeDelta task_lengths[num_tests] = { - base::TimeDelta::FromSeconds(1), base::TimeDelta::FromMilliseconds(50), - base::TimeDelta::FromMilliseconds(1)}; - std::string test_descriptions[num_tests] = {"OneSecondTasks", "FiftyMsTasks", - "OneMsTasks"}; - for (int i = 0; i < num_tests; ++i) { - QueueingTimeEstimatorForTest estimator( - &client, base::TimeDelta::FromSeconds(1), 20, time); - time += base::TimeDelta::FromSeconds(1); - timer_.Reset(); - do { - estimator.OnExecutionStarted(time); - time += task_lengths[i]; - estimator.OnExecutionStopped(time); - timer_.NextLap(); - } while (!timer_.HasTimeLimitExpired()); - perf_test::PrintResult("QueueingTimeEstimatorTestPerfTest", "ManyTasks", - test_descriptions[i], timer_.LapsPerSecond(), - "tasks/s", true); - } -} - -} // namespace scheduler -} // namespace blink
diff --git a/third_party/blink/renderer/platform/text/hyphenation/hyphenation_minikin.cc b/third_party/blink/renderer/platform/text/hyphenation/hyphenation_minikin.cc index b9fbc7db..17cd34e 100644 --- a/third_party/blink/renderer/platform/text/hyphenation/hyphenation_minikin.cc +++ b/third_party/blink/renderer/platform/text/hyphenation/hyphenation_minikin.cc
@@ -24,26 +24,21 @@ namespace { -template <typename CharType> -StringView SkipLeadingSpaces(const CharType* text, - unsigned length, - unsigned* num_leading_spaces_out) { - const CharType* begin = text; - const CharType* end = text + length; - while (text != end && Character::TreatAsSpace(*text)) - text++; - *num_leading_spaces_out = text - begin; - return StringView(text, static_cast<unsigned>(end - text)); +inline bool ShouldSkipLeadingChar(UChar32 c) { + if (Character::TreatAsSpace(c)) + return true; + // Strip leading punctuation, defined as OP and QU line breaking classes, + // see UAX #14. + const int32_t lb = u_getIntPropertyValue(c, UCHAR_LINE_BREAK); + if (lb == U_LB_OPEN_PUNCTUATION || lb == U_LB_QUOTATION) + return true; + return false; } -StringView SkipLeadingSpaces(const StringView& text, - unsigned* num_leading_spaces_out) { - if (text.Is8Bit()) { - return SkipLeadingSpaces(text.Characters8(), text.length(), - num_leading_spaces_out); - } - return SkipLeadingSpaces(text.Characters16(), text.length(), - num_leading_spaces_out); +inline bool ShouldSkipTrailingChar(UChar32 c) { + // Strip trailing spaces, punctuation and control characters. + const int32_t gc_mask = U_GET_GC_MASK(c); + return gc_mask & (U_GC_ZS_MASK | U_GC_P_MASK | U_GC_CC_MASK); } } // namespace @@ -86,6 +81,44 @@ return true; } +StringView HyphenationMinikin::WordToHyphenate( + const StringView& text, + unsigned* num_leading_chars_out) { + if (text.Is8Bit()) { + const LChar* begin = text.Characters8(); + const LChar* end = begin + text.length(); + while (begin != end && ShouldSkipLeadingChar(*begin)) + ++begin; + while (begin != end && ShouldSkipTrailingChar(end[-1])) + --end; + *num_leading_chars_out = begin - text.Characters8(); + CHECK_GE(end, begin); + return StringView(begin, end - begin); + } + const UChar* begin = text.Characters16(); + int index = 0; + int len = text.length(); + while (index < len) { + int next_index = index; + UChar32 c; + U16_NEXT(begin, next_index, len, c); + if (!ShouldSkipLeadingChar(c)) + break; + index = next_index; + } + while (index < len) { + int prev_len = len; + UChar32 c; + U16_PREV(begin, index, prev_len, c); + if (!ShouldSkipTrailingChar(c)) + break; + len = prev_len; + } + *num_leading_chars_out = index; + CHECK_GE(len, index); + return StringView(begin + index, len - index); +} + Vector<uint8_t> HyphenationMinikin::Hyphenate(const StringView& text) const { Vector<uint8_t> result; if (text.Is8Bit()) { @@ -105,11 +138,11 @@ wtf_size_t HyphenationMinikin::LastHyphenLocation( const StringView& text, wtf_size_t before_index) const { - unsigned num_leading_spaces; - StringView word = SkipLeadingSpaces(text, &num_leading_spaces); - if (before_index <= num_leading_spaces) + unsigned num_leading_chars; + StringView word = WordToHyphenate(text, &num_leading_chars); + if (before_index <= num_leading_chars) return 0; - before_index = std::min<wtf_size_t>(before_index - num_leading_spaces, + before_index = std::min<wtf_size_t>(before_index - num_leading_chars, word.length() - kMinimumSuffixLength); if (word.length() < kMinimumPrefixLength + kMinimumSuffixLength || @@ -122,15 +155,15 @@ static_assert(kMinimumPrefixLength >= 1, "|beforeIndex - 1| can underflow"); for (wtf_size_t i = before_index - 1; i >= kMinimumPrefixLength; i--) { if (result[i]) - return i + num_leading_spaces; + return i + num_leading_chars; } return 0; } Vector<wtf_size_t, 8> HyphenationMinikin::HyphenLocations( const StringView& text) const { - unsigned num_leading_spaces; - StringView word = SkipLeadingSpaces(text, &num_leading_spaces); + unsigned num_leading_chars; + StringView word = WordToHyphenate(text, &num_leading_chars); Vector<wtf_size_t, 8> hyphen_locations; if (word.length() < kMinimumPrefixLength + kMinimumSuffixLength) @@ -142,7 +175,7 @@ for (wtf_size_t i = word.length() - kMinimumSuffixLength - 1; i >= kMinimumPrefixLength; i--) { if (result[i]) - hyphen_locations.push_back(i + num_leading_spaces); + hyphen_locations.push_back(i + num_leading_chars); } return hyphen_locations; }
diff --git a/third_party/blink/renderer/platform/text/hyphenation/hyphenation_minikin.h b/third_party/blink/renderer/platform/text/hyphenation/hyphenation_minikin.h index e3c39c1..4f7bfcfe 100644 --- a/third_party/blink/renderer/platform/text/hyphenation/hyphenation_minikin.h +++ b/third_party/blink/renderer/platform/text/hyphenation/hyphenation_minikin.h
@@ -28,6 +28,11 @@ wtf_size_t before_index) const override; Vector<wtf_size_t, 8> HyphenLocations(const StringView&) const override; + // Extract the word to hyphenate by skipping leading and trailing spaces and + // punctuations. + static StringView WordToHyphenate(const StringView& text, + unsigned* num_leading_chars_out); + static AtomicString MapLocale(const AtomicString& locale); static scoped_refptr<HyphenationMinikin> FromFileForTesting(base::File);
diff --git a/third_party/blink/renderer/platform/text/hyphenation_test.cc b/third_party/blink/renderer/platform/text/hyphenation_test.cc index 1b608fa4..3905814b 100644 --- a/third_party/blink/renderer/platform/text/hyphenation_test.cc +++ b/third_party/blink/renderer/platform/text/hyphenation_test.cc
@@ -61,6 +61,33 @@ return nullptr; } #endif + +#if defined(USE_MINIKIN_HYPHENATION) + void TestWordToHyphenate(StringView text, + StringView expected, + unsigned expected_num_leading_chars) { + unsigned num_leading_chars; + const StringView result = + HyphenationMinikin::WordToHyphenate(text, &num_leading_chars); + EXPECT_EQ(result, expected); + EXPECT_EQ(num_leading_chars, expected_num_leading_chars); + + // |WordToHyphenate| has separate codepaths for 8 and 16 bits. Make sure + // both codepaths return the same results. When a paragraph has at least one + // 16 bits character (e.g., Emoji), there will be 8 bits words in 16 bits + // string. + if (!text.Is8Bit()) { + // If |text| is 16 bits, 16 bits codepath is already tested. + return; + } + String text16 = text.ToString(); + text16.Ensure16Bit(); + const StringView result16 = + HyphenationMinikin::WordToHyphenate(text16, &num_leading_chars); + EXPECT_EQ(result16, expected); + EXPECT_EQ(num_leading_chars, expected_num_leading_chars); + } +#endif }; TEST_F(HyphenationTest, Get) { @@ -141,6 +168,18 @@ EXPECT_THAT(actual, ElementsAreArray(locations)); } +#if defined(USE_MINIKIN_HYPHENATION) +TEST_F(HyphenationTest, WordToHyphenate) { + TestWordToHyphenate("word", "word", 0); + TestWordToHyphenate(" word", "word", 1); + TestWordToHyphenate(" word", "word", 2); + TestWordToHyphenate(" word..", "word", 2); + TestWordToHyphenate(" ( word. ).", "word", 3); + TestWordToHyphenate(u" ( \u3042. ).", u"\u3042", 3); + TestWordToHyphenate(u" ( \U00020B9F. ).", u"\U00020B9F", 3); +} +#endif + TEST_F(HyphenationTest, LeadingSpaces) { scoped_refptr<Hyphenation> hyphenation = GetHyphenation("en-us"); #if defined(OS_ANDROID) @@ -163,12 +202,6 @@ String only_spaces(" "); EXPECT_THAT(hyphenation->HyphenLocations(only_spaces), ElementsAre()); EXPECT_EQ(0u, hyphenation->LastHyphenLocation(only_spaces, 3)); - - // Line breaker is not supposed to pass with trailing spaces. - String trailing_space("principle "); - EXPECT_THAT(hyphenation->HyphenLocations(trailing_space), - testing::AnyOf(ElementsAre(), ElementsAre(6, 4))); - EXPECT_EQ(0u, hyphenation->LastHyphenLocation(trailing_space, 10)); } TEST_F(HyphenationTest, English) {
diff --git a/third_party/blink/renderer/platform/weborigin/security_origin.cc b/third_party/blink/renderer/platform/weborigin/security_origin.cc index 6f460ab..b4102e4 100644 --- a/third_party/blink/renderer/platform/weborigin/security_origin.cc +++ b/third_party/blink/renderer/platform/weborigin/security_origin.cc
@@ -88,6 +88,10 @@ return KURL(url.GetPath()); } +// Note: When changing ShouldTreatAsOpaqueOrigin, consider also updating +// IsValidInput in //url/scheme_host_port.cc (there might be existing +// differences in behavior between these 2 layers, but we should avoid +// introducing new differences). static bool ShouldTreatAsOpaqueOrigin(const KURL& url) { if (!url.IsValid()) return true;
diff --git a/third_party/blink/renderer/platform/weborigin/security_origin_test.cc b/third_party/blink/renderer/platform/weborigin/security_origin_test.cc index ef22581..6926a75 100644 --- a/third_party/blink/renderer/platform/weborigin/security_origin_test.cc +++ b/third_party/blink/renderer/platform/weborigin/security_origin_test.cc
@@ -745,6 +745,7 @@ TEST_F(SecurityOriginTest, UrlOriginConversions) { url::ScopedSchemeRegistryForTests scoped_registry; + url::AddNoAccessScheme("no-access"); url::AddLocalScheme("nonstandard-but-local"); struct TestCases { const char* const url; @@ -780,6 +781,9 @@ {"mailto:localhost/", "", "", 0, true}, {"about:blank", "", "", 0, true}, + // Custom no-access scheme. + {"no-access:blah", "", "", 0, true}, + // Registered URLs {"ftp://example.com/", "ftp", "example.com", 21}, {"ws://example.com/", "ws", "example.com", 80}, @@ -958,6 +962,23 @@ } } +// See also OriginTest.ConstructFromGURL_OpaqueOrigin and +// NavigationUrlRewriteBrowserTest.RewriteToNoAccess. +TEST_F(SecurityOriginTest, StandardNoAccessScheme) { + url::ScopedSchemeRegistryForTests scoped_registry; + url::AddStandardScheme("std-no-access", url::SCHEME_WITH_HOST); + url::AddNoAccessScheme("std-no-access"); + url::AddStandardScheme("std", url::SCHEME_WITH_HOST); + + scoped_refptr<const SecurityOrigin> custom_standard_noaccess_origin = + SecurityOrigin::CreateFromString("std-no-access://host"); + EXPECT_TRUE(custom_standard_noaccess_origin->IsOpaque()); + + scoped_refptr<const SecurityOrigin> custom_standard_origin = + SecurityOrigin::CreateFromString("std://host"); + EXPECT_FALSE(custom_standard_origin->IsOpaque()); +} + TEST_F(SecurityOriginTest, NonStandardScheme) { scoped_refptr<const SecurityOrigin> origin = SecurityOrigin::CreateFromString("cow://");
diff --git a/third_party/blink/renderer/platform/wtf/allocator/allocator.h b/third_party/blink/renderer/platform/wtf/allocator/allocator.h index c6b35283..4d25949c 100644 --- a/third_party/blink/renderer/platform/wtf/allocator/allocator.h +++ b/third_party/blink/renderer/platform/wtf/allocator/allocator.h
@@ -65,15 +65,6 @@ private: \ friend class ::WTF::internal::__thisIsHereToForceASemicolonAfterThisMacro -#define IS_GARBAGE_COLLECTED_CONTAINER_TYPE() \ - IS_GARBAGE_COLLECTED_TYPE(); \ - \ - public: \ - using IsGarbageCollectedCollectionTypeMarker = int; \ - \ - private: \ - friend class ::WTF::internal::__thisIsHereToForceASemicolonAfterThisMacro - #if defined(__clang__) #define ANNOTATE_STACK_ALLOCATED \ __attribute__((annotate("blink_stack_allocated")))
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 2501294..c194dc8 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -2295,6 +2295,8 @@ # css-pseudo-4 opacity not applied to ::first-line crbug.com/1085772 external/wpt/css/css-pseudo/first-line-opacity-001.html [ Failure ] +crbug.com/1165324 http/tests/devtools/console/console-preserve-log-x-process-navigation.js [ Pass Failure ] + # motion-1 issues crbug.com/641245 external/wpt/css/motion/offset-path-ray-002.html [ Failure ] crbug.com/641245 external/wpt/css/motion/offset-path-ray-003.html [ Failure ] @@ -4954,8 +4956,6 @@ # Works in main table patch, needs percentage sizing fix. crbug.com/958381 virtual/layout_ng_table/external/wpt/css/css-tables/height-distribution/percentage-sizing-of-table-cell-children.html [ Failure ] -crbug.com/958381 virtual/layout_ng_table/external/wpt/css/css-tables/percent-width-ignored-001.tentative.html [ Failure ] -crbug.com/958381 virtual/layout_ng_table/external/wpt/css/css-tables/percent-width-ignored-003.tentative.html [ Failure ] # Sheriff 2019-08-14 crbug.com/993671 [ Win ] http/tests/media/video-frame-size-change.html [ Pass Failure ]
diff --git a/third_party/blink/web_tests/compositing/layer-creation/fixed-position-nonscrollable-body-expected.txt b/third_party/blink/web_tests/compositing/layer-creation/fixed-position-nonscrollable-body-expected.txt index 8f94fa3b..eeb594f 100644 --- a/third_party/blink/web_tests/compositing/layer-creation/fixed-position-nonscrollable-body-expected.txt +++ b/third_party/blink/web_tests/compositing/layer-creation/fixed-position-nonscrollable-body-expected.txt
@@ -5,6 +5,24 @@ "bounds": [800, 4021], "contentsOpaque": true, "backgroundColor": "#FFFFFF" + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed lime box'", + "bounds": [100, 100], + "contentsOpaque": true, + "backgroundColor": "#00FF00", + "transform": 1 + } + ], + "transforms": [ + { + "id": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [10, 100, 0, 1] + ] } ] }
diff --git a/third_party/blink/web_tests/compositing/layer-creation/fixed-position-nonscrollable-body-overlap-expected.txt b/third_party/blink/web_tests/compositing/layer-creation/fixed-position-nonscrollable-body-overlap-expected.txt index 00639270..3160401 100644 --- a/third_party/blink/web_tests/compositing/layer-creation/fixed-position-nonscrollable-body-overlap-expected.txt +++ b/third_party/blink/web_tests/compositing/layer-creation/fixed-position-nonscrollable-body-overlap-expected.txt
@@ -17,10 +17,10 @@ }, { "name": "LayoutNGBlockFlow (positioned) DIV class='fixed lime box'", - "position": [10, 100], "bounds": [100, 100], "contentsOpaque": true, - "backgroundColor": "#00FF00" + "backgroundColor": "#00FF00", + "transform": 2 } ], "transforms": [ @@ -32,6 +32,15 @@ [0, 0, 1, 0], [10, 100, 0, 1] ] + }, + { + "id": 2, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [10, 100, 0, 1] + ] } ] }
diff --git a/third_party/blink/web_tests/compositing/layer-creation/fixed-position-nonscrollable-iframes-in-scrollable-page-expected.txt b/third_party/blink/web_tests/compositing/layer-creation/fixed-position-nonscrollable-iframes-in-scrollable-page-expected.txt index 21627b6..0f23d6e0 100644 --- a/third_party/blink/web_tests/compositing/layer-creation/fixed-position-nonscrollable-iframes-in-scrollable-page-expected.txt +++ b/third_party/blink/web_tests/compositing/layer-creation/fixed-position-nonscrollable-iframes-in-scrollable-page-expected.txt
@@ -15,9 +15,33 @@ "transform": 1 }, { + "name": "LayoutView #document", + "bounds": [150, 150], + "transform": 2 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed lime box'", + "bounds": [100, 100], + "contentsOpaque": true, + "backgroundColor": "#00FF00", + "transform": 3 + }, + { "name": "LayoutIFrame (positioned) IFRAME id='iframe2' class='composited'", "bounds": [154, 154], - "transform": 2 + "transform": 4 + }, + { + "name": "LayoutView #document", + "bounds": [150, 150], + "transform": 5 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed lime box'", + "bounds": [100, 100], + "contentsOpaque": true, + "backgroundColor": "#00FF00", + "transform": 6 }, { "name": "LayoutIFrame (positioned) IFRAME id='iframe3'", @@ -25,6 +49,18 @@ "bounds": [154, 154] }, { + "name": "LayoutView #document", + "bounds": [150, 150], + "transform": 7 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed lime box'", + "bounds": [100, 100], + "contentsOpaque": true, + "backgroundColor": "#00FF00", + "transform": 8 + }, + { "name": "ContentsLayer for Vertical Scrollbar Layer", "position": [785, 0], "bounds": [15, 600], @@ -47,8 +83,66 @@ [1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], + [12, 32, 0, 1] + ] + }, + { + "id": 3, + "parent": 2, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [10, 10, 0, 1] + ] + }, + { + "id": 4, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], [10, 200, 0, 1] ] + }, + { + "id": 5, + "parent": 4, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [2, 2, 0, 1] + ] + }, + { + "id": 6, + "parent": 5, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [10, 10, 0, 1] + ] + }, + { + "id": 7, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [12, 382, 0, 1] + ] + }, + { + "id": 8, + "parent": 7, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [10, 10, 0, 1] + ] } ] }
diff --git a/third_party/blink/web_tests/dark-mode/images/image-as-shader-expected.png b/third_party/blink/web_tests/dark-mode/images/image-as-shader-expected.png new file mode 100644 index 0000000..cab5749 --- /dev/null +++ b/third_party/blink/web_tests/dark-mode/images/image-as-shader-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/dark-mode/images/image-as-shader.html b/third_party/blink/web_tests/dark-mode/images/image-as-shader.html new file mode 100644 index 0000000..a7bf474 --- /dev/null +++ b/third_party/blink/web_tests/dark-mode/images/image-as-shader.html
@@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> + <head> + <style> + html { + background: #000 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQYV2NgYGD4DwABBAEAcCBlCwAAAABJRU5ErkJggg==) repeat 0 0; + } + div { + background-color: white; + width: 100px; + height: 100px; + } + </style> + </head> + <body> + <div></div> + </body> + </html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/hyphens-auto-last-word-001.html b/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/hyphens-auto-last-word-001.html new file mode 100644 index 0000000..273f060 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/hyphens-auto-last-word-001.html
@@ -0,0 +1,21 @@ +<!DOCTYPE html> +<title>CSS Text: `hyphens: auto` for last word</title> +<link rel="author" title="Koji Ishii" href="mailto:kojii@chromium.org"> +<link rel="help" href="https://www.w3.org/TR/css-text-3/#hyphenation"> +<link rel="match" href="reference/hyphens-auto-last-word-001-ref.html"> +<link rel="match" href="reference/hyphens-auto-last-word-001-ref2.html"> +<style> +div { + hyphens: auto; + width: 5ch; + border: 1px solid blue; +} +</style> +<body lang="en-us"> + <div style="width: 10ch">Test example</div> + <div>example</div> + <div>1 example</div> + <div>1234 example</div> + <div>example 5678</div> + <div>1234 example 5678</div> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/hyphens-punctuation-001.html b/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/hyphens-punctuation-001.html new file mode 100644 index 0000000..feea836 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/hyphens-punctuation-001.html
@@ -0,0 +1,17 @@ +<!DOCTYPE html> +<title>CSS Text Test: Automatic hyphenation for trailing punctuation characters</title> +<link rel="author" title="Koji Ishii" href="mailto:kojii@chromium.org"> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#hyphens-property"> +<link rel="match" href="reference/hyphens-punctuation-001-ref.html"> +<style> +div { + hyphens: auto; + width: 5ch; + border: 1px solid blue; +} +</style> +<body lang="en-us"> + <div>00000 example 00000</div> + <div>00000 example. 00000</div> + <div>00000 (example 00000</div> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/reference/hyphens-auto-last-word-001-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/reference/hyphens-auto-last-word-001-ref.html new file mode 100644 index 0000000..7fe23fe7 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/reference/hyphens-auto-last-word-001-ref.html
@@ -0,0 +1,15 @@ +<!DOCTYPE html> +<style> +div { + width: 5ch; + border: 1px solid blue; +} +</style> +<body lang="en-us"> + <div style="width: 10ch">Test ex­am­ple</div> + <div>ex­am­ple</div> + <div>1 ex­am­ple</div> + <div>1234 ex­am­ple</div> + <div>ex­am­ple 5678</div> + <div>1234 ex­am­ple 5678</div> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/reference/hyphens-auto-last-word-001-ref2.html b/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/reference/hyphens-auto-last-word-001-ref2.html new file mode 100644 index 0000000..9c9f413 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/reference/hyphens-auto-last-word-001-ref2.html
@@ -0,0 +1,15 @@ +<!DOCTYPE html> +<style> +div { + width: 5ch; + border: 1px solid blue; +} +</style> +<body lang="en-us"> + <div style="width: 10ch">Test example</div> + <div>ex­am­ple</div> + <div>1<br>ex­am­ple</div> + <div>1234 ex­am­ple</div> + <div>ex­am­ple 5678</div> + <div>1234 ex­am­ple 5678</div> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/reference/hyphens-punctuation-001-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/reference/hyphens-punctuation-001-ref.html new file mode 100644 index 0000000..75e23637 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/reference/hyphens-punctuation-001-ref.html
@@ -0,0 +1,12 @@ +<!DOCTYPE html> +<style> +div { + width: 5ch; + border: 1px solid blue; +} +</style> +<body lang="en-us"> + <div>00000 ex­am­ple 00000</div> + <div>00000 ex­am­ple. 00000</div> + <div>00000 (ex­am­ple 00000</div> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/import-maps/multiple-import-maps/basic-expected.txt b/third_party/blink/web_tests/external/wpt/import-maps/multiple-import-maps/basic-expected.txt new file mode 100644 index 0000000..b56a107 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/import-maps/multiple-import-maps/basic-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Second import map should be rejected assert_array_equals: lengths differ, expected array ["onerror 2", "log:B1", "log:B2", "log:A3"] length 4, got ["log:B1", "log:B2", "log:A3"] length 3 +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/import-maps/multiple-import-maps/basic.html b/third_party/blink/web_tests/external/wpt/import-maps/multiple-import-maps/basic.html new file mode 100644 index 0000000..9ab03dd --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/import-maps/multiple-import-maps/basic.html
@@ -0,0 +1,36 @@ +<!DOCTYPE html> +<html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +const log = []; +</script> +<script type="importmap" onerror="log.push('onerror 1')"> +{ + "imports": { + "../resources/log.js?pipe=sub&name=A1": "../resources/log.js?pipe=sub&name=B1", + "../resources/log.js?pipe=sub&name=A2": "../resources/log.js?pipe=sub&name=B2" + } +} +</script> +<script type="importmap" onerror="log.push('onerror 2')"> +{ + "imports": { + "../resources/log.js?pipe=sub&name=A1": "../resources/log.js?pipe=sub&name=C1", + "../resources/log.js?pipe=sub&name=A3": "../resources/log.js?pipe=sub&name=C3" + } +} +</script> +<script> +// Currently the spec doesn't allow multiple import maps, by setting acquiring +// import maps to false on preparing the first import map. +promise_test(() => { + return import("../resources/log.js?pipe=sub&name=A1") + .then(() => import("../resources/log.js?pipe=sub&name=A2")) + .then(() => import("../resources/log.js?pipe=sub&name=A3")) + .then(() => assert_array_equals( + log, + ["onerror 2", "log:B1", "log:B2", "log:A3"])) + }, + "Second import map should be rejected"); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/import-maps/multiple-import-maps/with-errors-expected.txt b/third_party/blink/web_tests/external/wpt/import-maps/multiple-import-maps/with-errors-expected.txt new file mode 100644 index 0000000..2ac5edb1 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/import-maps/multiple-import-maps/with-errors-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Second import map should be rejected after an import map with errors assert_array_equals: lengths differ, expected array ["onerror 2", "log:A"] length 2, got ["log:C"] length 1 +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/import-maps/multiple-import-maps/with-errors.html b/third_party/blink/web_tests/external/wpt/import-maps/multiple-import-maps/with-errors.html new file mode 100644 index 0000000..a93ecaa --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/import-maps/multiple-import-maps/with-errors.html
@@ -0,0 +1,32 @@ +<!DOCTYPE html> +<html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +setup({allow_uncaught_exception : true}); + +const log = []; +</script> +<script type="importmap" onerror="log.push('onerror 1')"> +Parse Error +</script> +<script type="importmap" onerror="log.push('onerror 2')"> +{ + "imports": { + "../resources/log.js?pipe=sub&name=A": "../resources/log.js?pipe=sub&name=C" + } +} +</script> +<script> +// Currently the spec doesn't allow multiple import maps, by setting acquiring +// import maps to false on preparing the first import map. +// Even the first import map has errors and thus Document's import map is not +// updated, the second import map is still rejected at preparationg. +promise_test(() => { + return import("../resources/log.js?pipe=sub&name=A") + .then(() => assert_array_equals( + log, + ["onerror 2", "log:A"])) + }, + "Second import map should be rejected after an import map with errors"); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/preload/avoid-prefetching-on-text-plain.html b/third_party/blink/web_tests/external/wpt/preload/avoid-prefetching-on-text-plain.html index 45564e1..b14b7e4 100644 --- a/third_party/blink/web_tests/external/wpt/preload/avoid-prefetching-on-text-plain.html +++ b/third_party/blink/web_tests/external/wpt/preload/avoid-prefetching-on-text-plain.html
@@ -16,11 +16,9 @@ window.addEventListener("message", function(msg) { // Parse the Performance API data passed from the plain text iframe. const entries = JSON.parse(msg.data); - const urls = []; const resource_types = []; for (const entry of entries) { resource_types.push(entry.entryType); - urls.push(entry.name); } // If preloading is working correctly, should only see the text document // represented in the performance information. A 'resource' type indicates @@ -33,8 +31,6 @@ } } assert_false(resource_found, "no resources should be present"); - assert_equals(urls.length, 1); - assert_equals(urls[0].endsWith("avoid-prefetching-on-text-plain-inner.html"), true); done(); }); prefetchingIframe.addEventListener('load', function() {
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/current-time.html b/third_party/blink/web_tests/external/wpt/scroll-animations/current-time.html index cbe2d8d6..fe8c64a 100644 --- a/third_party/blink/web_tests/external/wpt/scroll-animations/current-time.html +++ b/third_party/blink/web_tests/external/wpt/scroll-animations/current-time.html
@@ -463,86 +463,4 @@ assert_equals(scrollTimeline.currentTime, scrollTimeline.timeRange); }, 'currentTime handles startScrollOffset > endScrollOffset correctly'); -promise_test(async t => { - const scroller = setupScrollTimelineTest(); - // Set the timeRange such that currentTime maps directly to the value - // scrolled. The contents and scroller are square, so it suffices to compute - // one edge and use it for all the timelines. - const scrollerSize = scroller.scrollHeight - scroller.clientHeight; - - const scrollTimeline = new ScrollTimeline({ - scrollSource: scroller, - timeRange: scrollerSize, - orientation: 'block', - scrollOffsets: [CSS.px(10), CSS.px(20), CSS.px(40), CSS.px(70), CSS.px(90)], - }); - - var offset = 0; - var w = 1 / 4; // offset weight - var p = 0; // progress within the offset - - scroller.scrollTop = 10; - assert_times_equal( - scrollTimeline.currentTime, (offset + p) * w * scrollerSize, - "current time calculation when scroll = " + scroller.scrollTop); - - p = (12 - 10) / (20 - 10); - scroller.scrollTop = 12; - await waitForNextFrame(); - assert_times_equal( - scrollTimeline.currentTime, (offset + p) * w * scrollerSize, - "current time calculation when scroll = " + scroller.scrollTop); - - offset = 1; - p = 0; - scroller.scrollTop = 20; - await waitForNextFrame(); - assert_times_equal( - scrollTimeline.currentTime, (offset + p) * w * scrollerSize, - "current time calculation when scroll = " + scroller.scrollTop); - - p = (35 - 20) / (40 - 20); - scroller.scrollTop = 35; - await waitForNextFrame(); - assert_times_equal( - scrollTimeline.currentTime, (offset + p) * w * scrollerSize, - "current time calculation when scroll = " + scroller.scrollTop); - - offset = 2; - p = 0; - scroller.scrollTop = 40; - await waitForNextFrame(); - assert_times_equal( - scrollTimeline.currentTime, (offset + p) * w * scrollerSize, - "current time calculation when scroll = " + scroller.scrollTop); - - p = (60 - 40) / (70 - 40); - scroller.scrollTop = 60; - await waitForNextFrame(); - assert_times_equal( - scrollTimeline.currentTime, (offset + p) * w * scrollerSize, - "current time calculation when scroll = " + scroller.scrollTop); - - offset = 3; - p = 0; - scroller.scrollTop = 70; - await waitForNextFrame(); - assert_times_equal( - scrollTimeline.currentTime, (offset + p) * w * scrollerSize, - "current time calculation when scroll = " + scroller.scrollTop); - - p = (80 - 70) / (90 - 70); - scroller.scrollTop = 80; - await waitForNextFrame(); - assert_times_equal( - scrollTimeline.currentTime, (offset + p) * w * scrollerSize, - "current time calculation when scroll = " + scroller.scrollTop); - - scroller.scrollTop = 90; - await waitForNextFrame(); - assert_times_equal( - scrollTimeline.currentTime, scrollerSize, - "current time calculation when scroll = " + scroller.scrollTop); -}, 'currentTime calculations when multiple scroll offsets are specified'); - </script>
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/multiple-scroll-offsets.tentative.html b/third_party/blink/web_tests/external/wpt/scroll-animations/multiple-scroll-offsets.tentative.html new file mode 100644 index 0000000..026b2e7 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/scroll-animations/multiple-scroll-offsets.tentative.html
@@ -0,0 +1,143 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>ScrollTimeline current time algorithm</title> +<link rel="help" href="https://wicg.github.io/scroll-animations/#current-time-algorithm"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/web-animations/testcommon.js"></script> +<script src="./resources/scrolltimeline-utils.js"></script> + +<body></body> + +<script> +'use strict'; + +promise_test(async t => { + const scroller = setupScrollTimelineTest(); + const scrollerSize = scroller.scrollHeight - scroller.clientHeight; + + const scrollTimeline = new ScrollTimeline({ + scrollSource: scroller, + timeRange: scrollerSize, + orientation: 'block', + scrollOffsets: [CSS.px(10), CSS.px(20), CSS.px(40), CSS.px(70), CSS.px(90)], + }); + + var offset = 0; + var w = 1 / 4; // offset weight + var p = 0; // progress within the offset + + scroller.scrollTop = 10; + assert_times_equal( + scrollTimeline.currentTime, (offset + p) * w * scrollerSize, + "current time calculation when scroll = " + scroller.scrollTop); + + p = (12 - 10) / (20 - 10); + scroller.scrollTop = 12; + await waitForNextFrame(); + assert_times_equal( + scrollTimeline.currentTime, (offset + p) * w * scrollerSize, + "current time calculation when scroll = " + scroller.scrollTop); + + offset = 1; + p = 0; + scroller.scrollTop = 20; + await waitForNextFrame(); + assert_times_equal( + scrollTimeline.currentTime, (offset + p) * w * scrollerSize, + "current time calculation when scroll = " + scroller.scrollTop); + + p = (35 - 20) / (40 - 20); + scroller.scrollTop = 35; + await waitForNextFrame(); + assert_times_equal( + scrollTimeline.currentTime, (offset + p) * w * scrollerSize, + "current time calculation when scroll = " + scroller.scrollTop); + + offset = 2; + p = 0; + scroller.scrollTop = 40; + await waitForNextFrame(); + assert_times_equal( + scrollTimeline.currentTime, (offset + p) * w * scrollerSize, + "current time calculation when scroll = " + scroller.scrollTop); + + p = (60 - 40) / (70 - 40); + scroller.scrollTop = 60; + await waitForNextFrame(); + assert_times_equal( + scrollTimeline.currentTime, (offset + p) * w * scrollerSize, + "current time calculation when scroll = " + scroller.scrollTop); + + offset = 3; + p = 0; + scroller.scrollTop = 70; + await waitForNextFrame(); + assert_times_equal( + scrollTimeline.currentTime, (offset + p) * w * scrollerSize, + "current time calculation when scroll = " + scroller.scrollTop); + + p = (80 - 70) / (90 - 70); + scroller.scrollTop = 80; + await waitForNextFrame(); + assert_times_equal( + scrollTimeline.currentTime, (offset + p) * w * scrollerSize, + "current time calculation when scroll = " + scroller.scrollTop); + + scroller.scrollTop = 90; + await waitForNextFrame(); + assert_times_equal( + scrollTimeline.currentTime, scrollerSize, + "current time calculation when scroll = " + scroller.scrollTop); +}, 'currentTime calculations when multiple scroll offsets are specified'); + +promise_test(async t => { + const scroller = setupScrollTimelineTest(); + const scrollerSize = scroller.scrollHeight - scroller.clientHeight; + + var scrollTimeline = new ScrollTimeline({ + scrollSource: scroller, + timeRange: scrollerSize, + orientation: 'block', + scrollOffsets: [CSS.px(300), CSS.px(200), CSS.px(10)], + }); + + scroller.scrollTop = 250; + await waitForNextFrame(); + assert_times_equal( + scrollTimeline.currentTime, 0, + "current time calculation when scroll = " + scroller.scrollTop); + + scroller.scrollTop = 400; + await waitForNextFrame(); + assert_times_equal( + scrollTimeline.currentTime, scrollerSize, + "current time calculation when scroll = " + scroller.scrollTop); + + scrollTimeline = new ScrollTimeline({ + scrollSource: scroller, + timeRange: scrollerSize, + orientation: 'block', + scrollOffsets: [CSS.px(0), CSS.px(400), CSS.px(200)], + }); + + scroller.scrollTop = 100; + await waitForNextFrame(); + assert_times_equal( + scrollTimeline.currentTime, 0.25 * 0.5 * scrollerSize, + "current time calculation when scroll = " + scroller.scrollTop); + + scrollTimeline = new ScrollTimeline({ + scrollSource: scroller, + timeRange: scrollerSize, + orientation: 'block', + scrollOffsets: [CSS.px(200), CSS.px(0), CSS.px(400)], + }); + + scroller.scrollTop = 200; + await waitForNextFrame(); + assert_times_equal( + scrollTimeline.currentTime, 0.5 * scrollerSize + 0.5 * 0.5 * scrollerSize, + "current time calculation when scroll = " + scroller.scrollTop); +}, 'currentTime calculations when overlapping scroll offsets are specified'); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/webcodecs/audio-decoder.any.js b/third_party/blink/web_tests/external/wpt/webcodecs/audio-decoder.any.js index 70110a7..a636723 100644 --- a/third_party/blink/web_tests/external/wpt/webcodecs/audio-decoder.any.js +++ b/third_party/blink/web_tests/external/wpt/webcodecs/audio-decoder.any.js
@@ -15,6 +15,55 @@ }); } +const invalidConfigs = [ + { + comment: 'Emtpy codec', + config: {codec: ''}, + }, + { + comment: 'Unrecognized codec', + config: {codec: 'bogus'}, + }, + { + comment: 'Video codec', + config: {codec: 'vp8'}, + }, + { + comment: 'Ambiguous codec', + config: {codec: 'vp9'}, + }, + { + comment: 'Codec with MIME type', + config: {codec: 'audio/webm; codecs="opus"'}, + }, +]; + +invalidConfigs.forEach(entry => { + promise_test(t => { + return promise_rejects_js(t, TypeError, AudioDecoder.isConfigSupported(entry.config)); + }, 'Test that AudioDecoder.isConfigSupported() rejects invalid config:' + entry.comment); +}); + + +invalidConfigs.forEach(entry => { + async_test(t => { + let codec = new AudioDecoder(getDefaultCodecInit(t)); + assert_throws_js(TypeError, () => { codec.configure(entry.config); }); + t.done(); + }, 'Test that AudioDecoder.configure() rejects invalid config:' + entry.comment); +}); + +promise_test(t => { + return AudioDecoder.isConfigSupported({ + codec: 'opus', + sampleRate: 48000, + numberOfChannels: 2, + // Opus header extradata. + description: new Uint8Array([0x4f, 0x70, 0x75, 0x73, 0x48, 0x65, 0x61, 0x64, + 0x01, 0x02, 0x38, 0x01, 0x80, 0xbb, 0x00, 0x00, 0x00, 0x00, 0x00]) + }); +}, 'Test AudioDecoder.isConfigSupported() with a valid config'); + promise_test(t => { // AudioDecoderInit lacks required fields. assert_throws_js(TypeError, () => { new AudioDecoder({}); });
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/compositing/layer-creation/fixed-position-nonscrollable-body-expected.txt b/third_party/blink/web_tests/flag-specific/composite-after-paint/compositing/layer-creation/fixed-position-nonscrollable-body-expected.txt index 0a2db58..23e0520 100644 --- a/third_party/blink/web_tests/flag-specific/composite-after-paint/compositing/layer-creation/fixed-position-nonscrollable-body-expected.txt +++ b/third_party/blink/web_tests/flag-specific/composite-after-paint/compositing/layer-creation/fixed-position-nonscrollable-body-expected.txt
@@ -8,10 +8,21 @@ }, { "name": "LayoutNGBlockFlow (positioned) DIV class='fixed lime box'", - "position": [10, 100], "bounds": [100, 100], "contentsOpaque": true, - "backgroundColor": "#00FF00" + "backgroundColor": "#00FF00", + "transform": 1 + } + ], + "transforms": [ + { + "id": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [10, 100, 0, 1] + ] } ] }
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/compositing/layer-creation/fixed-position-nonscrollable-body-overlap-expected.txt b/third_party/blink/web_tests/flag-specific/composite-after-paint/compositing/layer-creation/fixed-position-nonscrollable-body-overlap-expected.txt index 93f980f..b945d37 100644 --- a/third_party/blink/web_tests/flag-specific/composite-after-paint/compositing/layer-creation/fixed-position-nonscrollable-body-overlap-expected.txt +++ b/third_party/blink/web_tests/flag-specific/composite-after-paint/compositing/layer-creation/fixed-position-nonscrollable-body-overlap-expected.txt
@@ -17,10 +17,10 @@ }, { "name": "LayoutNGBlockFlow (positioned) DIV class='fixed lime box'", - "position": [10, 100], "bounds": [100, 100], "contentsOpaque": true, - "backgroundColor": "#00FF00" + "backgroundColor": "#00FF00", + "transform": 2 } ], "transforms": [ @@ -32,6 +32,15 @@ [0, 0, 1, 0], [10, 100, 0, 1] ] + }, + { + "id": 2, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [10, 100, 0, 1] + ] } ] }
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/compositing/layer-creation/fixed-position-nonscrollable-iframes-in-scrollable-page-expected.txt b/third_party/blink/web_tests/flag-specific/composite-after-paint/compositing/layer-creation/fixed-position-nonscrollable-iframes-in-scrollable-page-expected.txt index 63df1d96..09264d2 100644 --- a/third_party/blink/web_tests/flag-specific/composite-after-paint/compositing/layer-creation/fixed-position-nonscrollable-iframes-in-scrollable-page-expected.txt +++ b/third_party/blink/web_tests/flag-specific/composite-after-paint/compositing/layer-creation/fixed-position-nonscrollable-iframes-in-scrollable-page-expected.txt
@@ -15,9 +15,23 @@ "transform": 1 }, { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed lime box'", + "bounds": [100, 100], + "contentsOpaque": true, + "backgroundColor": "#00FF00", + "transform": 3 + }, + { "name": "LayoutIFrame (positioned) IFRAME id='iframe2' class='composited'", "bounds": [154, 154], - "transform": 2 + "transform": 4 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed lime box'", + "bounds": [100, 100], + "contentsOpaque": true, + "backgroundColor": "#00FF00", + "transform": 6 }, { "name": "LayoutIFrame (positioned) IFRAME id='iframe3'", @@ -25,6 +39,13 @@ "bounds": [154, 154] }, { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed lime box'", + "bounds": [100, 100], + "contentsOpaque": true, + "backgroundColor": "#00FF00", + "transform": 8 + }, + { "name": "VerticalScrollbar", "position": [785, 0], "bounds": [15, 600] @@ -46,8 +67,66 @@ [1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], + [12, 32, 0, 1] + ] + }, + { + "id": 3, + "parent": 2, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [10, 10, 0, 1] + ] + }, + { + "id": 4, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], [10, 200, 0, 1] ] + }, + { + "id": 5, + "parent": 4, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [2, 2, 0, 1] + ] + }, + { + "id": 6, + "parent": 5, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [10, 10, 0, 1] + ] + }, + { + "id": 7, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [12, 382, 0, 1] + ] + }, + { + "id": 8, + "parent": 7, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [10, 10, 0, 1] + ] } ] }
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/compositing/layer-creation/main-thread-scrolling-non-composited-fixed-overflow-hidden-expected.txt b/third_party/blink/web_tests/flag-specific/composite-after-paint/compositing/layer-creation/main-thread-scrolling-non-composited-fixed-overflow-hidden-expected.txt index b8299e9..bf1b2f6 100644 --- a/third_party/blink/web_tests/flag-specific/composite-after-paint/compositing/layer-creation/main-thread-scrolling-non-composited-fixed-overflow-hidden-expected.txt +++ b/third_party/blink/web_tests/flag-specific/composite-after-paint/compositing/layer-creation/main-thread-scrolling-non-composited-fixed-overflow-hidden-expected.txt
@@ -9,8 +9,19 @@ }, { "name": "LayoutNGBlockFlow (positioned) DIV class='fixed'", - "position": [10, 10], - "bounds": [39, 20] + "bounds": [39, 20], + "transform": 1 + } + ], + "transforms": [ + { + "id": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [10, 10, 0, 1] + ] } ] }
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/scroll/fixed-scroll-viewport-scroll-hidden-expected.txt b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/scroll/fixed-scroll-viewport-scroll-hidden-expected.txt index 029cb61..2a59cfd 100644 --- a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/scroll/fixed-scroll-viewport-scroll-hidden-expected.txt +++ b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/scroll/fixed-scroll-viewport-scroll-hidden-expected.txt
@@ -9,10 +9,10 @@ }, { "name": "LayoutNGBlockFlow (positioned) DIV class='fixed green'", - "position": [8, 100], "bounds": [100, 100], "contentsOpaque": true, - "backgroundColor": "#008000" + "backgroundColor": "#008000", + "transform": 2 } ], "transforms": [ @@ -24,6 +24,15 @@ [0, 0, 1, 0], [0, -100, 0, 1] ] + }, + { + "id": 2, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [8, 100, 0, 1] + ] } ] }
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/scroll/scrolled-iframe-scrollbar-change-expected.txt b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/scroll/scrolled-iframe-scrollbar-change-expected.txt index 10650af..23f92dd 100644 --- a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/scroll/scrolled-iframe-scrollbar-change-expected.txt +++ b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/scroll/scrolled-iframe-scrollbar-change-expected.txt
@@ -4,9 +4,31 @@ "name": "Scrolling background of LayoutView #document", "bounds": [804, 604], "contentsOpaque": true, + "backgroundColor": "#FF0000", + "invalidations": [ + [787, 2, 15, 600], + [779, 2, 15, 592] + ] + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV id='overlay'", + "bounds": [800, 600], + "contentsOpaque": true, "backgroundColor": "#008000", "invalidations": [ - [2, 2, 800, 600] + [0, 0, 800, 600] + ], + "transform": 1 + } + ], + "transforms": [ + { + "id": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [2, 2, 0, 1] ] } ]
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/fixed-position-nonscrollable-body-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/fixed-position-nonscrollable-body-expected.txt new file mode 100644 index 0000000..118b301 --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/fixed-position-nonscrollable-body-expected.txt
@@ -0,0 +1,29 @@ +{ + "layers": [ + { + "name": "Scrolling Contents Layer", + "bounds": [800, 4021], + "contentsOpaque": true, + "backgroundColor": "#FFFFFF" + }, + { + "name": "LayoutBlockFlow (positioned) DIV class='fixed lime box'", + "bounds": [100, 100], + "contentsOpaque": true, + "backgroundColor": "#00FF00", + "transform": 1 + } + ], + "transforms": [ + { + "id": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [10, 100, 0, 1] + ] + } + ] +} +
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/fixed-position-nonscrollable-body-overlap-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/fixed-position-nonscrollable-body-overlap-expected.txt index 161eb9d..80260cc 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/fixed-position-nonscrollable-body-overlap-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/fixed-position-nonscrollable-body-overlap-expected.txt
@@ -17,10 +17,10 @@ }, { "name": "LayoutBlockFlow (positioned) DIV class='fixed lime box'", - "position": [10, 100], "bounds": [100, 100], "contentsOpaque": true, - "backgroundColor": "#00FF00" + "backgroundColor": "#00FF00", + "transform": 2 } ], "transforms": [ @@ -32,6 +32,15 @@ [0, 0, 1, 0], [10, 100, 0, 1] ] + }, + { + "id": 2, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [10, 100, 0, 1] + ] } ] }
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/fixed-position-nonscrollable-iframes-in-scrollable-page-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/fixed-position-nonscrollable-iframes-in-scrollable-page-expected.txt index 81e7129..32458f0 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/fixed-position-nonscrollable-iframes-in-scrollable-page-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/fixed-position-nonscrollable-iframes-in-scrollable-page-expected.txt
@@ -15,9 +15,33 @@ "transform": 1 }, { + "name": "LayoutView #document", + "bounds": [150, 150], + "transform": 2 + }, + { + "name": "LayoutBlockFlow (positioned) DIV class='fixed lime box'", + "bounds": [100, 100], + "contentsOpaque": true, + "backgroundColor": "#00FF00", + "transform": 3 + }, + { "name": "LayoutIFrame (positioned) IFRAME id='iframe2' class='composited'", "bounds": [154, 154], - "transform": 2 + "transform": 4 + }, + { + "name": "LayoutView #document", + "bounds": [150, 150], + "transform": 5 + }, + { + "name": "LayoutBlockFlow (positioned) DIV class='fixed lime box'", + "bounds": [100, 100], + "contentsOpaque": true, + "backgroundColor": "#00FF00", + "transform": 6 }, { "name": "LayoutIFrame (positioned) IFRAME id='iframe3'", @@ -25,6 +49,18 @@ "bounds": [154, 154] }, { + "name": "LayoutView #document", + "bounds": [150, 150], + "transform": 7 + }, + { + "name": "LayoutBlockFlow (positioned) DIV class='fixed lime box'", + "bounds": [100, 100], + "contentsOpaque": true, + "backgroundColor": "#00FF00", + "transform": 8 + }, + { "name": "ContentsLayer for Vertical Scrollbar Layer", "position": [785, 0], "bounds": [15, 600], @@ -47,8 +83,66 @@ [1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], + [12, 32, 0, 1] + ] + }, + { + "id": 3, + "parent": 2, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [10, 10, 0, 1] + ] + }, + { + "id": 4, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], [10, 200, 0, 1] ] + }, + { + "id": 5, + "parent": 4, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [2, 2, 0, 1] + ] + }, + { + "id": 6, + "parent": 5, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [10, 10, 0, 1] + ] + }, + { + "id": 7, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [12, 382, 0, 1] + ] + }, + { + "id": 8, + "parent": 7, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [10, 10, 0, 1] + ] } ] }
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/main-thread-scrolling-non-composited-fixed-overflow-hidden-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/main-thread-scrolling-non-composited-fixed-overflow-hidden-expected.txt new file mode 100644 index 0000000..a110cb2 --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/main-thread-scrolling-non-composited-fixed-overflow-hidden-expected.txt
@@ -0,0 +1,28 @@ +TEST +{ + "layers": [ + { + "name": "Scrolling Contents Layer", + "bounds": [800, 5021], + "contentsOpaque": true, + "backgroundColor": "#FFFFFF" + }, + { + "name": "LayoutBlockFlow (positioned) DIV class='fixed'", + "bounds": [39, 20], + "transform": 1 + } + ], + "transforms": [ + { + "id": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [10, 10, 0, 1] + ] + } + ] +} +
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/scroll/fixed-scroll-viewport-scroll-hidden-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/scroll/fixed-scroll-viewport-scroll-hidden-expected.txt new file mode 100644 index 0000000..6315b15e --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/scroll/fixed-scroll-viewport-scroll-hidden-expected.txt
@@ -0,0 +1,39 @@ +{ + "layers": [ + { + "name": "Scrolling Contents Layer", + "bounds": [800, 2016], + "contentsOpaque": true, + "backgroundColor": "#FFFFFF", + "transform": 1 + }, + { + "name": "LayoutBlockFlow (positioned) DIV class='fixed green'", + "bounds": [100, 100], + "contentsOpaque": true, + "backgroundColor": "#008000", + "transform": 2 + } + ], + "transforms": [ + { + "id": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [0, -100, 0, 1] + ] + }, + { + "id": 2, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [8, 100, 0, 1] + ] + } + ] +} +
diff --git a/third_party/blink/web_tests/http/tests/mediasession/callback-alive-after-gc.html b/third_party/blink/web_tests/http/tests/mediasession/callback-alive-after-gc.html new file mode 100644 index 0000000..f17bc2d --- /dev/null +++ b/third_party/blink/web_tests/http/tests/mediasession/callback-alive-after-gc.html
@@ -0,0 +1,21 @@ +<!DOCTYPE html> +<title>Test that setting MediaSession callbacks are alive after garbage-collection</title> +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> +<script type="module"> +import '/js-test-resources/gc.js'; + +import {MediaSessionServiceMock} from './resources/mediasessionservice-mock.js'; +import {MediaSessionAction} from '/gen/services/media_session/public/mojom/media_session.mojom.m.js'; + +async_test(t => { + const mock = new MediaSessionServiceMock; + mock.setClientCallback(_ => { + gc(); + setTimeout(_ => { + mock.getClient().didReceiveAction(MediaSessionAction.kPlay); + }); + }); + window.navigator.mediaSession.setActionHandler("play", _ => { t.done(); }); +}); +</script>
diff --git a/third_party/blink/web_tests/media/mediasession/mojo/file-image-removed.html b/third_party/blink/web_tests/http/tests/mediasession/file-image-removed.html similarity index 65% rename from third_party/blink/web_tests/media/mediasession/mojo/file-image-removed.html rename to third_party/blink/web_tests/http/tests/mediasession/file-image-removed.html index f2e2484..c1b26e7 100644 --- a/third_party/blink/web_tests/media/mediasession/mojo/file-image-removed.html +++ b/third_party/blink/web_tests/http/tests/mediasession/file-image-removed.html
@@ -2,14 +2,12 @@ <title>MediaSession Mojo Test</title> <script src="../../../resources/testharness.js"></script> <script src="../../../resources/testharnessreport.js"></script> -<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> -<script src="file:///gen/third_party/blink/public/mojom/mediasession/media_session.mojom.js"></script> -<script src="resources/mediasessionservice-mock.js"></script> -<script src="resources/utils.js"></script> -<script> +<script type="module"> +import {MediaSessionServiceMock} from './resources/mediasessionservice-mock.js'; +import {assert_metadata_equals} from './resources/utils.js'; async_test(function(t) { - let m = mediaSessionServiceMock; + let m = new MediaSessionServiceMock(); var metadata = new MediaMetadata({ artwork: [ { src: "file:///foo/bar.jpg", type: "image/jpeg"}
diff --git a/third_party/blink/web_tests/media/mediasession/mojo/media-control-action-reaches-client.html b/third_party/blink/web_tests/http/tests/mediasession/media-control-action-reaches-client.html similarity index 64% rename from third_party/blink/web_tests/media/mediasession/mojo/media-control-action-reaches-client.html rename to third_party/blink/web_tests/http/tests/mediasession/media-control-action-reaches-client.html index b9f5349..1d1e63d 100644 --- a/third_party/blink/web_tests/media/mediasession/mojo/media-control-action-reaches-client.html +++ b/third_party/blink/web_tests/http/tests/mediasession/media-control-action-reaches-client.html
@@ -2,12 +2,9 @@ <title>MediaSession Mojo Test</title> <script src="../../../resources/testharness.js"></script> <script src="../../../resources/testharnessreport.js"></script> -<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> -<script src="file:///gen/services/media_session/public/mojom/media_session.mojom.js"></script> -<script src="file:///gen/third_party/blink/public/mojom/mediasession/media_session.mojom.js"></script> -<script src="resources/mediasessionservice-mock.js"></script> -<script src="resources/utils.js"></script> -<script> +<script type="module"> +import {MediaSessionServiceMock} from './resources/mediasessionservice-mock.js'; +import {MediaSessionAction} from '/gen/services/media_session/public/mojom/media_session.mojom.m.js'; var mock; @@ -45,18 +42,18 @@ window.navigator.mediaSession.setActionHandler( "seekforward", t.step_func(checkExpectation.bind(null, t, "seekforward"))); - mock.getClient().didReceiveAction(mediaSession.mojom.MediaSessionAction.kPlay); - mock.getClient().didReceiveAction(mediaSession.mojom.MediaSessionAction.kPause); - mock.getClient().didReceiveAction(mediaSession.mojom.MediaSessionAction.kPreviousTrack); - mock.getClient().didReceiveAction(mediaSession.mojom.MediaSessionAction.kNextTrack); - mock.getClient().didReceiveAction(mediaSession.mojom.MediaSessionAction.kSeekBackward); - mock.getClient().didReceiveAction(mediaSession.mojom.MediaSessionAction.kSeekForward); + mock.getClient().didReceiveAction(MediaSessionAction.kPlay); + mock.getClient().didReceiveAction(MediaSessionAction.kPause); + mock.getClient().didReceiveAction(MediaSessionAction.kPreviousTrack); + mock.getClient().didReceiveAction(MediaSessionAction.kNextTrack); + mock.getClient().didReceiveAction(MediaSessionAction.kSeekBackward); + mock.getClient().didReceiveAction(MediaSessionAction.kSeekForward); } // Use async_test to do asynchronous setup since setup() only works for // synchronous setup. async_test(function(t) { - mock = mediaSessionServiceMock; + mock = new MediaSessionServiceMock(); mock.setClientCallback(t.step_func(runTests.bind(null, t))); // Touch window.navigator.mediaSession to start the service. window.navigator.mediaSession.metadata = null;
diff --git a/third_party/blink/web_tests/http/tests/mediasession/media-control-seek-to-action-reaches-client.html b/third_party/blink/web_tests/http/tests/mediasession/media-control-seek-to-action-reaches-client.html new file mode 100644 index 0000000..67aa738 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/mediasession/media-control-seek-to-action-reaches-client.html
@@ -0,0 +1,23 @@ +<!DOCTYPE html> +<title>MediaSession Mojo Test</title> +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> +<script type="module"> +import {MediaSessionServiceMock} from './resources/mediasessionservice-mock.js'; +import {MediaSessionAction} from '/gen/services/media_session/public/mojom/media_session.mojom.m.js'; + +async_test((t) => { + const mediaSessionServiceMock = new MediaSessionServiceMock(); + mediaSessionServiceMock.setClientCallback(t.step_func(() => { + mediaSessionServiceMock.getClient().didReceiveAction( + MediaSessionAction.kSeekTo, + {seekTo: {seekTime: {microseconds: 10000000}, fastSeek: true}}); + })); + + window.navigator.mediaSession.setActionHandler("seekto", t.step_func_done((e) => { + assert_equals(e.action, "seekto"); + assert_equals(e.seekTime, 10); + assert_true(e.fastSeek); + })); +}, "test that the seek to action reaches client"); +</script>
diff --git a/third_party/blink/web_tests/media/mediasession/mojo/media-control-set-handler-notifies-service.html b/third_party/blink/web_tests/http/tests/mediasession/media-control-set-handler-notifies-service.html similarity index 66% rename from third_party/blink/web_tests/media/mediasession/mojo/media-control-set-handler-notifies-service.html rename to third_party/blink/web_tests/http/tests/mediasession/media-control-set-handler-notifies-service.html index 8937197c..2abbfa2 100644 --- a/third_party/blink/web_tests/media/mediasession/mojo/media-control-set-handler-notifies-service.html +++ b/third_party/blink/web_tests/http/tests/mediasession/media-control-set-handler-notifies-service.html
@@ -2,12 +2,9 @@ <title>Test that setting MediaSession event handler should notify the service</title> <script src="../../../resources/testharness.js"></script> <script src="../../../resources/testharnessreport.js"></script> -<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> -<script src="file:///gen/services/media_session/public/mojom/media_session.mojom.js"></script> -<script src="file:///gen/third_party/blink/public/mojom/mediasession/media_session.mojom.js"></script> -<script src="resources/mediasessionservice-mock.js"></script> -<script src="resources/utils.js"></script> -<script> +<script type="module"> +import {MediaSessionServiceMock} from './resources/mediasessionservice-mock.js'; +import {MediaSessionAction} from '/gen/services/media_session/public/mojom/media_session.mojom.m.js'; var expectations; @@ -17,34 +14,34 @@ function getExpectations() { if (!expectations) { expectations = [ - [ mediaSession.mojom.MediaSessionAction.kPlay, true ], - [ mediaSession.mojom.MediaSessionAction.kPause, true ], - [ mediaSession.mojom.MediaSessionAction.kPreviousTrack, true ], - [ mediaSession.mojom.MediaSessionAction.kNextTrack, true ], - [ mediaSession.mojom.MediaSessionAction.kSeekBackward, true ], - [ mediaSession.mojom.MediaSessionAction.kSeekForward, true ], - [ mediaSession.mojom.MediaSessionAction.kSeekTo, true ], - [ mediaSession.mojom.MediaSessionAction.kPlay, false ], - [ mediaSession.mojom.MediaSessionAction.kPause, false ], - [ mediaSession.mojom.MediaSessionAction.kPreviousTrack, false ], - [ mediaSession.mojom.MediaSessionAction.kNextTrack, false ], - [ mediaSession.mojom.MediaSessionAction.kSeekBackward, false ], - [ mediaSession.mojom.MediaSessionAction.kSeekForward, false ], - [ mediaSession.mojom.MediaSessionAction.kSeekTo, false ], - [ mediaSession.mojom.MediaSessionAction.kPlay, true ], - [ mediaSession.mojom.MediaSessionAction.kPause, true ], - [ mediaSession.mojom.MediaSessionAction.kPreviousTrack, true ], - [ mediaSession.mojom.MediaSessionAction.kNextTrack, true ], - [ mediaSession.mojom.MediaSessionAction.kSeekBackward, true ], - [ mediaSession.mojom.MediaSessionAction.kSeekForward, true ], - [ mediaSession.mojom.MediaSessionAction.kSeekTo, true ], + [ MediaSessionAction.kPlay, true ], + [ MediaSessionAction.kPause, true ], + [ MediaSessionAction.kPreviousTrack, true ], + [ MediaSessionAction.kNextTrack, true ], + [ MediaSessionAction.kSeekBackward, true ], + [ MediaSessionAction.kSeekForward, true ], + [ MediaSessionAction.kSeekTo, true ], + [ MediaSessionAction.kPlay, false ], + [ MediaSessionAction.kPause, false ], + [ MediaSessionAction.kPreviousTrack, false ], + [ MediaSessionAction.kNextTrack, false ], + [ MediaSessionAction.kSeekBackward, false ], + [ MediaSessionAction.kSeekForward, false ], + [ MediaSessionAction.kSeekTo, false ], + [ MediaSessionAction.kPlay, true ], + [ MediaSessionAction.kPause, true ], + [ MediaSessionAction.kPreviousTrack, true ], + [ MediaSessionAction.kNextTrack, true ], + [ MediaSessionAction.kSeekBackward, true ], + [ MediaSessionAction.kSeekForward, true ], + [ MediaSessionAction.kSeekTo, true ], ]; } return expectations; } async_test(function(t) { - let m = mediaSessionServiceMock; + const m = new MediaSessionServiceMock(); m.setEnableDisableActionCallback(t.step_func(function(action, isEnabled) { var expectedAction = getExpectations()[nextExpectation][0]; var expectedIsEnabled = getExpectations()[nextExpectation][1];
diff --git a/third_party/blink/web_tests/media/mediasession/mojo/metadata-async.html b/third_party/blink/web_tests/http/tests/mediasession/metadata-async.html similarity index 85% rename from third_party/blink/web_tests/media/mediasession/mojo/metadata-async.html rename to third_party/blink/web_tests/http/tests/mediasession/metadata-async.html index 5a726b0..5b3421e 100644 --- a/third_party/blink/web_tests/media/mediasession/mojo/metadata-async.html +++ b/third_party/blink/web_tests/http/tests/mediasession/metadata-async.html
@@ -2,11 +2,9 @@ <title>MediaMetadata Mojo Test</title> <script src="../../../resources/testharness.js"></script> <script src="../../../resources/testharnessreport.js"></script> -<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> -<script src="file:///gen/third_party/blink/public/mojom/mediasession/media_session.mojom.js"></script> -<script src="resources/mediasessionservice-mock.js"></script> -<script src="resources/utils.js"></script> -<script> +<script type="module"> +import {MediaSessionServiceMock} from './resources/mediasessionservice-mock.js'; +import {assert_metadata_equals} from './resources/utils.js'; async_test(t => { // The following are expected results. @@ -39,7 +37,7 @@ ]; var resultId = 0; - let m = mediaSessionServiceMock; + const m = new MediaSessionServiceMock(); m.setMetadataCallback(t.step_func(receivedMetadata => { assert_metadata_equals(receivedMetadata, results[resultId]); ++resultId;
diff --git a/third_party/blink/web_tests/media/mediasession/mojo/metadata-propagated-twice.html b/third_party/blink/web_tests/http/tests/mediasession/metadata-propagated-twice.html similarity index 71% rename from third_party/blink/web_tests/media/mediasession/mojo/metadata-propagated-twice.html rename to third_party/blink/web_tests/http/tests/mediasession/metadata-propagated-twice.html index dbdff47..ab720fba 100644 --- a/third_party/blink/web_tests/media/mediasession/mojo/metadata-propagated-twice.html +++ b/third_party/blink/web_tests/http/tests/mediasession/metadata-propagated-twice.html
@@ -2,14 +2,12 @@ <title>MediaSession Mojo Test</title> <script src="../../../resources/testharness.js"></script> <script src="../../../resources/testharnessreport.js"></script> -<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> -<script src="file:///gen/third_party/blink/public/mojom/mediasession/media_session.mojom.js"></script> -<script src="resources/mediasessionservice-mock.js"></script> -<script src="resources/utils.js"></script> -<script> +<script type="module"> +import {MediaSessionServiceMock} from './resources/mediasessionservice-mock.js'; +import {assert_metadata_equals} from './resources/utils.js'; async_test(function(t) { - let m = mediaSessionServiceMock; + const m = new MediaSessionServiceMock(); var dontCareMetadata = new MediaMetadata({}); m.setMetadataCallback(t.step_func(function() {
diff --git a/third_party/blink/web_tests/media/mediasession/mojo/metadata-propagated.html b/third_party/blink/web_tests/http/tests/mediasession/metadata-propagated.html similarity index 66% rename from third_party/blink/web_tests/media/mediasession/mojo/metadata-propagated.html rename to third_party/blink/web_tests/http/tests/mediasession/metadata-propagated.html index 31fa8bf8..321420e 100644 --- a/third_party/blink/web_tests/media/mediasession/mojo/metadata-propagated.html +++ b/third_party/blink/web_tests/http/tests/mediasession/metadata-propagated.html
@@ -2,14 +2,12 @@ <title>MediaSession Mojo Test</title> <script src="../../../resources/testharness.js"></script> <script src="../../../resources/testharnessreport.js"></script> -<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> -<script src="file:///gen/third_party/blink/public/mojom/mediasession/media_session.mojom.js"></script> -<script src="resources/mediasessionservice-mock.js"></script> -<script src="resources/utils.js"></script> -<script> +<script type="module"> +import {MediaSessionServiceMock} from './resources/mediasessionservice-mock.js'; +import {assert_metadata_equals} from './resources/utils.js'; async_test(function(t) { - let m = mediaSessionServiceMock; + const m = new MediaSessionServiceMock(); var metadata = new MediaMetadata({ title: "title1", artist: "artist1",
diff --git a/third_party/blink/web_tests/media/mediasession/mojo/metadata-session-link.html b/third_party/blink/web_tests/http/tests/mediasession/metadata-session-link.html similarity index 82% rename from third_party/blink/web_tests/media/mediasession/mojo/metadata-session-link.html rename to third_party/blink/web_tests/http/tests/mediasession/metadata-session-link.html index 6d6fe39..59cd24e 100644 --- a/third_party/blink/web_tests/media/mediasession/mojo/metadata-session-link.html +++ b/third_party/blink/web_tests/http/tests/mediasession/metadata-session-link.html
@@ -2,11 +2,9 @@ <title>MediaMetadata / MediaSession link Mojo Test</title> <script src="../../../resources/testharness.js"></script> <script src="../../../resources/testharnessreport.js"></script> -<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> -<script src="file:///gen/third_party/blink/public/mojom/mediasession/media_session.mojom.js"></script> -<script src="resources/mediasessionservice-mock.js"></script> -<script src="resources/utils.js"></script> -<script> +<script type="module"> +import {MediaSessionServiceMock} from './resources/mediasessionservice-mock.js'; +import {assert_metadata_equals} from './resources/utils.js'; async_test(t => { // The following are expected results. @@ -24,7 +22,7 @@ ]; var resultId = 0; - let m = mediaSessionServiceMock; + const m = new MediaSessionServiceMock(); m.setMetadataCallback(t.step_func(receivedMetadata => { assert_metadata_equals(receivedMetadata, results[resultId]); ++resultId;
diff --git a/third_party/blink/web_tests/media/mediasession/mojo/playback-state-propagated.html b/third_party/blink/web_tests/http/tests/mediasession/playback-state-propagated.html similarity index 75% rename from third_party/blink/web_tests/media/mediasession/mojo/playback-state-propagated.html rename to third_party/blink/web_tests/http/tests/mediasession/playback-state-propagated.html index 918aa46..2e97ca0 100644 --- a/third_party/blink/web_tests/media/mediasession/mojo/playback-state-propagated.html +++ b/third_party/blink/web_tests/http/tests/mediasession/playback-state-propagated.html
@@ -2,11 +2,10 @@ <title>MediaSession Mojo Test</title> <script src="../../../resources/testharness.js"></script> <script src="../../../resources/testharnessreport.js"></script> -<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> -<script src="file:///gen/third_party/blink/public/mojom/mediasession/media_session.mojom.js"></script> -<script src="resources/mediasessionservice-mock.js"></script> -<script src="resources/utils.js"></script> -<script> +<script type="module"> +import {MediaSessionServiceMock} from './resources/mediasessionservice-mock.js'; + +import {MediaSessionPlaybackState} from '/gen/third_party/blink/public/mojom/mediasession/media_session.mojom.m.js'; var inputStates = ["none", "paused", "playing", "invalid", "none"]; var expectations; @@ -26,7 +25,7 @@ } async_test(function(t) { - let m = mediaSessionServiceMock; + const m = new MediaSessionServiceMock(); m.setPlaybackStateCallback(t.step_func(function(state) { assert_equals(state, getExpectations()[nextExpectation++]); if (nextExpectation == getExpectations().length)
diff --git a/third_party/blink/web_tests/media/mediasession/mojo/position-state-propagated.html b/third_party/blink/web_tests/http/tests/mediasession/position-state-propagated.html similarity index 70% rename from third_party/blink/web_tests/media/mediasession/mojo/position-state-propagated.html rename to third_party/blink/web_tests/http/tests/mediasession/position-state-propagated.html index 6573d6b..572d820 100644 --- a/third_party/blink/web_tests/media/mediasession/mojo/position-state-propagated.html +++ b/third_party/blink/web_tests/http/tests/mediasession/position-state-propagated.html
@@ -2,11 +2,9 @@ <title>MediaSession Mojo Test</title> <script src="../../../resources/testharness.js"></script> <script src="../../../resources/testharnessreport.js"></script> -<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> -<script src="file:///gen/third_party/blink/public/mojom/mediasession/media_session.mojom.js"></script> -<script src="resources/mediasessionservice-mock.js"></script> -<script src="resources/utils.js"></script> -<script> +<script type="module"> +import {MediaSessionServiceMock} from './resources/mediasessionservice-mock.js'; + const inputPositions = [ { duration: 10 }, { duration: 10, playbackRate: 2.0, position: 5 }, @@ -20,14 +18,14 @@ ]; function toSecs(timeDelta) { - return timeDelta.microseconds / 1000000; + return Number(timeDelta.microseconds / 1000000n); } async_test((t) => { - let m = mediaSessionServiceMock; + const m = new MediaSessionServiceMock(); let nextExpectation = 0; - mediaSessionServiceMock.setPositionStateCallback(t.step_func((position) => { + m.setPositionStateCallback(t.step_func((position) => { const expectation = expectations[nextExpectation++]; if (expectation === null) {
diff --git a/third_party/blink/web_tests/media/mediasession/mojo/resources/mediasessionservice-mock.js b/third_party/blink/web_tests/http/tests/mediasession/resources/mediasessionservice-mock.js similarity index 71% rename from third_party/blink/web_tests/media/mediasession/mojo/resources/mediasessionservice-mock.js rename to third_party/blink/web_tests/http/tests/mediasession/resources/mediasessionservice-mock.js index 5220d05a..d4aed5c 100644 --- a/third_party/blink/web_tests/media/mediasession/mojo/resources/mediasessionservice-mock.js +++ b/third_party/blink/web_tests/http/tests/mediasession/resources/mediasessionservice-mock.js
@@ -1,8 +1,9 @@ /* - * mediasessionservice-mock contains a mock implementation of MediaSessionService. + * mediasessionservice-mock contains a mock implementation of + * MediaSessionService. */ -"use strict"; +import {MediaSessionService, MediaSessionServiceReceiver} from '/gen/third_party/blink/public/mojom/mediasession/media_session.mojom.m.js'; function mojoString16ToJS(mojoString16) { return String.fromCharCode.apply(null, mojoString16.data); @@ -11,15 +12,15 @@ function mojoImageToJS(mojoImage) { var src = mojoImage.src.url; var type = mojoString16ToJS(mojoImage.type); - var sizes = ""; + var sizes = ''; for (var i = 0; i < mojoImage.sizes.length; i++) { if (i > 0) - sizes += " "; + sizes += ' '; var mojoSize = mojoImage.sizes[i]; - sizes += mojoSize.width.toString() + "x" + mojoSize.height.toString(); + sizes += mojoSize.width.toString() + 'x' + mojoSize.height.toString(); } - return { src: src, type: type, sizes: sizes }; + return {src, type, sizes}; } function mojoMetadataToJS(mojoMetadata) { @@ -33,22 +34,18 @@ for (var i = 0; i < mojoMetadata.artwork.length; i++) artwork.push(mojoImageToJS(mojoMetadata.artwork[i])); - return new MediaMetadata({title: title, artist: artist, album: album, artwork: artwork}); + return new MediaMetadata({title, artist, album, artwork}); } -var MediaSessionAction = blink.mojom.MediaSessionAction; -var MediaSessionPlaybackState = blink.mojom.MediaSessionPlaybackState; - -class MediaSessionServiceMock { +export class MediaSessionServiceMock { constructor() { this.pendingResponse_ = null; - this.bindingSet_ = new mojo.BindingSet( - blink.mojom.MediaSessionService); + this.receiver_ = new MediaSessionServiceReceiver(this); this.interceptor_ = - new MojoInterfaceInterceptor(blink.mojom.MediaSessionService.name); - this.interceptor_.oninterfacerequest = - e => this.bindingSet_.addBinding(this, e.handle); + new MojoInterfaceInterceptor(MediaSessionService.$interfaceName); + this.interceptor_.oninterfacerequest = e => + this.receiver_.$.bindHandle(e.handle); this.interceptor_.start(); } @@ -107,5 +104,3 @@ return this.client_; } } - -let mediaSessionServiceMock = new MediaSessionServiceMock();
diff --git a/third_party/blink/web_tests/media/mediasession/mojo/resources/utils.js b/third_party/blink/web_tests/http/tests/mediasession/resources/utils.js similarity index 75% rename from third_party/blink/web_tests/media/mediasession/mojo/resources/utils.js rename to third_party/blink/web_tests/http/tests/mediasession/resources/utils.js index f8947a60..db7f5493 100644 --- a/third_party/blink/web_tests/media/mediasession/mojo/resources/utils.js +++ b/third_party/blink/web_tests/http/tests/mediasession/resources/utils.js
@@ -4,12 +4,13 @@ assert_equals(expected.sizes, observed.sizes); } -function assert_metadata_equals(expected, observed) { +export function assert_metadata_equals(expected, observed) { assert_equals(expected.title, observed.title, 'metadata.title'); assert_equals(expected.artist, observed.artist, 'metadata.artist'); assert_equals(expected.album, observed.album, 'metadata.album'); - assert_equals(expected.artwork.length, observed.artwork.length, - 'metadata.artwork.length'); + assert_equals( + expected.artwork.length, observed.artwork.length, + 'metadata.artwork.length'); for (var i = 0; i < expected.artwork.length; i++) assert_image_equals(expected.artwork[i], observed.artwork[i]); }
diff --git a/third_party/blink/web_tests/http/tests/mediasession/set-null-metadata.html b/third_party/blink/web_tests/http/tests/mediasession/set-null-metadata.html new file mode 100644 index 0000000..28620e50 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/mediasession/set-null-metadata.html
@@ -0,0 +1,17 @@ +<!DOCTYPE html> +<title>MediaSession Mojo Test</title> +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> +<script type="module"> +import {MediaSessionServiceMock} from './resources/mediasessionservice-mock.js'; + +async_test(function(t) { + const m = new MediaSessionServiceMock(); + m.setMetadataCallback(t.step_func(function(receivedMetadata) { + assert_equals(receivedMetadata, null); + t.done(); + })); + window.navigator.mediaSession.metadata = null; +}, "test that null MediaMetadata is correctly propagated"); + +</script>
diff --git a/third_party/blink/web_tests/media/mediasession/mojo/callback-alive-after-gc.html b/third_party/blink/web_tests/media/mediasession/mojo/callback-alive-after-gc.html deleted file mode 100644 index fa105d5c..0000000 --- a/third_party/blink/web_tests/media/mediasession/mojo/callback-alive-after-gc.html +++ /dev/null
@@ -1,25 +0,0 @@ -<!DOCTYPE html> -<title>Test that setting MediaSession callbacks are alive after garbage-collection</title> -<script src="../../../resources/testharness.js"></script> -<script src="../../../resources/testharnessreport.js"></script> -<script src="../../../resources/gc.js"></script> -<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> -<script src="file:///gen/services/media_session/public/mojom/media_session.mojom.js"></script> -<script src="file:///gen/third_party/blink/public/mojom/mediasession/media_session.mojom.js"></script> -<script src="resources/mediasessionservice-mock.js"></script> -<script src="resources/utils.js"></script> -<script> - -var mock; - -async_test(function(t) { - let mock = mediaSessionServiceMock; - mock.setClientCallback(_ => { - gc(); - setTimeout(_ => { - mock.getClient().didReceiveAction(mediaSession.mojom.MediaSessionAction.kPlay); - }); - }); - window.navigator.mediaSession.setActionHandler("play", _ => { t.done(); }); -}); -</script>
diff --git a/third_party/blink/web_tests/media/mediasession/mojo/media-control-seek-to-action-reaches-client.html b/third_party/blink/web_tests/media/mediasession/mojo/media-control-seek-to-action-reaches-client.html deleted file mode 100644 index f9a27f8..0000000 --- a/third_party/blink/web_tests/media/mediasession/mojo/media-control-seek-to-action-reaches-client.html +++ /dev/null
@@ -1,30 +0,0 @@ -<!DOCTYPE html> -<title>MediaSession Mojo Test</title> -<script src="../../../resources/testharness.js"></script> -<script src="../../../resources/testharnessreport.js"></script> -<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> -<script src="file:///gen/gen/mojo/public/mojom/base/time.mojom.js"></script> -<script src="file:///gen/services/media_session/public/mojom/media_session.mojom.js"></script> -<script src="file:///gen/third_party/blink/public/mojom/mediasession/media_session.mojom.js"></script> -<script src="resources/mediasessionservice-mock.js"></script> -<script src="resources/utils.js"></script> -<script> -async_test((t) => { - mediaSessionServiceMock.setClientCallback(t.step_func(() => { - mediaSessionServiceMock.getClient().didReceiveAction( - mediaSession.mojom.MediaSessionAction.kSeekTo, - new blink.mojom.MediaSessionActionDetails({ - seekTo: new blink.mojom.MediaSessionSeekToDetails({ - seekTime: new mojoBase.mojom.TimeDelta({microseconds: 10000000}), - fastSeek: true - }) - })); - })); - - window.navigator.mediaSession.setActionHandler("seekto", t.step_func_done((e) => { - assert_equals(e.action, "seekto"); - assert_equals(e.seekTime, 10); - assert_true(e.fastSeek); - })); -}, "test that the seek to action reaches client"); -</script>
diff --git a/third_party/blink/web_tests/media/mediasession/mojo/set-null-metadata.html b/third_party/blink/web_tests/media/mediasession/mojo/set-null-metadata.html deleted file mode 100644 index db3479a..0000000 --- a/third_party/blink/web_tests/media/mediasession/mojo/set-null-metadata.html +++ /dev/null
@@ -1,20 +0,0 @@ -<!DOCTYPE html> -<title>MediaSession Mojo Test</title> -<script src="../../../resources/testharness.js"></script> -<script src="../../../resources/testharnessreport.js"></script> -<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> -<script src="file:///gen/third_party/blink/public/mojom/mediasession/media_session.mojom.js"></script> -<script src="resources/mediasessionservice-mock.js"></script> -<script src="resources/utils.js"></script> -<script> - -async_test(function(t) { - let m = mediaSessionServiceMock; - m.setMetadataCallback(t.step_func(function(receivedMetadata) { - assert_equals(receivedMetadata, null); - t.done(); - })); - window.navigator.mediaSession.metadata = null; -}, "test that null MediaMetadata is correctly propagated"); - -</script>
diff --git a/third_party/blink/web_tests/paint/invalidation/scroll/fixed-scroll-viewport-scroll-hidden-expected.txt b/third_party/blink/web_tests/paint/invalidation/scroll/fixed-scroll-viewport-scroll-hidden-expected.txt index 2b89c39a..9b2c380 100644 --- a/third_party/blink/web_tests/paint/invalidation/scroll/fixed-scroll-viewport-scroll-hidden-expected.txt +++ b/third_party/blink/web_tests/paint/invalidation/scroll/fixed-scroll-viewport-scroll-hidden-expected.txt
@@ -5,11 +5,14 @@ "bounds": [800, 2016], "contentsOpaque": true, "backgroundColor": "#FFFFFF", - "invalidations": [ - [8, 200, 100, 100], - [8, 100, 100, 100] - ], "transform": 1 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed green'", + "bounds": [100, 100], + "contentsOpaque": true, + "backgroundColor": "#008000", + "transform": 2 } ], "transforms": [ @@ -21,6 +24,15 @@ [0, 0, 1, 0], [0, -100, 0, 1] ] + }, + { + "id": 2, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [8, 100, 0, 1] + ] } ] }
diff --git a/third_party/blink/web_tests/platform/linux/compositing/layer-creation/main-thread-scrolling-non-composited-fixed-overflow-hidden-expected.txt b/third_party/blink/web_tests/platform/linux/compositing/layer-creation/main-thread-scrolling-non-composited-fixed-overflow-hidden-expected.txt new file mode 100644 index 0000000..01f5301 --- /dev/null +++ b/third_party/blink/web_tests/platform/linux/compositing/layer-creation/main-thread-scrolling-non-composited-fixed-overflow-hidden-expected.txt
@@ -0,0 +1,28 @@ +TEST +{ + "layers": [ + { + "name": "Scrolling Contents Layer", + "bounds": [800, 5021], + "contentsOpaque": true, + "backgroundColor": "#FFFFFF" + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed'", + "bounds": [39, 20], + "transform": 1 + } + ], + "transforms": [ + { + "id": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [10, 10, 0, 1] + ] + } + ] +} +
diff --git a/third_party/blink/web_tests/platform/linux/html/details_summary/details-position-expected.png b/third_party/blink/web_tests/platform/linux/html/details_summary/details-position-expected.png index 9255b8f..480abbf 100644 --- a/third_party/blink/web_tests/platform/linux/html/details_summary/details-position-expected.png +++ b/third_party/blink/web_tests/platform/linux/html/details_summary/details-position-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/external/wpt/dom/events/scrolling/scrollend-event-for-user-scroll-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/external/wpt/dom/events/scrolling/scrollend-event-for-user-scroll-expected.txt deleted file mode 100644 index a9b7884..0000000 --- a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/external/wpt/dom/events/scrolling/scrollend-event-for-user-scroll-expected.txt +++ /dev/null
@@ -1,7 +0,0 @@ -This is a testharness.js-based test. -FAIL Tests that the target_div gets scrollend event when dragging scroll on target. promise_test: Unhandled rejection with value: "target_div did not receive scrollend event after dragging scroll on target." -FAIL Tests that the target_div gets scrollend event when click scrollbar on target. promise_test: Unhandled rejection with value: "target_div did not receive scrollend event after clicking scrollbar on target." -FAIL Tests that the target_div gets scrollend event when drag the thumb of target. promise_test: Unhandled rejection with value: "target_div did not receive scrollend event after dragging the thumb of target." -PASS Tests that the target_div gets scrollend event when send DOWN key to target. -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/fast/dom/52776-expected.png b/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/fast/dom/52776-expected.png deleted file mode 100644 index 8ada27b..0000000 --- a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/fast/dom/52776-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/fast/dom/HTMLMeterElement/meter-boundary-values-expected.png b/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/fast/dom/HTMLMeterElement/meter-boundary-values-expected.png deleted file mode 100644 index 88c11f3..0000000 --- a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/fast/dom/HTMLMeterElement/meter-boundary-values-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/fast/dom/HTMLMeterElement/meter-clone-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/fast/dom/HTMLMeterElement/meter-clone-expected.txt deleted file mode 100644 index f840958..0000000 --- a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/fast/dom/HTMLMeterElement/meter-clone-expected.txt +++ /dev/null
@@ -1,10 +0,0 @@ -PASS cloned.value is target.value -PASS internals.shadowPseudoId(clonedShadowRoot.firstChild) is internals.shadowPseudoId(targetShadowRoot.firstChild) -PASS internals.shadowPseudoId(clonedShadowRoot.firstChild.firstChild) is internals.shadowPseudoId(targetShadowRoot.firstChild.firstChild) -PASS internals.shadowPseudoId(clonedShadowRoot.firstChild.firstChild.firstChild) is internals.shadowPseudoId(targetShadowRoot.firstChild.firstChild.firstChild) -PASS clonedShadowRoot.firstChild.firstChild.firstChild.style.width is "70%" -PASS targetShadowRoot.firstChild.firstChild.firstChild.style.width is "50%" -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/fast/dom/HTMLMeterElement/meter-element-markup-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/fast/dom/HTMLMeterElement/meter-element-markup-expected.txt deleted file mode 100644 index a39a6a3..0000000 --- a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/fast/dom/HTMLMeterElement/meter-element-markup-expected.txt +++ /dev/null
@@ -1,75 +0,0 @@ - -Both meter elements should have a nested shadow box with a width specified: -| " - " -| <meter> -| max="100" -| value="70" -| <shadow:root> -| <div> -| pseudo="-webkit-meter-inner-element" -| shadow:pseudoId="-webkit-meter-inner-element" -| <div> -| pseudo="-webkit-meter-bar" -| shadow:pseudoId="-webkit-meter-bar" -| <div> -| pseudo="-webkit-meter-optimum-value" -| style="width: 70%;" -| shadow:pseudoId="-webkit-meter-optimum-value" -| <div> -| pseudo="-internal-fallback" -| shadow:pseudoId="-internal-fallback" -| <slot> -| name="user-agent-default-slot" -| " - " -| <meter> -| high="6" -| low="3" -| max="10" -| min="0" -| optimum="5" -| value="10" -| <shadow:root> -| <div> -| pseudo="-webkit-meter-inner-element" -| shadow:pseudoId="-webkit-meter-inner-element" -| <div> -| pseudo="-webkit-meter-bar" -| shadow:pseudoId="-webkit-meter-bar" -| <div> -| pseudo="-webkit-meter-suboptimum-value" -| style="width: 100%;" -| shadow:pseudoId="-webkit-meter-suboptimum-value" -| <div> -| pseudo="-internal-fallback" -| shadow:pseudoId="-internal-fallback" -| <slot> -| name="user-agent-default-slot" -| " - " -| <meter> -| high="6" -| low="3" -| max="10" -| min="0" -| optimum="0" -| value="10" -| <shadow:root> -| <div> -| pseudo="-webkit-meter-inner-element" -| shadow:pseudoId="-webkit-meter-inner-element" -| <div> -| pseudo="-webkit-meter-bar" -| shadow:pseudoId="-webkit-meter-bar" -| <div> -| pseudo="-webkit-meter-even-less-good-value" -| style="width: 100%;" -| shadow:pseudoId="-webkit-meter-even-less-good-value" -| <div> -| pseudo="-internal-fallback" -| shadow:pseudoId="-internal-fallback" -| <slot> -| name="user-agent-default-slot" -| " - "
diff --git a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/fast/dom/HTMLMeterElement/meter-optimums-expected.png b/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/fast/dom/HTMLMeterElement/meter-optimums-expected.png deleted file mode 100644 index 8c9f4b6a..0000000 --- a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/fast/dom/HTMLMeterElement/meter-optimums-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/fast/dom/HTMLMeterElement/meter-styles-changing-pseudo-expected.png b/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/fast/dom/HTMLMeterElement/meter-styles-changing-pseudo-expected.png deleted file mode 100644 index 7d479d7..0000000 --- a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/fast/dom/HTMLMeterElement/meter-styles-changing-pseudo-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/fast/dom/HTMLMeterElement/meter-styles-expected.png b/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/fast/dom/HTMLMeterElement/meter-styles-expected.png deleted file mode 100644 index a7a9b52..0000000 --- a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/fast/dom/HTMLMeterElement/meter-styles-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/fast/dom/focus-contenteditable-expected.png b/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/fast/dom/focus-contenteditable-expected.png deleted file mode 100644 index 2300b2f..0000000 --- a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/fast/dom/focus-contenteditable-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/fast/parser/bad-xml-slash-expected.png b/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/fast/parser/bad-xml-slash-expected.png deleted file mode 100644 index 0e12fae0..0000000 --- a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/fast/parser/bad-xml-slash-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/fast/parser/entity-comment-in-textarea-expected.png b/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/fast/parser/entity-comment-in-textarea-expected.png deleted file mode 100644 index ddf3ae17..0000000 --- a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/fast/parser/entity-comment-in-textarea-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/fast/parser/open-comment-in-textarea-expected.png b/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/fast/parser/open-comment-in-textarea-expected.png deleted file mode 100644 index b342357..0000000 --- a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/fast/parser/open-comment-in-textarea-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-1-and-click-expected.png b/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-1-and-click-expected.png deleted file mode 100644 index f45d7fb..0000000 --- a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-1-and-click-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-10-and-click-expected.png b/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-10-and-click-expected.png deleted file mode 100644 index 35222a8..0000000 --- a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-10-and-click-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-2-and-click-expected.png b/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-2-and-click-expected.png deleted file mode 100644 index c15fc31..0000000 --- a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-2-and-click-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-3-and-click-expected.png b/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-3-and-click-expected.png deleted file mode 100644 index 77c04f9..0000000 --- a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-3-and-click-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-4-and-click-expected.png b/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-4-and-click-expected.png deleted file mode 100644 index 8353760a..0000000 --- a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-4-and-click-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-5-and-click-expected.png b/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-5-and-click-expected.png deleted file mode 100644 index f3699d6..0000000 --- a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-5-and-click-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-6-and-click-expected.png b/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-6-and-click-expected.png deleted file mode 100644 index 35222a8..0000000 --- a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-6-and-click-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-7-and-click-expected.png b/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-7-and-click-expected.png deleted file mode 100644 index 35222a8..0000000 --- a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-7-and-click-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-8-and-click-expected.png b/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-8-and-click-expected.png deleted file mode 100644 index 9e084c7..0000000 --- a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-8-and-click-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-9-and-click-expected.png b/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-9-and-click-expected.png deleted file mode 100644 index 7d65c180..0000000 --- a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-9-and-click-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-no-summary4-expected.png b/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-no-summary4-expected.png deleted file mode 100644 index a6e52ea8..0000000 --- a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-no-summary4-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-open-javascript-expected.png b/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-open-javascript-expected.png deleted file mode 100644 index e9b8fe2..0000000 --- a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-open-javascript-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-open2-expected.png b/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-open2-expected.png deleted file mode 100644 index 6ec7c82..0000000 --- a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-open2-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-open4-expected.png b/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-open4-expected.png deleted file mode 100644 index 6ec7c82..0000000 --- a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-open4-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-remove-summary-1-and-click-expected.png b/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-remove-summary-1-and-click-expected.png deleted file mode 100644 index 358d84c..0000000 --- a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-remove-summary-1-and-click-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-remove-summary-2-and-click-expected.png b/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-remove-summary-2-and-click-expected.png deleted file mode 100644 index 88fb71b..0000000 --- a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-remove-summary-2-and-click-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-remove-summary-3-and-click-expected.png b/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-remove-summary-3-and-click-expected.png deleted file mode 100644 index b30847f..0000000 --- a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-remove-summary-3-and-click-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-remove-summary-4-and-click-expected.png b/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-remove-summary-4-and-click-expected.png deleted file mode 100644 index 2a25f58..0000000 --- a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-remove-summary-4-and-click-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-remove-summary-5-and-click-expected.png b/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-remove-summary-5-and-click-expected.png deleted file mode 100644 index d3bdec4c..0000000 --- a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-remove-summary-5-and-click-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-remove-summary-6-and-click-expected.png b/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-remove-summary-6-and-click-expected.png deleted file mode 100644 index b79c81a..0000000 --- a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-remove-summary-6-and-click-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-replace-summary-child-expected.png b/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-replace-summary-child-expected.png deleted file mode 100644 index d235912b..0000000 --- a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-replace-summary-child-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-replace-text-expected.png b/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-replace-text-expected.png deleted file mode 100644 index 64203ed7..0000000 --- a/third_party/blink/web_tests/platform/linux/virtual/web-components-v0-disabled/html/details_summary/details-replace-text-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac-arm11.0/compositing/layer-creation/fixed-position-nonscrollable-body-expected.txt b/third_party/blink/web_tests/platform/mac-mac-arm11.0/compositing/layer-creation/fixed-position-nonscrollable-body-expected.txt new file mode 100644 index 0000000..8f94fa3b --- /dev/null +++ b/third_party/blink/web_tests/platform/mac-mac-arm11.0/compositing/layer-creation/fixed-position-nonscrollable-body-expected.txt
@@ -0,0 +1,11 @@ +{ + "layers": [ + { + "name": "Scrolling Contents Layer", + "bounds": [800, 4021], + "contentsOpaque": true, + "backgroundColor": "#FFFFFF" + } + ] +} +
diff --git a/third_party/blink/web_tests/platform/mac-mac-arm11.0/compositing/layer-creation/fixed-position-nonscrollable-body-overlap-expected.txt b/third_party/blink/web_tests/platform/mac-mac-arm11.0/compositing/layer-creation/fixed-position-nonscrollable-body-overlap-expected.txt new file mode 100644 index 0000000..00639270 --- /dev/null +++ b/third_party/blink/web_tests/platform/mac-mac-arm11.0/compositing/layer-creation/fixed-position-nonscrollable-body-overlap-expected.txt
@@ -0,0 +1,38 @@ +Even though we can opt-out of fixed-position compositing for unscrollable fixed-position containers, we still need to composite fixed-position layers that need compositing for other reasons such as overlap. + +{ + "layers": [ + { + "name": "Scrolling Contents Layer", + "bounds": [800, 4024], + "contentsOpaque": true, + "backgroundColor": "#FFFFFF" + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='absolute composited red box'", + "bounds": [100, 100], + "contentsOpaque": true, + "backgroundColor": "#FF0000", + "transform": 1 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed lime box'", + "position": [10, 100], + "bounds": [100, 100], + "contentsOpaque": true, + "backgroundColor": "#00FF00" + } + ], + "transforms": [ + { + "id": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [10, 100, 0, 1] + ] + } + ] +} +
diff --git a/third_party/blink/web_tests/platform/mac-mac-arm11.0/compositing/layer-creation/fixed-position-nonscrollable-iframes-in-scrollable-page-expected.txt b/third_party/blink/web_tests/platform/mac-mac-arm11.0/compositing/layer-creation/fixed-position-nonscrollable-iframes-in-scrollable-page-expected.txt new file mode 100644 index 0000000..21627b6 --- /dev/null +++ b/third_party/blink/web_tests/platform/mac-mac-arm11.0/compositing/layer-creation/fixed-position-nonscrollable-iframes-in-scrollable-page-expected.txt
@@ -0,0 +1,56 @@ +In all iframes, the green fixed-position element should not be composited. +{ + "layers": [ + { + "name": "Scrolling Contents Layer", + "bounds": [785, 4016], + "contentsOpaque": true, + "backgroundColor": "#FFFFFF" + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='composited box'", + "bounds": [300, 100], + "contentsOpaque": true, + "backgroundColor": "#00FFFF", + "transform": 1 + }, + { + "name": "LayoutIFrame (positioned) IFRAME id='iframe2' class='composited'", + "bounds": [154, 154], + "transform": 2 + }, + { + "name": "LayoutIFrame (positioned) IFRAME id='iframe3'", + "position": [10, 380], + "bounds": [154, 154] + }, + { + "name": "ContentsLayer for Vertical Scrollbar Layer", + "position": [785, 0], + "bounds": [15, 600], + "contentsOpaque": true + } + ], + "transforms": [ + { + "id": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [50, 360, 0, 1] + ] + }, + { + "id": 2, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [10, 200, 0, 1] + ] + } + ] +} + +Composited box underneath iframe.
diff --git a/third_party/blink/web_tests/compositing/layer-creation/main-thread-scrolling-non-composited-fixed-overflow-hidden-expected.txt b/third_party/blink/web_tests/platform/mac-mac-arm11.0/compositing/layer-creation/main-thread-scrolling-non-composited-fixed-overflow-hidden-expected.txt similarity index 100% rename from third_party/blink/web_tests/compositing/layer-creation/main-thread-scrolling-non-composited-fixed-overflow-hidden-expected.txt rename to third_party/blink/web_tests/platform/mac-mac-arm11.0/compositing/layer-creation/main-thread-scrolling-non-composited-fixed-overflow-hidden-expected.txt
diff --git a/third_party/blink/web_tests/platform/mac-mac-arm11.0/paint/invalidation/scroll/fixed-scroll-viewport-scroll-hidden-expected.txt b/third_party/blink/web_tests/platform/mac-mac-arm11.0/paint/invalidation/scroll/fixed-scroll-viewport-scroll-hidden-expected.txt new file mode 100644 index 0000000..2b89c39a --- /dev/null +++ b/third_party/blink/web_tests/platform/mac-mac-arm11.0/paint/invalidation/scroll/fixed-scroll-viewport-scroll-hidden-expected.txt
@@ -0,0 +1,27 @@ +{ + "layers": [ + { + "name": "Scrolling Contents Layer", + "bounds": [800, 2016], + "contentsOpaque": true, + "backgroundColor": "#FFFFFF", + "invalidations": [ + [8, 200, 100, 100], + [8, 100, 100, 100] + ], + "transform": 1 + } + ], + "transforms": [ + { + "id": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [0, -100, 0, 1] + ] + } + ] +} +
diff --git a/third_party/blink/web_tests/paint/invalidation/scroll/scrolled-iframe-scrollbar-change-expected.txt b/third_party/blink/web_tests/platform/mac-mac-arm11.0/paint/invalidation/scroll/scrolled-iframe-scrollbar-change-expected.txt similarity index 100% rename from third_party/blink/web_tests/paint/invalidation/scroll/scrolled-iframe-scrollbar-change-expected.txt rename to third_party/blink/web_tests/platform/mac-mac-arm11.0/paint/invalidation/scroll/scrolled-iframe-scrollbar-change-expected.txt
diff --git a/third_party/blink/web_tests/platform/mac-mac10.12/virtual/web-components-v0-disabled/external/wpt/dom/events/scrolling/scrollend-event-for-user-scroll-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.12/virtual/web-components-v0-disabled/external/wpt/dom/events/scrolling/scrollend-event-for-user-scroll-expected.txt deleted file mode 100644 index 9a27f97f..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.12/virtual/web-components-v0-disabled/external/wpt/dom/events/scrolling/scrollend-event-for-user-scroll-expected.txt +++ /dev/null
@@ -1,10 +0,0 @@ -Content-Type: text/plain -This is a testharness.js-based test. -FAIL Tests that the target_div gets scrollend event when dragging scroll on target. promise_test: Unhandled rejection with value: "target_div did not receive scrollend event after dragging scroll on target." -FAIL Tests that the target_div gets scrollend event when click scrollbar on target. promise_test: Unhandled rejection with value: "target_div did not receive scrollend event after clicking scrollbar on target." -FAIL Tests that the target_div gets scrollend event when drag the thumb of target. promise_test: Unhandled rejection with value: "target_div did not receive scrollend event after dragging the thumb of target." -FAIL Tests that the target_div gets scrollend event when send DOWN key to target. assert_true: expected true got false -Harness: the test ran to completion. - -#EOF -#EOF
diff --git a/third_party/blink/web_tests/platform/mac-mac10.12/virtual/web-components-v0-disabled/fast/dom/HTMLMeterElement/meter-optimums-expected.png b/third_party/blink/web_tests/platform/mac-mac10.12/virtual/web-components-v0-disabled/fast/dom/HTMLMeterElement/meter-optimums-expected.png deleted file mode 100644 index 0384a07..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.12/virtual/web-components-v0-disabled/fast/dom/HTMLMeterElement/meter-optimums-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.13/paint/invalidation/scroll/scrolled-iframe-scrollbar-change-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.13/paint/invalidation/scroll/scrolled-iframe-scrollbar-change-expected.txt new file mode 100644 index 0000000..ccc7ffc --- /dev/null +++ b/third_party/blink/web_tests/platform/mac-mac10.13/paint/invalidation/scroll/scrolled-iframe-scrollbar-change-expected.txt
@@ -0,0 +1,39 @@ +{ + "layers": [ + { + "name": "Scrolling Contents Layer", + "bounds": [804, 604], + "contentsOpaque": true, + "backgroundColor": "#FFFFFF", + "invalidations": [ + [10, 2, 769, 592], + [787, 2, 15, 600] + ] + }, + { + "name": "LayoutView #document", + "bounds": [800, 600], + "backgroundColor": "#FF0000", + "transform": 1 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV id='overlay'", + "bounds": [800, 600], + "contentsOpaque": true, + "backgroundColor": "#008000", + "transform": 1 + } + ], + "transforms": [ + { + "id": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [2, 2, 0, 1] + ] + } + ] +} +
diff --git a/third_party/blink/web_tests/platform/mac-mac10.13/virtual/web-components-v0-disabled/fast/dom/52776-expected.png b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/web-components-v0-disabled/fast/dom/52776-expected.png deleted file mode 100644 index b9fc423..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.13/virtual/web-components-v0-disabled/fast/dom/52776-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.13/virtual/web-components-v0-disabled/fast/dom/title-text-property-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/web-components-v0-disabled/fast/dom/title-text-property-expected.txt deleted file mode 100644 index 0a1ece0..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.13/virtual/web-components-v0-disabled/fast/dom/title-text-property-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -TITLE CHANGED: 'This is the new title' -Original title is: 'Original Title' -Setting new title to: 'This is the new title' -New title is: 'This is the new title'
diff --git a/third_party/blink/web_tests/platform/mac-mac10.13/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-3-and-click-expected.png b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-3-and-click-expected.png deleted file mode 100644 index dedfc7dc..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.13/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-3-and-click-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/compositing/layer-creation/main-thread-scrolling-non-composited-fixed-overflow-hidden-expected.txt b/third_party/blink/web_tests/platform/mac/compositing/layer-creation/main-thread-scrolling-non-composited-fixed-overflow-hidden-expected.txt new file mode 100644 index 0000000..763b4de --- /dev/null +++ b/third_party/blink/web_tests/platform/mac/compositing/layer-creation/main-thread-scrolling-non-composited-fixed-overflow-hidden-expected.txt
@@ -0,0 +1,28 @@ +TEST +{ + "layers": [ + { + "name": "Scrolling Contents Layer", + "bounds": [800, 5021], + "contentsOpaque": true, + "backgroundColor": "#FFFFFF" + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed'", + "bounds": [38, 18], + "transform": 1 + } + ], + "transforms": [ + { + "id": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [10, 10, 0, 1] + ] + } + ] +} +
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/html/semantics/forms/the-input-element/selection-pointer-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/html/semantics/forms/the-input-element/selection-pointer-expected.txt deleted file mode 100644 index cd5b61f6..0000000 --- a/third_party/blink/web_tests/platform/mac/external/wpt/html/semantics/forms/the-input-element/selection-pointer-expected.txt +++ /dev/null
@@ -1,27 +0,0 @@ -Content-Type: text/plain -This is a testharness.js-based test. -PASS Selecting texts across <input type=button> should not cancel selection -PASS Selecting texts across <input type=checkbox> should not cancel selection -PASS Selecting texts across <input type=color> should not cancel selection -PASS Selecting texts across <input type=date> should not cancel selection -PASS Selecting texts across <input type=datetime-local> should not cancel selection -PASS Selecting texts across <input type=email> should not cancel selection -PASS Selecting texts across <input type=file> should not cancel selection -FAIL Selecting texts across <input type=image> should not cancel selection promise_test: Unhandled rejection with value: object "Error: element click intercepted error" -PASS Selecting texts across <input type=month> should not cancel selection -PASS Selecting texts across <input type=number> should not cancel selection -PASS Selecting texts across <input type=password> should not cancel selection -PASS Selecting texts across <input type=radio> should not cancel selection -PASS Selecting texts across <input type=range> should not cancel selection -PASS Selecting texts across <input type=reset> should not cancel selection -PASS Selecting texts across <input type=search> should not cancel selection -PASS Selecting texts across <input type=submit> should not cancel selection -PASS Selecting texts across <input type=tel> should not cancel selection -PASS Selecting texts across <input type=text> should not cancel selection -PASS Selecting texts across <input type=time> should not cancel selection -PASS Selecting texts across <input type=url> should not cancel selection -PASS Selecting texts across <input type=week> should not cancel selection -Harness: the test ran to completion. - -#EOF -#EOF
diff --git a/third_party/blink/web_tests/platform/mac/paint/invalidation/scroll/scrolled-iframe-scrollbar-change-expected.txt b/third_party/blink/web_tests/platform/mac/paint/invalidation/scroll/scrolled-iframe-scrollbar-change-expected.txt new file mode 100644 index 0000000..4023ca0 --- /dev/null +++ b/third_party/blink/web_tests/platform/mac/paint/invalidation/scroll/scrolled-iframe-scrollbar-change-expected.txt
@@ -0,0 +1,35 @@ +{ + "layers": [ + { + "name": "Scrolling Contents Layer", + "bounds": [804, 604], + "contentsOpaque": true, + "backgroundColor": "#FFFFFF" + }, + { + "name": "LayoutView #document", + "bounds": [800, 600], + "backgroundColor": "#FF0000", + "transform": 1 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV id='overlay'", + "bounds": [800, 600], + "contentsOpaque": true, + "backgroundColor": "#008000", + "transform": 1 + } + ], + "transforms": [ + { + "id": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [2, 2, 0, 1] + ] + } + ] +} +
diff --git a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/fast/dom/34176-expected.png b/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/fast/dom/34176-expected.png deleted file mode 100644 index 20b3422..0000000 --- a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/fast/dom/34176-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/fast/dom/52776-expected.png b/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/fast/dom/52776-expected.png deleted file mode 100644 index 70be8ec..0000000 --- a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/fast/dom/52776-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/fast/dom/HTMLMeterElement/meter-boundary-values-expected.png b/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/fast/dom/HTMLMeterElement/meter-boundary-values-expected.png deleted file mode 100644 index fe9477b..0000000 --- a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/fast/dom/HTMLMeterElement/meter-boundary-values-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/fast/dom/HTMLMeterElement/meter-optimums-expected.png b/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/fast/dom/HTMLMeterElement/meter-optimums-expected.png deleted file mode 100644 index 14f92fd1..0000000 --- a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/fast/dom/HTMLMeterElement/meter-optimums-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/fast/dom/HTMLMeterElement/meter-styles-changing-pseudo-expected.png b/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/fast/dom/HTMLMeterElement/meter-styles-changing-pseudo-expected.png deleted file mode 100644 index 6dd9d55..0000000 --- a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/fast/dom/HTMLMeterElement/meter-styles-changing-pseudo-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/fast/dom/HTMLMeterElement/meter-styles-expected.png b/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/fast/dom/HTMLMeterElement/meter-styles-expected.png deleted file mode 100644 index 49be4ce6..0000000 --- a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/fast/dom/HTMLMeterElement/meter-styles-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/fast/dom/focus-contenteditable-expected.png b/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/fast/dom/focus-contenteditable-expected.png deleted file mode 100644 index 3e25dad..0000000 --- a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/fast/dom/focus-contenteditable-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/fast/dom/title-text-property-expected.txt b/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/fast/dom/title-text-property-expected.txt deleted file mode 100644 index 9add247..0000000 --- a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/fast/dom/title-text-property-expected.txt +++ /dev/null
@@ -1,3 +0,0 @@ -Original title is: 'Original Title' -Setting new title to: 'This is the new title' -New title is: 'This is the new title'
diff --git a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/fast/parser/bad-xml-slash-expected.png b/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/fast/parser/bad-xml-slash-expected.png deleted file mode 100644 index d7fb6c4..0000000 --- a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/fast/parser/bad-xml-slash-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/fast/parser/entity-comment-in-textarea-expected.png b/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/fast/parser/entity-comment-in-textarea-expected.png deleted file mode 100644 index 330ea6b..0000000 --- a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/fast/parser/entity-comment-in-textarea-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/fast/parser/open-comment-in-textarea-expected.png b/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/fast/parser/open-comment-in-textarea-expected.png deleted file mode 100644 index b0c2aba..0000000 --- a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/fast/parser/open-comment-in-textarea-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-1-and-click-expected.png b/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-1-and-click-expected.png deleted file mode 100644 index 6f5b21ef..0000000 --- a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-1-and-click-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-10-and-click-expected.png b/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-10-and-click-expected.png deleted file mode 100644 index 632a04b6..0000000 --- a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-10-and-click-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-2-and-click-expected.png b/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-2-and-click-expected.png deleted file mode 100644 index 7fb98033..0000000 --- a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-2-and-click-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-3-and-click-expected.png b/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-3-and-click-expected.png deleted file mode 100644 index 41bfc61..0000000 --- a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-3-and-click-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-4-and-click-expected.png b/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-4-and-click-expected.png deleted file mode 100644 index 73766a5..0000000 --- a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-4-and-click-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-5-and-click-expected.png b/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-5-and-click-expected.png deleted file mode 100644 index 12f40610..0000000 --- a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-5-and-click-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-6-and-click-expected.png b/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-6-and-click-expected.png deleted file mode 100644 index 632a04b6..0000000 --- a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-6-and-click-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-7-and-click-expected.png b/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-7-and-click-expected.png deleted file mode 100644 index 632a04b6..0000000 --- a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-7-and-click-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-8-and-click-expected.png b/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-8-and-click-expected.png deleted file mode 100644 index 80cc312c..0000000 --- a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-8-and-click-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-9-and-click-expected.png b/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-9-and-click-expected.png deleted file mode 100644 index 435885f..0000000 --- a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-add-summary-9-and-click-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-no-summary4-expected.png b/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-no-summary4-expected.png deleted file mode 100644 index 392e562..0000000 --- a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-no-summary4-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-open-javascript-expected.png b/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-open-javascript-expected.png deleted file mode 100644 index f4f31f0..0000000 --- a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-open-javascript-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-open2-expected.png b/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-open2-expected.png deleted file mode 100644 index 3adf8e66..0000000 --- a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-open2-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-open4-expected.png b/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-open4-expected.png deleted file mode 100644 index 3adf8e66..0000000 --- a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-open4-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-remove-summary-1-and-click-expected.png b/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-remove-summary-1-and-click-expected.png deleted file mode 100644 index e64c030..0000000 --- a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-remove-summary-1-and-click-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-remove-summary-2-and-click-expected.png b/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-remove-summary-2-and-click-expected.png deleted file mode 100644 index f6139448..0000000 --- a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-remove-summary-2-and-click-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-remove-summary-3-and-click-expected.png b/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-remove-summary-3-and-click-expected.png deleted file mode 100644 index 7c2db47..0000000 --- a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-remove-summary-3-and-click-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-remove-summary-4-and-click-expected.png b/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-remove-summary-4-and-click-expected.png deleted file mode 100644 index 4a74fdf..0000000 --- a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-remove-summary-4-and-click-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-remove-summary-5-and-click-expected.png b/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-remove-summary-5-and-click-expected.png deleted file mode 100644 index cb1ccd7..0000000 --- a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-remove-summary-5-and-click-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-remove-summary-6-and-click-expected.png b/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-remove-summary-6-and-click-expected.png deleted file mode 100644 index 7d1c03c..0000000 --- a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-remove-summary-6-and-click-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-replace-summary-child-expected.png b/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-replace-summary-child-expected.png deleted file mode 100644 index 27be22e..0000000 --- a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-replace-summary-child-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-replace-text-expected.png b/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-replace-text-expected.png deleted file mode 100644 index da1dc78..0000000 --- a/third_party/blink/web_tests/platform/mac/virtual/web-components-v0-disabled/html/details_summary/details-replace-text-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/compositing/layer-creation/main-thread-scrolling-non-composited-fixed-overflow-hidden-expected.txt b/third_party/blink/web_tests/platform/win/compositing/layer-creation/main-thread-scrolling-non-composited-fixed-overflow-hidden-expected.txt new file mode 100644 index 0000000..a7f17797a --- /dev/null +++ b/third_party/blink/web_tests/platform/win/compositing/layer-creation/main-thread-scrolling-non-composited-fixed-overflow-hidden-expected.txt
@@ -0,0 +1,28 @@ +TEST +{ + "layers": [ + { + "name": "Scrolling Contents Layer", + "bounds": [800, 5021], + "contentsOpaque": true, + "backgroundColor": "#FFFFFF" + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed'", + "bounds": [36, 20], + "transform": 1 + } + ], + "transforms": [ + { + "id": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [10, 10, 0, 1] + ] + } + ] +} +
diff --git a/third_party/blink/web_tests/platform/win/paint/invalidation/scroll/scrolled-iframe-scrollbar-change-expected.txt b/third_party/blink/web_tests/platform/win/paint/invalidation/scroll/scrolled-iframe-scrollbar-change-expected.txt new file mode 100644 index 0000000..ccc7ffc --- /dev/null +++ b/third_party/blink/web_tests/platform/win/paint/invalidation/scroll/scrolled-iframe-scrollbar-change-expected.txt
@@ -0,0 +1,39 @@ +{ + "layers": [ + { + "name": "Scrolling Contents Layer", + "bounds": [804, 604], + "contentsOpaque": true, + "backgroundColor": "#FFFFFF", + "invalidations": [ + [10, 2, 769, 592], + [787, 2, 15, 600] + ] + }, + { + "name": "LayoutView #document", + "bounds": [800, 600], + "backgroundColor": "#FF0000", + "transform": 1 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV id='overlay'", + "bounds": [800, 600], + "contentsOpaque": true, + "backgroundColor": "#008000", + "transform": 1 + } + ], + "transforms": [ + { + "id": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [2, 2, 0, 1] + ] + } + ] +} +
diff --git a/third_party/blink/web_tests/platform/win/virtual/web-components-v0-disabled/fast/dom/HTMLMeterElement/meter-clone-expected.txt b/third_party/blink/web_tests/platform/win/virtual/web-components-v0-disabled/fast/dom/HTMLMeterElement/meter-clone-expected.txt deleted file mode 100644 index f840958..0000000 --- a/third_party/blink/web_tests/platform/win/virtual/web-components-v0-disabled/fast/dom/HTMLMeterElement/meter-clone-expected.txt +++ /dev/null
@@ -1,10 +0,0 @@ -PASS cloned.value is target.value -PASS internals.shadowPseudoId(clonedShadowRoot.firstChild) is internals.shadowPseudoId(targetShadowRoot.firstChild) -PASS internals.shadowPseudoId(clonedShadowRoot.firstChild.firstChild) is internals.shadowPseudoId(targetShadowRoot.firstChild.firstChild) -PASS internals.shadowPseudoId(clonedShadowRoot.firstChild.firstChild.firstChild) is internals.shadowPseudoId(targetShadowRoot.firstChild.firstChild.firstChild) -PASS clonedShadowRoot.firstChild.firstChild.firstChild.style.width is "70%" -PASS targetShadowRoot.firstChild.firstChild.firstChild.style.width is "50%" -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/blink/web_tests/platform/win/virtual/web-components-v0-disabled/fast/dom/HTMLMeterElement/meter-element-markup-expected.txt b/third_party/blink/web_tests/platform/win/virtual/web-components-v0-disabled/fast/dom/HTMLMeterElement/meter-element-markup-expected.txt deleted file mode 100644 index a39a6a3..0000000 --- a/third_party/blink/web_tests/platform/win/virtual/web-components-v0-disabled/fast/dom/HTMLMeterElement/meter-element-markup-expected.txt +++ /dev/null
@@ -1,75 +0,0 @@ - -Both meter elements should have a nested shadow box with a width specified: -| " - " -| <meter> -| max="100" -| value="70" -| <shadow:root> -| <div> -| pseudo="-webkit-meter-inner-element" -| shadow:pseudoId="-webkit-meter-inner-element" -| <div> -| pseudo="-webkit-meter-bar" -| shadow:pseudoId="-webkit-meter-bar" -| <div> -| pseudo="-webkit-meter-optimum-value" -| style="width: 70%;" -| shadow:pseudoId="-webkit-meter-optimum-value" -| <div> -| pseudo="-internal-fallback" -| shadow:pseudoId="-internal-fallback" -| <slot> -| name="user-agent-default-slot" -| " - " -| <meter> -| high="6" -| low="3" -| max="10" -| min="0" -| optimum="5" -| value="10" -| <shadow:root> -| <div> -| pseudo="-webkit-meter-inner-element" -| shadow:pseudoId="-webkit-meter-inner-element" -| <div> -| pseudo="-webkit-meter-bar" -| shadow:pseudoId="-webkit-meter-bar" -| <div> -| pseudo="-webkit-meter-suboptimum-value" -| style="width: 100%;" -| shadow:pseudoId="-webkit-meter-suboptimum-value" -| <div> -| pseudo="-internal-fallback" -| shadow:pseudoId="-internal-fallback" -| <slot> -| name="user-agent-default-slot" -| " - " -| <meter> -| high="6" -| low="3" -| max="10" -| min="0" -| optimum="0" -| value="10" -| <shadow:root> -| <div> -| pseudo="-webkit-meter-inner-element" -| shadow:pseudoId="-webkit-meter-inner-element" -| <div> -| pseudo="-webkit-meter-bar" -| shadow:pseudoId="-webkit-meter-bar" -| <div> -| pseudo="-webkit-meter-even-less-good-value" -| style="width: 100%;" -| shadow:pseudoId="-webkit-meter-even-less-good-value" -| <div> -| pseudo="-internal-fallback" -| shadow:pseudoId="-internal-fallback" -| <slot> -| name="user-agent-default-slot" -| " - "
diff --git a/third_party/blink/web_tests/platform/win7/virtual/web-components-v0-disabled/external/wpt/dom/events/scrolling/scrollend-event-for-user-scroll-expected.txt b/third_party/blink/web_tests/platform/win7/virtual/web-components-v0-disabled/external/wpt/dom/events/scrolling/scrollend-event-for-user-scroll-expected.txt deleted file mode 100644 index a9b7884..0000000 --- a/third_party/blink/web_tests/platform/win7/virtual/web-components-v0-disabled/external/wpt/dom/events/scrolling/scrollend-event-for-user-scroll-expected.txt +++ /dev/null
@@ -1,7 +0,0 @@ -This is a testharness.js-based test. -FAIL Tests that the target_div gets scrollend event when dragging scroll on target. promise_test: Unhandled rejection with value: "target_div did not receive scrollend event after dragging scroll on target." -FAIL Tests that the target_div gets scrollend event when click scrollbar on target. promise_test: Unhandled rejection with value: "target_div did not receive scrollend event after clicking scrollbar on target." -FAIL Tests that the target_div gets scrollend event when drag the thumb of target. promise_test: Unhandled rejection with value: "target_div did not receive scrollend event after dragging the thumb of target." -PASS Tests that the target_div gets scrollend event when send DOWN key to target. -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/win7/virtual/web-components-v0-disabled/fast/dom/HTMLMeterElement/meter-clone-expected.txt b/third_party/blink/web_tests/platform/win7/virtual/web-components-v0-disabled/fast/dom/HTMLMeterElement/meter-clone-expected.txt deleted file mode 100644 index f840958..0000000 --- a/third_party/blink/web_tests/platform/win7/virtual/web-components-v0-disabled/fast/dom/HTMLMeterElement/meter-clone-expected.txt +++ /dev/null
@@ -1,10 +0,0 @@ -PASS cloned.value is target.value -PASS internals.shadowPseudoId(clonedShadowRoot.firstChild) is internals.shadowPseudoId(targetShadowRoot.firstChild) -PASS internals.shadowPseudoId(clonedShadowRoot.firstChild.firstChild) is internals.shadowPseudoId(targetShadowRoot.firstChild.firstChild) -PASS internals.shadowPseudoId(clonedShadowRoot.firstChild.firstChild.firstChild) is internals.shadowPseudoId(targetShadowRoot.firstChild.firstChild.firstChild) -PASS clonedShadowRoot.firstChild.firstChild.firstChild.style.width is "70%" -PASS targetShadowRoot.firstChild.firstChild.firstChild.style.width is "50%" -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/blink/web_tests/platform/win7/virtual/web-components-v0-disabled/fast/dom/HTMLMeterElement/meter-element-markup-expected.txt b/third_party/blink/web_tests/platform/win7/virtual/web-components-v0-disabled/fast/dom/HTMLMeterElement/meter-element-markup-expected.txt deleted file mode 100644 index a39a6a3..0000000 --- a/third_party/blink/web_tests/platform/win7/virtual/web-components-v0-disabled/fast/dom/HTMLMeterElement/meter-element-markup-expected.txt +++ /dev/null
@@ -1,75 +0,0 @@ - -Both meter elements should have a nested shadow box with a width specified: -| " - " -| <meter> -| max="100" -| value="70" -| <shadow:root> -| <div> -| pseudo="-webkit-meter-inner-element" -| shadow:pseudoId="-webkit-meter-inner-element" -| <div> -| pseudo="-webkit-meter-bar" -| shadow:pseudoId="-webkit-meter-bar" -| <div> -| pseudo="-webkit-meter-optimum-value" -| style="width: 70%;" -| shadow:pseudoId="-webkit-meter-optimum-value" -| <div> -| pseudo="-internal-fallback" -| shadow:pseudoId="-internal-fallback" -| <slot> -| name="user-agent-default-slot" -| " - " -| <meter> -| high="6" -| low="3" -| max="10" -| min="0" -| optimum="5" -| value="10" -| <shadow:root> -| <div> -| pseudo="-webkit-meter-inner-element" -| shadow:pseudoId="-webkit-meter-inner-element" -| <div> -| pseudo="-webkit-meter-bar" -| shadow:pseudoId="-webkit-meter-bar" -| <div> -| pseudo="-webkit-meter-suboptimum-value" -| style="width: 100%;" -| shadow:pseudoId="-webkit-meter-suboptimum-value" -| <div> -| pseudo="-internal-fallback" -| shadow:pseudoId="-internal-fallback" -| <slot> -| name="user-agent-default-slot" -| " - " -| <meter> -| high="6" -| low="3" -| max="10" -| min="0" -| optimum="0" -| value="10" -| <shadow:root> -| <div> -| pseudo="-webkit-meter-inner-element" -| shadow:pseudoId="-webkit-meter-inner-element" -| <div> -| pseudo="-webkit-meter-bar" -| shadow:pseudoId="-webkit-meter-bar" -| <div> -| pseudo="-webkit-meter-even-less-good-value" -| style="width: 100%;" -| shadow:pseudoId="-webkit-meter-even-less-good-value" -| <div> -| pseudo="-internal-fallback" -| shadow:pseudoId="-internal-fallback" -| <slot> -| name="user-agent-default-slot" -| " - "
diff --git a/third_party/blink/web_tests/virtual/dark-mode-default/dark-mode/images/image-as-shader-expected.png b/third_party/blink/web_tests/virtual/dark-mode-default/dark-mode/images/image-as-shader-expected.png new file mode 100644 index 0000000..30310d5 --- /dev/null +++ b/third_party/blink/web_tests/virtual/dark-mode-default/dark-mode/images/image-as-shader-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/virtual/dark-mode-images-filter-all/dark-mode/images/image-as-shader-expected.png b/third_party/blink/web_tests/virtual/dark-mode-images-filter-all/dark-mode/images/image-as-shader-expected.png new file mode 100644 index 0000000..30310d5 --- /dev/null +++ b/third_party/blink/web_tests/virtual/dark-mode-images-filter-all/dark-mode/images/image-as-shader-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/virtual/dark-mode-images-filter-none/dark-mode/images/image-as-shader-expected.png b/third_party/blink/web_tests/virtual/dark-mode-images-filter-none/dark-mode/images/image-as-shader-expected.png new file mode 100644 index 0000000..30310d5 --- /dev/null +++ b/third_party/blink/web_tests/virtual/dark-mode-images-filter-none/dark-mode/images/image-as-shader-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/virtual/dark-mode-images-grayscale/dark-mode/images/image-as-shader-expected.png b/third_party/blink/web_tests/virtual/dark-mode-images-grayscale/dark-mode/images/image-as-shader-expected.png new file mode 100644 index 0000000..30310d5 --- /dev/null +++ b/third_party/blink/web_tests/virtual/dark-mode-images-grayscale/dark-mode/images/image-as-shader-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/virtual/text-antialias/hyphens/hyphens-auto-nowrap-expected.html b/third_party/blink/web_tests/virtual/text-antialias/hyphens/hyphens-auto-nowrap-expected.html index 618993e..8054af3 100644 --- a/third_party/blink/web_tests/virtual/text-antialias/hyphens/hyphens-auto-nowrap-expected.html +++ b/third_party/blink/web_tests/virtual/text-antialias/hyphens/hyphens-auto-nowrap-expected.html
@@ -8,6 +8,6 @@ } </style> <div lang="en-us"> - <div>hy-<br>phenation</div> + <div>hy-<br>phen-<br>ation</div> <div>hyphenation</div> </div>
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt index 88d9550..7e49a267 100644 --- a/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt +++ b/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -16,6 +16,7 @@ [Worker] method constructor [Worker] setter onabort [Worker] interface AudioDecoder +[Worker] static method isConfigSupported [Worker] attribute @@toStringTag [Worker] getter decodeQueueSize [Worker] getter state @@ -25,6 +26,16 @@ [Worker] method decode [Worker] method flush [Worker] method reset +[Worker] interface AudioEncoder +[Worker] attribute @@toStringTag +[Worker] getter encodeQueueSize +[Worker] getter state +[Worker] method close +[Worker] method configure +[Worker] method constructor +[Worker] method encode +[Worker] method flush +[Worker] method reset [Worker] interface AudioFrame [Worker] attribute @@toStringTag [Worker] getter buffer
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt index f0c175c..efef17d 100644 --- a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt +++ b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
@@ -271,6 +271,7 @@ method resume method suspend interface AudioDecoder + static method isConfigSupported attribute @@toStringTag getter decodeQueueSize getter state @@ -284,6 +285,16 @@ attribute @@toStringTag getter maxChannelCount method constructor +interface AudioEncoder + attribute @@toStringTag + getter encodeQueueSize + getter state + method close + method configure + method constructor + method encode + method flush + method reset interface AudioFrame attribute @@toStringTag getter buffer
diff --git a/third_party/farmhash/BUILD.gn b/third_party/farmhash/BUILD.gn index 3af22438..722f95e 100644 --- a/third_party/farmhash/BUILD.gn +++ b/third_party/farmhash/BUILD.gn
@@ -6,6 +6,14 @@ include_dirs = [ "src/src" ] } +config("farmhash-warnings") { + cflags = [] + + # The reduction of farmhash files to a minimum triggers -Wunused-function + # warnings in farmhash.c + cflags += [ "-Wno-unused-function" ] +} + source_set("farmhash") { public = [ "src/src/farmhash.h" ] @@ -13,6 +21,7 @@ configs -= [ "//build/config/compiler:chromium_code" ] configs += [ "//build/config/compiler:no_chromium_code" ] + configs += [ ":farmhash-warnings" ] public_configs = [ ":farmhash_include" ] }
diff --git a/tools/clang/rewrite_raw_ptr_fields/RewriteRawPtrFields.cpp b/tools/clang/rewrite_raw_ptr_fields/RewriteRawPtrFields.cpp index dd196f1..0ae7637 100644 --- a/tools/clang/rewrite_raw_ptr_fields/RewriteRawPtrFields.cpp +++ b/tools/clang/rewrite_raw_ptr_fields/RewriteRawPtrFields.cpp
@@ -1086,7 +1086,7 @@ // TODO(lukasza): It is unclear why |traverse| below is needed. Maybe it can // be removed if https://bugs.llvm.org/show_bug.cgi?id=46287 is fixed. match_finder.addMatcher( - traverse(clang::ast_type_traits::TK_AsIs, + traverse(clang::TraversalKind::TK_AsIs, cxxConstructExpr(templated_function_arg_matcher)), &affected_expr_rewriter);
diff --git a/tools/ipc_fuzzer/fuzzer/fuzzer.cc b/tools/ipc_fuzzer/fuzzer/fuzzer.cc index e458d00e..7319b4e 100644 --- a/tools/ipc_fuzzer/fuzzer/fuzzer.cc +++ b/tools/ipc_fuzzer/fuzzer/fuzzer.cc
@@ -1670,7 +1670,7 @@ case 0: { // network::DataElement::Type::TYPE_BYTES if (RandEvent(2)) { - p->SetToEmptyBytes(); + p->SetToBytes(nullptr, 0); } else { char data[256]; int data_len = RandInRange(sizeof(data));
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index 3a944c31..a30a4f5 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -284,8 +284,6 @@ 'Libfuzzer Upload Mac ASan': 'libfuzzer_mac_asan_shared_release_bot', 'Libfuzzer Upload Windows ASan': 'libfuzzer_windows_asan_release_bot', - 'Linux remote_run Builder': 'release_bot', - 'Linux remote_run Tester': 'release_bot', 'Linux Viz': 'release_trybot', 'linux-ash-chromium-builder-fyi-rel': 'chromeos_with_codecs_release_bot', 'linux-lacros-builder-fyi-rel': 'lacros_on_linux_release_bot', @@ -1521,7 +1519,7 @@ ], 'angle_specific_release_trybot_ios': [ - 'angle_specific_tests', 'shared_release_trybot', 'ios', 'ios_simulator', 'ios_cpu_x64', 'xctest', + 'angle_specific_tests', 'release_trybot', 'ios', 'ios_simulator', 'ios_cpu_x64', 'xctest', ], 'angle_specific_release_trybot_x86': [
diff --git a/tools/mb/mb_config_expectations/chromium.angle.json b/tools/mb/mb_config_expectations/chromium.angle.json index f30b87c3..e796400c9 100644 --- a/tools/mb/mb_config_expectations/chromium.angle.json +++ b/tools/mb/mb_config_expectations/chromium.angle.json
@@ -96,7 +96,7 @@ "build_angle_trace_perf_tests": true, "dcheck_always_on": true, "enable_run_ios_unittests_with_xctest": true, - "is_component_build": true, + "is_component_build": false, "is_debug": false, "symbol_level": 1, "target_cpu": "x64",
diff --git a/tools/mb/mb_config_expectations/chromium.fyi.json b/tools/mb/mb_config_expectations/chromium.fyi.json index f0f86cf4..fd37073 100644 --- a/tools/mb/mb_config_expectations/chromium.fyi.json +++ b/tools/mb/mb_config_expectations/chromium.fyi.json
@@ -130,20 +130,6 @@ "use_goma": true } }, - "Linux remote_run Builder": { - "gn_args": { - "is_component_build": false, - "is_debug": false, - "use_goma": true - } - }, - "Linux remote_run Tester": { - "gn_args": { - "is_component_build": false, - "is_debug": false, - "use_goma": true - } - }, "Mac Builder Next": { "gn_args": { "ffmpeg_branding": "Chrome",
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.angle.json b/tools/mb/mb_config_expectations/tryserver.chromium.angle.json index 9f5a6096..d855b9d 100644 --- a/tools/mb/mb_config_expectations/tryserver.chromium.angle.json +++ b/tools/mb/mb_config_expectations/tryserver.chromium.angle.json
@@ -113,7 +113,7 @@ "build_angle_trace_perf_tests": true, "dcheck_always_on": true, "enable_run_ios_unittests_with_xctest": true, - "is_component_build": true, + "is_component_build": false, "is_debug": false, "symbol_level": 1, "target_cpu": "x64",
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml index 5c1dd3ed..66e6316 100644 --- a/tools/metrics/actions/actions.xml +++ b/tools/metrics/actions/actions.xml
@@ -9148,6 +9148,16 @@ </description> </action> +<action name="IOS.DefaultBrowserFullscreenPromo.RemindMeTapped"> + <owner>thegreenfrog@chromium.org</owner> + <owner>rohitrao@chromium.org</owner> + <description> + The user tapped the "Remind Me Later" button in the default + browser fullscreen promo modal that takes the user to the Settings app. iOS + only. + </description> +</action> + <action name="IOS.DefaultBrowserNTPPromoTapped"> <owner>thegreenfrog@chromium.org</owner> <owner>rohitrao@chromium.org</owner> @@ -12037,6 +12047,7 @@ </action> <action name="ManagedUsers_Chromeos_Sync_Recovered"> + <obsolete>Legacy supervised users are deprecated</obsolete> <owner>Please list the metric's owners. Add more owner tags as needed.</owner> <description>Please enter the description of this user action.</description> </action> @@ -22095,6 +22106,15 @@ </description> </action> +<action name="Signin_Impression_FromUserManager" not_user_triggered="true"> + <owner>jkrcal@chromium.org</owner> + <owner>droger@chromium.org</owner> + <description> + Recorded when showing sign in entry in the profile creation flow (as part of + the profile picker). + </description> +</action> + <action name="Signin_ImpressionWithAccount_FromAvatarBubbleSignin" not_user_triggered="true"> <owner>msarda@chromium.org</owner>
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index a4a28730..bd1c8c4 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -21831,6 +21831,7 @@ <int value="7" label="File IO error"/> <int value="8" label="Dlp interruption"/> <int value="9" label="Low disk space"/> + <int value="10" label="HDCP interruption"/> </enum> <enum name="EnhancedBookmarkViewMode"> @@ -30824,6 +30825,7 @@ <int value="3748" label="SamePartyCookieInclusionOverruledSameSite"/> <int value="3749" label="EmbedElementWithoutTypeSrcChanged"/> <int value="3750" label="PaymentHandlerStandardizedPaymentMethodIdentifier"/> + <int value="3751" label="WebCodecsAudioEncoder"/> </enum> <enum name="FeaturePolicyAllowlistType"> @@ -39351,6 +39353,7 @@ <enum name="IOSDefaultBrowserFullscreenPromoAction"> <int value="0" label="Action Button"/> <int value="1" label="Cancel"/> + <int value="2" label="Remind Me Later"/> </enum> <enum name="IOSDeviceThermalState"> @@ -41067,6 +41070,10 @@ <int value="8" label="HandleUpdateOrigins Invalid"/> </enum> +<enum name="LaunchCause"> + <int value="0" label="Other"/> +</enum> + <enum name="LauncherRankingItemType"> <summary> The type of a result in the Chrome OS launcher, simplified to fewer @@ -55774,6 +55781,7 @@ <int value="1704" label="Get Help with Chrome OS"/> <int value="1705" label="Report an Issue"/> <int value="1706" label="View Terms of Service"/> + <int value="1707" label="Open Diagnostics App"/> <int value="1800" label="View 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/histograms_xml/android/histograms.xml b/tools/metrics/histograms/histograms_xml/android/histograms.xml index 3b549d0..89fc3e4 100644 --- a/tools/metrics/histograms/histograms_xml/android/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/android/histograms.xml
@@ -1188,6 +1188,18 @@ </summary> </histogram> +<histogram base="true" name="Android.IsolatedSplits.ClassLoaderReplaced" + enum="BooleanYesNo" expires_after="2022-01-10"> +<!-- Name completed by histogram_suffixes name="AndroidFeatureModuleName" --> + + <owner>cduvall@chromium.org</owner> + <owner>agrieve@chromium.org</owner> + <summary> + Whether a split Context has had its ClassLoader replaced due to b/172602571. + This is recorded every time a split Context is created. + </summary> +</histogram> + <histogram base="true" name="Android.IsolatedSplits.ContextCreateTime" units="ms" expires_after="2021-12-07"> <!-- Name completed by histogram_suffixes name="AndroidFeatureModuleName" -->
diff --git a/tools/metrics/histograms/histograms_xml/ash/histograms.xml b/tools/metrics/histograms/histograms_xml/ash/histograms.xml index 332b005..d2421b86 100644 --- a/tools/metrics/histograms/histograms_xml/ash/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/ash/histograms.xml
@@ -336,6 +336,26 @@ </summary> </histogram> +<histogram name="Ash.Clipboard.ConsecutiveCopies" units="times" + expires_after="2021-09-01"> + <owner>newcomer@chromium.org</owner> + <owner>multipaste@google.com</owner> + <summary> + The number of consecutive copies in the user session, recorded when a paste + occurs. + </summary> +</histogram> + +<histogram name="Ash.Clipboard.ConsecutivePastes" units="times" + expires_after="2021-09-01"> + <owner>newcomer@chromium.org</owner> + <owner>multipaste@google.com</owner> + <summary> + The number of consecutive pastes in the user session, recorded when a copy + occurs. Includes pastes from Clipboard History. + </summary> +</histogram> + <histogram name="Ash.ClipboardHistory.ContextMenu.DisplayFormatDeleted" enum="ClipboardHistoryDisplayFormat" expires_after="2021-09-01"> <owner>andrewxu@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/blink/histograms.xml b/tools/metrics/histograms/histograms_xml/blink/histograms.xml index 784c786..f4bb1a74 100644 --- a/tools/metrics/histograms/histograms_xml/blink/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/blink/histograms.xml
@@ -33,7 +33,7 @@ </summary> </histogram> -<histogram name="Blink.Animate.UpdateTime" units="microseconds" +<histogram base="true" name="Blink.Animate.UpdateTime" units="microseconds" expires_after="2021-05-23"> <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" --> @@ -432,8 +432,8 @@ </summary> </histogram> -<histogram name="Blink.CompositingAssignments.UpdateTime" units="microseconds" - expires_after="2021-07-04"> +<histogram base="true" name="Blink.CompositingAssignments.UpdateTime" + units="microseconds" expires_after="2021-07-04"> <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" --> <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePostFCPSuffixes" --> @@ -451,8 +451,8 @@ </summary> </histogram> -<histogram name="Blink.CompositingCommit.UpdateTime" units="microseconds" - expires_after="2021-07-04"> +<histogram base="true" name="Blink.CompositingCommit.UpdateTime" + units="microseconds" expires_after="2021-07-04"> <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" --> <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePostFCPSuffixes" --> @@ -474,8 +474,8 @@ </summary> </histogram> -<histogram name="Blink.CompositingInputs.UpdateTime" units="microseconds" - expires_after="2021-07-04"> +<histogram base="true" name="Blink.CompositingInputs.UpdateTime" + units="microseconds" expires_after="2021-07-04"> <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" --> <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePostFCPSuffixes" --> @@ -591,7 +591,7 @@ <summary>Image codec inferred during decode.</summary> </histogram> -<histogram name="Blink.DisplayLockIntersectionObserver.UpdateTime" +<histogram base="true" name="Blink.DisplayLockIntersectionObserver.UpdateTime" units="microseconds" expires_after="2021-06-06"> <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" --> @@ -843,8 +843,8 @@ </summary> </histogram> -<histogram name="Blink.ForcedStyleAndLayout.UpdateTime" units="microseconds" - expires_after="2021-05-23"> +<histogram base="true" name="Blink.ForcedStyleAndLayout.UpdateTime" + units="microseconds" expires_after="2021-05-23"> <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" --> <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePostFCPSuffixes" --> @@ -861,8 +861,8 @@ </summary> </histogram> -<histogram name="Blink.HandleInputEvents.UpdateTime" units="microseconds" - expires_after="2021-07-04"> +<histogram base="true" name="Blink.HandleInputEvents.UpdateTime" + units="microseconds" expires_after="2021-07-04"> <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" --> <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePostFCPSuffixes" --> @@ -879,8 +879,8 @@ </summary> </histogram> -<histogram name="Blink.HitTestDocumentUpdate.UpdateTime" units="microseconds" - expires_after="2021-07-04"> +<histogram base="true" name="Blink.HitTestDocumentUpdate.UpdateTime" + units="microseconds" expires_after="2021-07-04"> <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" --> <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePostFCPSuffixes" --> @@ -1089,8 +1089,8 @@ </summary> </histogram> -<histogram name="Blink.ImplCompositorCommit.UpdateTime" units="microseconds" - expires_after="2021-07-04"> +<histogram base="true" name="Blink.ImplCompositorCommit.UpdateTime" + units="microseconds" expires_after="2021-07-04"> <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" --> <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePostFCPSuffixes" --> @@ -1117,8 +1117,8 @@ <summary>Records if a GestureScrollBegin is for cursor control.</summary> </histogram> -<histogram name="Blink.IntersectionObservation.UpdateTime" units="microseconds" - expires_after="2021-05-23"> +<histogram base="true" name="Blink.IntersectionObservation.UpdateTime" + units="microseconds" expires_after="2021-05-23"> <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" --> <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePostFCPSuffixes" --> @@ -1136,7 +1136,7 @@ </summary> </histogram> -<histogram name="Blink.JavascriptIntersectionObserver.UpdateTime" +<histogram base="true" name="Blink.JavascriptIntersectionObserver.UpdateTime" units="microseconds" expires_after="2021-06-06"> <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" --> @@ -1195,7 +1195,7 @@ </summary> </histogram> -<histogram name="Blink.Layout.UpdateTime" units="microseconds" +<histogram base="true" name="Blink.Layout.UpdateTime" units="microseconds" expires_after="2021-07-04"> <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" --> @@ -1249,7 +1249,7 @@ </summary> </histogram> -<histogram name="Blink.LazyLoadIntersectionObserver.UpdateTime" +<histogram base="true" name="Blink.LazyLoadIntersectionObserver.UpdateTime" units="microseconds" expires_after="2021-06-06"> <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" --> @@ -1513,7 +1513,7 @@ </summary> </histogram> -<histogram name="Blink.MainFrame.UpdateTime" units="microseconds" +<histogram base="true" name="Blink.MainFrame.UpdateTime" units="microseconds" expires_after="2021-06-20"> <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" --> @@ -1546,7 +1546,7 @@ </summary> </histogram> -<histogram name="Blink.MediaIntersectionObserver.UpdateTime" +<histogram base="true" name="Blink.MediaIntersectionObserver.UpdateTime" units="microseconds" expires_after="2021-06-06"> <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" --> @@ -1700,7 +1700,7 @@ </summary> </histogram> -<histogram name="Blink.Paint.UpdateTime" units="microseconds" +<histogram base="true" name="Blink.Paint.UpdateTime" units="microseconds" expires_after="2021-06-20"> <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" --> @@ -1718,7 +1718,7 @@ </summary> </histogram> -<histogram name="Blink.PrePaint.UpdateTime" units="microseconds" +<histogram base="true" name="Blink.PrePaint.UpdateTime" units="microseconds" expires_after="2021-06-27"> <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" --> @@ -1843,8 +1843,8 @@ </summary> </histogram> -<histogram name="Blink.ScrollingCoordinator.UpdateTime" units="microseconds" - expires_after="M88"> +<histogram base="true" name="Blink.ScrollingCoordinator.UpdateTime" + units="microseconds" expires_after="M88"> <obsolete> Merged into Blink.CompositingCommit.UpdateTime in http://crrev.com/815947 in M88. @@ -2030,7 +2030,7 @@ </summary> </histogram> -<histogram name="Blink.Style.UpdateTime" units="microseconds" +<histogram base="true" name="Blink.Style.UpdateTime" units="microseconds" expires_after="2021-05-23"> <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" --> @@ -2393,8 +2393,8 @@ </summary> </histogram> -<histogram name="Blink.WaitForCommit.UpdateTime" units="microseconds" - expires_after="2021-07-04"> +<histogram base="true" name="Blink.WaitForCommit.UpdateTime" + units="microseconds" expires_after="2021-07-04"> <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" --> <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePostFCPSuffixes" -->
diff --git a/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml b/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml index c66e24a..c491856e 100644 --- a/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml +++ b/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml
@@ -775,6 +775,7 @@ <suffix name="chrome" label="Chrome Module"/> <suffix name="dev_ui" label="Developer UI Module"/> <suffix name="extra_icu" label="Extra ICU Module"/> + <suffix name="feedv2" label="Feed V2 Module"/> <suffix name="image_editor" label="Image Editor Module"/> <suffix name="stack_unwinder" label="Stack Unwinder Module"/> <suffix name="tab_ui" label="Tab Management Module"/> @@ -828,6 +829,7 @@ name="Android.FeatureModules.UncachedInstallDuration.PendingDownload"/> <affected-histogram name="Android.FeatureModules.UncachedInstallDuration.PendingInstall"/> + <affected-histogram name="Android.IsolatedSplits.ClassLoaderReplaced"/> <affected-histogram name="Android.IsolatedSplits.ContextCreateTime"/> <affected-histogram name="Android.IsolatedSplits.PreloadWaitTime"/> </histogram_suffixes> @@ -8211,6 +8213,8 @@ </suffix> <suffix name="FeedJournalDatabase" label="Database for Feed journal storage."/> + <suffix name="FeedKeyValueDatabase" + label="Database for key value cache used in feed rendering."/> <suffix name="FeedStorageDatabase" label="Databases for Feed Storage."> <obsolete> Deprecated since 08/18.
diff --git a/tools/metrics/histograms/histograms_xml/ios/histograms.xml b/tools/metrics/histograms/histograms_xml/ios/histograms.xml index 292c252..79de568a 100644 --- a/tools/metrics/histograms/histograms_xml/ios/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/ios/histograms.xml
@@ -272,6 +272,26 @@ </summary> </histogram> +<histogram name="IOS.DefaultBrowserFullscreenPromoRemindMe" + enum="IOSDefaultBrowserFullscreenPromoAction" expires_after="2021-03-01"> + <owner>thegreenfrog@chromium.org</owner> + <owner>rohitrao@chromium.org</owner> + <summary> + The action taken by the user in response to the default browser promo with + the Remind Me Later button. + </summary> +</histogram> + +<histogram name="IOS.DefaultBrowserFullscreenPromoRemindMeSecondPromo" + enum="IOSDefaultBrowserFullscreenPromoAction" expires_after="2021-03-01"> + <owner>thegreenfrog@chromium.org</owner> + <owner>rohitrao@chromium.org</owner> + <summary> + The action taken by the user in response to the second default browser promo + after tapping on the Remind Me Later button. + </summary> +</histogram> + <histogram name="IOS.Dialogs.JavaScriptDialogClosed" enum="IOSJavaScriptDialogDismissalCause" expires_after="M80"> <owner>kkhorimoto@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/mobile/histograms.xml b/tools/metrics/histograms/histograms_xml/mobile/histograms.xml index c8037a9..2beb33a8 100644 --- a/tools/metrics/histograms/histograms_xml/mobile/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/mobile/histograms.xml
@@ -1081,6 +1081,19 @@ </summary> </histogram> +<histogram name="MobileStartup.Experimental.LaunchCause" enum="LaunchCause" + expires_after="2022-01-07"> + <owner>mthiesse@chromium.org</owner> + <owner>tedchoc@chromium.org</owner> + <owner>yfriedman@chromium.org</owner> + <summary> + Records what caused Chrome to be launched. + + Recorded for all types of ChromeActivity, in all cases where Chrome becomes + visible to the user. + </summary> +</histogram> + <histogram name="MobileStartup.IntentToCreationTime" units="ms" expires_after="2021-07-04"> <owner>tedchoc@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/others/histograms.xml b/tools/metrics/histograms/histograms_xml/others/histograms.xml index afac0ce9..9219e87 100644 --- a/tools/metrics/histograms/histograms_xml/others/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/others/histograms.xml
@@ -8440,7 +8440,7 @@ </histogram> <histogram name="LiteVideo.HintAgent.ActiveThrottleSize" units="count" - expires_after="M90"> + expires_after="M94"> <owner>rajendrant@chromium.org</owner> <owner>mcrouse@chromium.org</owner> <summary> @@ -8470,7 +8470,7 @@ </histogram> <histogram name="LiteVideo.NavigationMetrics.FrameRebufferMapSize" - units="count" expires_after="M90"> + units="count" expires_after="M94"> <owner>mcrouse@chromium.org</owner> <owner>rajendrant@chromium.org</owner> <summary> @@ -8480,7 +8480,7 @@ </histogram> <histogram name="LiteVideo.OriginHints.ParseResult" enum="BooleanSuccess" - expires_after="M90"> + expires_after="M94"> <owner>mcrouse@chromium.org</owner> <owner>rajendrant@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/histograms_xml/page/histograms.xml b/tools/metrics/histograms/histograms_xml/page/histograms.xml index 02c82732..c2b19fd 100644 --- a/tools/metrics/histograms/histograms_xml/page/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/page/histograms.xml
@@ -1231,9 +1231,10 @@ </histogram> <histogram name="PageLoad.FrameCounts.AdFrames.PerFrame.CreativeOriginStatus" - enum="CrossOriginCreativeStatus" expires_after="2020-12-31"> + enum="CrossOriginCreativeStatus" expires_after="2021-06-30"> <owner>cammie@chromium.org</owner> <owner>jkarlin@chromium.org</owner> + <owner>chrome-ads-histograms@google.com</owner> <summary> For each identified ad frame, whether the origin of the ad creative frame matches or differs from the origin of the main frame. @@ -1247,9 +1248,10 @@ <histogram name="PageLoad.FrameCounts.AdFrames.PerFrame.CreativeOriginStatusWithThrottling" - enum="CrossOriginCreativeStatusWithThrottling" expires_after="2020-12-31"> + enum="CrossOriginCreativeStatusWithThrottling" expires_after="2021-06-30"> <owner>cammie@chromium.org</owner> <owner>jkarlin@chromium.org</owner> + <owner>chrome-ads-histograms@google.com</owner> <summary> For each identified ad frame, whether the origin of the ad creative frame matches or differs from the origin of the main frame, further split by
diff --git a/tools/metrics/histograms/histograms_xml/stability/histograms.xml b/tools/metrics/histograms/histograms_xml/stability/histograms.xml index 47b81204b..666cac41 100644 --- a/tools/metrics/histograms/histograms_xml/stability/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/stability/histograms.xml
@@ -436,7 +436,7 @@ </summary> </histogram> -<histogram name="Stability.iOS.UTE.MobileSessionAppWillTerminateReceived" +<histogram name="Stability.iOS.UTE.MobileSessionAppWillTerminateWasReceived" enum="AppWillTerminateReceived" expires_after="2021-04-29"> <owner>eugenebut@chromium.org</owner> <owner>olivierrobin@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/subresource/histograms.xml b/tools/metrics/histograms/histograms_xml/subresource/histograms.xml index 542b42a..893de4e 100644 --- a/tools/metrics/histograms/histograms_xml/subresource/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/subresource/histograms.xml
@@ -32,6 +32,87 @@ </summary> </histogram> +<histogram name="SubresourceFilter.CnameAlias.Browser.HadAliases" + units="BooleanHadAliases" expires_after="2021-06-18"> + <owner>cammie@chromium.org</owner> + <owner>chrome-ads-histograms@google.com</owner> + <summary> + Records whether or not a given NavigationRequest has a nonempty vector of + CNAME aliases. Only recorded if + features::kSendCnameAliasesToSubresourceFilterFromBrowser is enabled. + Recorded in a method called in the SubframeNavigationFilteringThrottle's + destructor. + </summary> +</histogram> + +<histogram name="SubresourceFilter.CnameAlias.Browser.InvalidCount" + units="count" expires_after="2021-06-18"> + <owner>cammie@chromium.org</owner> + <owner>chrome-ads-histograms@google.com</owner> + <summary> + Counts the number of invalid CNAME aliases seen for a NavigationRequest by + the SubframeNavigationFilteringThrottle. Only recorded if + features::kSendCnameAliasesToSubresourceFilterFromBrowser is enabled and the + request has a nonempty vector of CNAME aliases. Recorded in a method called + in the SubframeNavigationFilteringThrottle's destructor. + </summary> +</histogram> + +<histogram name="SubresourceFilter.CnameAlias.Browser.ListLength" + units="length" expires_after="2021-06-18"> + <owner>cammie@chromium.org</owner> + <owner>chrome-ads-histograms@google.com</owner> + <summary> + Records the lengths of each CNAME aliases vector passed to the + SubframeNavigationFilteringThrottle, not including empty alias vectors. Only + recorded if features::kSendCnameAliasesToSubresourceFilterFromBrowser is + enabled and the request has a nonempty vector of CNAME aliases. Recorded in + a method called in the SubframeNavigationFilteringThrottle's destructor. + </summary> +</histogram> + +<histogram name="SubresourceFilter.CnameAlias.Browser.RedundantCount" + units="count" expires_after="2021-06-18"> + <owner>cammie@chromium.org</owner> + <owner>chrome-ads-histograms@google.com</owner> + <summary> + Counts the number of CNAME aliases seen by the + SubframeNavigationFilteringThrottle that match the host of the requested + URL. Only recorded if + features::kSendCnameAliasesToSubresourceFilterFromBrowser is enabled and the + request has a nonempty vector of CNAME aliases. Recorded in a method called + in the SubframeNavigationFilteringThrottle's destructor. + </summary> +</histogram> + +<histogram + name="SubresourceFilter.CnameAlias.Browser.WasAdTaggedBasedOnAliasCount" + units="count" expires_after="2021-06-18"> + <owner>cammie@chromium.org</owner> + <owner>chrome-ads-histograms@google.com</owner> + <summary> + Counts the number of CNAME aliases seen for a given NavigationRequest for + which LoadPolicy::kWouldDisallow was returned due to an alias match. Only + recorded if features::kSendCnameAliasesToSubresourceFilterFromBrowser is + enabled and the request has a nonempty vector of CNAME aliases. Recorded in + a method called in the SubframeNavigationFilteringThrottle's destructor. + </summary> +</histogram> + +<histogram + name="SubresourceFilter.CnameAlias.Browser.WasBlockedBasedOnAliasCount" + units="count" expires_after="2021-06-18"> + <owner>cammie@chromium.org</owner> + <owner>chrome-ads-histograms@google.com</owner> + <summary> + Counts the number of CNAME aliases seen for a given NavigationRequest for + which LoadPolicy::kDisallow was returned due to an alias match. Only + recorded if features::kSendCnameAliasesToSubresourceFilterFromBrowser is + enabled and the request has a nonempty vector of CNAME aliases. Recorded in + a method called in the SubframeNavigationFilteringThrottle's destructor. + </summary> +</histogram> + <histogram name="SubresourceFilter.CnameAlias.Renderer.HadAliases" units="BooleanHadAliases" expires_after="2021-06-18"> <owner>cammie@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/translate/histograms.xml b/tools/metrics/histograms/histograms_xml/translate/histograms.xml index 32d8fb9..07ae711 100644 --- a/tools/metrics/histograms/histograms_xml/translate/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/translate/histograms.xml
@@ -48,7 +48,7 @@ <summary>Tracks UI events related to the translate bubble.</summary> </histogram> -<histogram name="Translate.CaptureText" units="ms" expires_after="M88"> +<histogram name="Translate.CaptureText" units="ms" expires_after="M99"> <owner>sclittle@google.com</owner> <owner>megjablon@google.com</owner> <owner>chrome-language@google.com</owner>
diff --git a/tools/perf/core/bot_platforms.py b/tools/perf/core/bot_platforms.py index 5e16cd0..fbab7b5 100644 --- a/tools/perf/core/bot_platforms.py +++ b/tools/perf/core/bot_platforms.py
@@ -444,6 +444,8 @@ ]) _CHROMEOS_KEVIN_FYI_BENCHMARK_CONFIGS = PerfSuite([ _GetBenchmarkConfig('rendering.desktop')]) +_LACROS_EVE_FYI_BENCHMARK_CONFIGS = PerfSuite(['loading.desktop' + ]).Abridge(['loading.desktop']) _LINUX_PERF_FYI_BENCHMARK_CONFIGS = PerfSuite([ _GetBenchmarkConfig('power.desktop'), _GetBenchmarkConfig('rendering.desktop'), @@ -564,6 +566,12 @@ 4, 'chromeos', is_fyi=True) +LACROS_EVE_PERF_FYI = PerfPlatform('lacros-eve-perf-fyi', + '', + _LACROS_EVE_FYI_BENCHMARK_CONFIGS, + 1, + 'chromeos', + is_fyi=True) LINUX_PERF_FYI = PerfPlatform('linux-perf-fyi', '', _LINUX_PERF_FYI_BENCHMARK_CONFIGS,
diff --git a/tools/perf/core/perf_data_generator.py b/tools/perf/core/perf_data_generator.py index 44c516f..00e4763e 100755 --- a/tools/perf/core/perf_data_generator.py +++ b/tools/perf/core/perf_data_generator.py
@@ -264,6 +264,30 @@ 'device_type': 'kevin', }, }, + 'lacros-eve-perf-fyi': { + 'tests': [ + { + 'isolate': + 'performance_test_suite', + 'extra_args': [ + # The magic hostname that resolves to a CrOS device in the test lab + '--remote=variable_chromeos_device_hostname', + ], + }, + ], + 'platform': + 'lacros', + 'target_bits': + 64, + 'dimension': { + 'pool': 'chrome.tests', + # TODO(crbug.com/971204): Explicitly set the gpu to None to make + # chromium_swarming recipe_module ignore this dimension. + 'gpu': None, + 'os': 'ChromeOS', + 'device_type': 'eve', + }, + }, } # These configurations are taken from chromium_perf.py in @@ -1157,6 +1181,8 @@ browser_name = tester_config['platform'] elif tester_config['platform'] == 'chromeos': browser_name = 'cros-chrome' + elif tester_config['platform'] == 'lacros': + browser_name = 'lacros-chrome' elif (tester_config['platform'] == 'win' and tester_config['target_bits'] == 64): browser_name = 'release_x64'
diff --git a/tools/perf/core/perf_json_config_validator.py b/tools/perf/core/perf_json_config_validator.py index 3c1496c..6b2d08b 100644 --- a/tools/perf/core/perf_json_config_validator.py +++ b/tools/perf/core/perf_json_config_validator.py
@@ -28,6 +28,7 @@ 'chromeos-kevin-perf-fyi': {'chrome.tests'}, 'chromeos-amd64-generic-lacros-builder-perf': {'chrome.tests'}, 'fuchsia-perf-fyi': {'chrome.tests'}, + 'lacros-eve-perf-fyi': {'chrome.tests'}, } @@ -111,6 +112,10 @@ if browser_options.browser != 'cros-chrome': raise ValueError("%s must use 'cros-chrome' browser type" % builder_name) + elif 'lacros' in builder_name: + if browser_options.browser != 'lacros-chrome': + raise ValueError("%s must use 'lacros-chrome' browser type" % + builder_name) elif builder_name in ('win-10-perf', 'Win 7 Nvidia GPU Perf', 'win-10_laptop_low_end-perf_HP-Candidate', 'win-10_laptop_low_end-perf'):
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index 5587a52b..79b6faa 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -1,16 +1,16 @@ { "trace_processor_shell": { "win": { - "hash": "6ca5855918a82bfcb01db2253203a17b87808902", - "remote_path": "perfetto_binaries/trace_processor_shell/win/3bf3659d351a4ca6c07900f6de1a4c8dbbc4c9d0/trace_processor_shell.exe" + "hash": "26aa7f0361bf6a3fbf5627c8c8699301ab51c6e6", + "remote_path": "perfetto_binaries/trace_processor_shell/win/026943fd29be9ac85975ddb8afdd2853bb03b3da/trace_processor_shell.exe" }, "mac": { - "hash": "9dd9c289783e601e61c7d680c3e7aec33a24f650", - "remote_path": "perfetto_binaries/trace_processor_shell/mac/eddc7d0df5d1b1fc6a35162da39375cbaa809fe7/trace_processor_shell" + "hash": "f0efd147e6c4c6f1b295bb5755a0e927fd94da5b", + "remote_path": "perfetto_binaries/trace_processor_shell/mac/026943fd29be9ac85975ddb8afdd2853bb03b3da/trace_processor_shell" }, "linux": { - "hash": "5fc878a0256dfd62f3cac5b7384536e0902e23bd", - "remote_path": "perfetto_binaries/trace_processor_shell/linux/3bf3659d351a4ca6c07900f6de1a4c8dbbc4c9d0/trace_processor_shell" + "hash": "9de25afa2969d17640815fe3b83e4427b0526564", + "remote_path": "perfetto_binaries/trace_processor_shell/linux/53a231c0ae868366179bd560b68a2f5f4b166541/trace_processor_shell" } }, "power_profile.sql": {
diff --git a/tools/perf/core/shard_maps/lacros-eve-perf-fyi_map.json b/tools/perf/core/shard_maps/lacros-eve-perf-fyi_map.json new file mode 100644 index 0000000..f23488cf --- /dev/null +++ b/tools/perf/core/shard_maps/lacros-eve-perf-fyi_map.json
@@ -0,0 +1,17 @@ +{ + "0": { + "benchmarks": { + "loading.desktop": { + "abridged": true + } + } + }, + "extra_infos": { + "num_stories": 10, + "predicted_min_shard_time": 100, + "predicted_min_shard_index": 0, + "predicted_max_shard_time": 100, + "predicted_max_shard_index": 0, + "shard #0": 100 + } +} \ No newline at end of file
diff --git a/tools/perf/core/shard_maps/timing_data/lacros-eve-perf-fyi_timing.json b/tools/perf/core/shard_maps/timing_data/lacros-eve-perf-fyi_timing.json new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/tools/perf/core/shard_maps/timing_data/lacros-eve-perf-fyi_timing.json
@@ -0,0 +1 @@ +[] \ No newline at end of file
diff --git a/ui/accessibility/accessibility_features.cc b/ui/accessibility/accessibility_features.cc index 396aca9..7ff8967 100644 --- a/ui/accessibility/accessibility_features.cc +++ b/ui/accessibility/accessibility_features.cc
@@ -117,7 +117,7 @@ #if BUILDFLAG(IS_CHROMEOS_ASH) const base::Feature kSelectToSpeakNavigationControl{ - "SelectToSpeakNavigationControl", base::FEATURE_DISABLED_BY_DEFAULT}; + "SelectToSpeakNavigationControl", base::FEATURE_ENABLED_BY_DEFAULT}; bool IsSelectToSpeakNavigationControlEnabled() { return base::FeatureList::IsEnabled(
diff --git a/ui/android/java/res/values-v17/styles.xml b/ui/android/java/res/values-v17/styles.xml index f3829c7..7b31946 100644 --- a/ui/android/java/res/values-v17/styles.xml +++ b/ui/android/java/res/values-v17/styles.xml
@@ -235,7 +235,7 @@ <item name="android:textColor">@color/default_text_color_light_list</item> </style> <style name="TextAppearance.TextMediumThick.Secondary.Light" tools:ignore="UnusedResources"> - <item name="android:textColor">@color/default_text_color_light_list</item> + <item name="android:textColor">@color/default_text_color_secondary_light_list</item> </style> <style name="TextAppearance.TextLarge.Secondary.Light" tools:ignore="UnusedResources">
diff --git a/ui/android/java/src/org/chromium/ui/widget/ChipView.java b/ui/android/java/src/org/chromium/ui/widget/ChipView.java index 2a518dc..49f2119d 100644 --- a/ui/android/java/src/org/chromium/ui/widget/ChipView.java +++ b/ui/android/java/src/org/chromium/ui/widget/ChipView.java
@@ -275,6 +275,14 @@ } /** + * Returns the {@link RectProvider} that contains the start icon for the chip view. + * @return A {@link RectProvider} + */ + public RectProvider getStartIconViewRect() { + return new ViewRectProvider(mStartIcon); + } + + /** * Sets the correct tinting on the Chip's image view. * @param tintWithTextColor If true then the image view will be tinted with the primary text * color. If not, the tint will be cleared.
diff --git a/ui/android/window_android.cc b/ui/android/window_android.cc index e37dbeb..ae0f86f 100644 --- a/ui/android/window_android.cc +++ b/ui/android/window_android.cc
@@ -147,9 +147,6 @@ } void WindowAndroid::SetPreferredRefreshRate(float refresh_rate) { - if (force_60hz_refresh_rate_) - return; - if (test_hooks_) { test_hooks_->SetPreferredRate(refresh_rate); return; @@ -204,7 +201,6 @@ float refresh_rate) { if (compositor_) compositor_->OnUpdateRefreshRate(refresh_rate); - Force60HzRefreshRateIfNeeded(); } void WindowAndroid::OnSupportedRefreshRatesUpdated( @@ -218,8 +214,6 @@ } if (compositor_) compositor_->OnUpdateSupportedRefreshRates(supported_refresh_rates); - - Force60HzRefreshRateIfNeeded(); } void WindowAndroid::SetWideColorEnabled(bool enabled) { @@ -227,22 +221,6 @@ Java_WindowAndroid_setWideColorEnabled(env, GetJavaObject(), enabled); } -void WindowAndroid::SetForce60HzRefreshRate() { - if (force_60hz_refresh_rate_) - return; - - force_60hz_refresh_rate_ = true; - Force60HzRefreshRateIfNeeded(); -} - -void WindowAndroid::Force60HzRefreshRateIfNeeded() { - if (!force_60hz_refresh_rate_) - return; - - JNIEnv* env = AttachCurrentThread(); - Java_WindowAndroid_setPreferredRefreshRate(env, GetJavaObject(), 60.f); -} - bool WindowAndroid::HasPermission(const std::string& permission) { JNIEnv* env = AttachCurrentThread(); return Java_WindowAndroid_hasPermission(
diff --git a/ui/android/window_android.h b/ui/android/window_android.h index dd82231..658e85f 100644 --- a/ui/android/window_android.h +++ b/ui/android/window_android.h
@@ -104,8 +104,6 @@ void SetWideColorEnabled(bool enabled); - void SetForce60HzRefreshRate(); - class TestHooks { public: virtual ~TestHooks() = default; @@ -148,7 +146,6 @@ bool vsync_paused_ = false; TestHooks* test_hooks_ = nullptr; - bool force_60hz_refresh_rate_ = false; int selection_handles_active_count_ = 0;
diff --git a/ui/aura/native_window_occlusion_tracker_win.cc b/ui/aura/native_window_occlusion_tracker_win.cc index 746cb68..0f177987 100644 --- a/ui/aura/native_window_occlusion_tracker_win.cc +++ b/ui/aura/native_window_occlusion_tracker_win.cc
@@ -22,8 +22,59 @@ #include "base/win/scoped_gdi_object.h" #include "base/win/windows_version.h" #include "ui/aura/window_tree_host.h" +#include "ui/base/ui_base_features.h" #include "ui/gfx/win/hwnd_util.h" +const CLSID CLSID_ImmersiveShell = { + 0xC2F03A33, + 0x21F5, + 0x47FA, + {0xB4, 0xBB, 0x15, 0x63, 0x62, 0xA2, 0xF2, 0x39}}; + +const CLSID CLSID_VirtualDesktopAPI_Unknown = { + 0xC5E0CDCA, + 0x7B6E, + 0x41B2, + {0x9F, 0xC4, 0xD9, 0x39, 0x75, 0xCC, 0x46, 0x7B}}; + +struct IApplicationView : public IUnknown { + public: +}; + +MIDL_INTERFACE("FF72FFDD-BE7E-43FC-9C03-AD81681E88E4") +IVirtualDesktop : public IUnknown { + public: + virtual HRESULT STDMETHODCALLTYPE IsViewVisible(IApplicationView * pView, + int* pfVisible) = 0; + virtual HRESULT STDMETHODCALLTYPE GetID(GUID * pGuid) = 0; +}; + +enum AdjacentDesktop { LeftDirection = 3, RightDirection = 4 }; + +MIDL_INTERFACE("F31574D6-B682-4cdc-BD56-1827860ABEC6") +IVirtualDesktopManagerInternal : public IUnknown { + public: + virtual HRESULT STDMETHODCALLTYPE GetCount(UINT * pCount) = 0; + virtual HRESULT STDMETHODCALLTYPE MoveViewToDesktop( + IApplicationView * pView, IVirtualDesktop * pDesktop) = 0; + virtual HRESULT STDMETHODCALLTYPE CanViewMoveDesktops( + IApplicationView * pView, int* pfCanViewMoveDesktops) = 0; + virtual HRESULT STDMETHODCALLTYPE GetCurrentDesktop(IVirtualDesktop * + *desktop) = 0; + virtual HRESULT STDMETHODCALLTYPE GetDesktops(IObjectArray * *ppDesktops) = 0; + virtual HRESULT STDMETHODCALLTYPE GetAdjacentDesktop( + IVirtualDesktop * pDesktopReference, AdjacentDesktop uDirection, + IVirtualDesktop * *ppAdjacentDesktop) = 0; + virtual HRESULT STDMETHODCALLTYPE SwitchDesktop(IVirtualDesktop * + pDesktop) = 0; + virtual HRESULT STDMETHODCALLTYPE CreateDesktopW(IVirtualDesktop * + *ppNewDesktop) = 0; + virtual HRESULT STDMETHODCALLTYPE RemoveDesktop( + IVirtualDesktop * pRemove, IVirtualDesktop * pFallbackDesktop) = 0; + virtual HRESULT STDMETHODCALLTYPE FindDesktop( + GUID * desktopId, IVirtualDesktop * *ppDesktop) = 0; +}; + namespace aura { namespace { @@ -32,6 +83,9 @@ const base::TimeDelta kUpdateOcclusionDelay = base::TimeDelta::FromMilliseconds(16); +const base::TimeDelta kUpdateVirtualDesktopDelay = + base::TimeDelta::FromMilliseconds(1000); + // This global variable can be accessed only on main thread. NativeWindowOcclusionTrackerWin* g_tracker = nullptr; @@ -313,6 +367,19 @@ if (base::win::GetVersion() >= base::win::Version::WIN10) { ::CoCreateInstance(__uuidof(VirtualDesktopManager), nullptr, CLSCTX_ALL, IID_PPV_ARGS(&virtual_desktop_manager_)); + + Microsoft::WRL::ComPtr<IServiceProvider> service_provider; + if (base::FeatureList::IsEnabled( + features::kCalculateNativeWinOcclusionCheckVirtualDesktopUsed) && + SUCCEEDED(::CoCreateInstance(CLSID_ImmersiveShell, NULL, + CLSCTX_LOCAL_SERVER, + IID_PPV_ARGS(&service_provider)))) { + service_provider->QueryService( + CLSID_VirtualDesktopAPI_Unknown, + IID_PPV_ARGS(&virtual_desktop_manager_internal_)); + if (virtual_desktop_manager_internal_) + ComputeVirtualDesktopUsed(); + } } DETACH_FROM_SEQUENCE(sequence_checker_); } @@ -362,6 +429,8 @@ UnregisterEventHooks(); if (occlusion_update_timer_.IsRunning()) occlusion_update_timer_.Stop(); + if (virtual_desktop_update_timer_.IsRunning()) + virtual_desktop_update_timer_.Stop(); } } @@ -508,12 +577,25 @@ } void NativeWindowOcclusionTrackerWin::WindowOcclusionCalculator:: + ComputeVirtualDesktopUsed() { + UINT count = 0; + if (SUCCEEDED(virtual_desktop_manager_internal_->GetCount(&count))) + virtual_desktops_used_ = count > 1; +} + +void NativeWindowOcclusionTrackerWin::WindowOcclusionCalculator:: ScheduleOcclusionCalculationIfNeeded() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!occlusion_update_timer_.IsRunning()) + if (!occlusion_update_timer_.IsRunning()) { occlusion_update_timer_.Start( FROM_HERE, kUpdateOcclusionDelay, this, &WindowOcclusionCalculator::ComputeNativeWindowOcclusionStatus); + if (virtual_desktop_manager_internal_) { + virtual_desktop_update_timer_.Start( + FROM_HERE, kUpdateVirtualDesktopDelay, this, + &WindowOcclusionCalculator::ComputeVirtualDesktopUsed); + } + } } void NativeWindowOcclusionTrackerWin::WindowOcclusionCalculator:: @@ -769,7 +851,7 @@ base::Optional<bool> NativeWindowOcclusionTrackerWin:: WindowOcclusionCalculator::IsWindowOnCurrentVirtualDesktop(HWND hwnd) { - if (!virtual_desktop_manager_) + if (!virtual_desktop_manager_ || !virtual_desktops_used_) return true; BOOL on_current_desktop;
diff --git a/ui/aura/native_window_occlusion_tracker_win.h b/ui/aura/native_window_occlusion_tracker_win.h index 4934e8b..7c64593 100644 --- a/ui/aura/native_window_occlusion_tracker_win.h +++ b/ui/aura/native_window_occlusion_tracker_win.h
@@ -34,6 +34,8 @@ class Rect; } +struct IVirtualDesktopManagerInternal; + namespace aura { // This class keeps track of whether any HWNDs are occluding any app windows. @@ -134,6 +136,10 @@ // their occlusion status has changed. void ComputeNativeWindowOcclusionStatus(); + // Computes if virtual desktops are used. This is used as an optimization + // since IsWindowOnCurrentVirtualDesktop is a slow call. + void ComputeVirtualDesktopUsed(); + // Schedules an occlusion calculation |update_occlusion_delay_| time in the // future, if one isn't already scheduled. void ScheduleOcclusionCalculationIfNeeded(); @@ -217,6 +223,9 @@ // Timer to delay occlusion update. base::OneShotTimer occlusion_update_timer_; + // Timer to check how many virtual desktops are present. + base::OneShotTimer virtual_desktop_update_timer_; + // Used to keep track of whether we're in the middle of getting window move // events, in order to wait until the window move is complete before // calculating window occlusion. @@ -244,9 +253,18 @@ // ignore windows occluded by the dragged window. HWND moving_window_ = 0; + // By caching if virtual desktops are in use or not we can avoid calling + // IsWindowOnCurrentVirtualDesktop which is slow. Start with an initial + // value of true so that we only optimize after we get confirmation that + // there are no virtual desktops. + bool virtual_desktops_used_ = true; + // Only used on Win10+. Microsoft::WRL::ComPtr<IVirtualDesktopManager> virtual_desktop_manager_; + Microsoft::WRL::ComPtr<IVirtualDesktopManagerInternal> + virtual_desktop_manager_internal_; + SEQUENCE_CHECKER(sequence_checker_); base::WeakPtrFactory<WindowOcclusionCalculator> weak_factory_{this};
diff --git a/ui/base/ui_base_features.cc b/ui/base/ui_base_features.cc index 2d5847dd7..0193353 100644 --- a/ui/base/ui_base_features.cc +++ b/ui/base/ui_base_features.cc
@@ -24,6 +24,10 @@ // If enabled, calculate native window occlusion - Windows-only. const base::Feature kCalculateNativeWinOcclusion{ "CalculateNativeWinOcclusion", base::FEATURE_ENABLED_BY_DEFAULT}; + +const base::Feature kCalculateNativeWinOcclusionCheckVirtualDesktopUsed{ + "CalculateNativeWinOcclusionCheckVirtualDesktopUsed", + base::FEATURE_DISABLED_BY_DEFAULT}; #endif // OW_WIN // Whether or not to delegate color queries to the color provider.
diff --git a/ui/base/ui_base_features.h b/ui/base/ui_base_features.h index 4eeda91..e12abf7 100644 --- a/ui/base/ui_base_features.h +++ b/ui/base/ui_base_features.h
@@ -48,6 +48,8 @@ COMPONENT_EXPORT(UI_BASE_FEATURES) extern const base::Feature kCalculateNativeWinOcclusion; COMPONENT_EXPORT(UI_BASE_FEATURES) +extern const base::Feature kCalculateNativeWinOcclusionCheckVirtualDesktopUsed; +COMPONENT_EXPORT(UI_BASE_FEATURES) extern const base::Feature kElasticOverscrollWin; COMPONENT_EXPORT(UI_BASE_FEATURES) extern const base::Feature kInputPaneOnScreenKeyboard;
diff --git a/ui/compositor/animation_throughput_reporter.cc b/ui/compositor/animation_throughput_reporter.cc index 893a539..043a349f 100644 --- a/ui/compositor/animation_throughput_reporter.cc +++ b/ui/compositor/animation_throughput_reporter.cc
@@ -9,10 +9,8 @@ #include "base/bind.h" #include "base/check.h" -#include "base/memory/scoped_refptr.h" #include "base/memory/weak_ptr.h" #include "base/optional.h" -#include "base/scoped_observation.h" #include "cc/animation/animation.h" #include "ui/compositor/callback_layer_animation_observer.h" #include "ui/compositor/compositor.h" @@ -20,7 +18,6 @@ #include "ui/compositor/layer_animation_delegate.h" #include "ui/compositor/layer_animation_sequence.h" #include "ui/compositor/layer_animator.h" -#include "ui/compositor/layer_observer.h" #include "ui/compositor/throughput_tracker.h" namespace ui { @@ -33,45 +30,27 @@ // is going away, it needs to have the same lifetime of the animations to track // the performance. In such case, the owner reporter would drop the ownership // and set set_should_delete() to let the tracker manages its own lifetime -// based on LayerDetroyed and LayerAnimationObserver signals. On the other hand, -// if there are no animations to track, the tracker is released with its owner -// reporter. +// based on LayerAnimationObserver signals. On the other hand, if there are no +// animations to track, the tracker is released with its owner reporter. class AnimationThroughputReporter::AnimationTracker - : public CallbackLayerAnimationObserver, - public LayerObserver { + : public CallbackLayerAnimationObserver { public: - AnimationTracker(Layer* layer, ReportCallback report_callback) + AnimationTracker(LayerAnimator* animator, ReportCallback report_callback) : CallbackLayerAnimationObserver( base::BindRepeating(&AnimationTracker::OnAnimationEnded, base::Unretained(this))), - animator_(layer->GetAnimator()), + animator_(animator), report_callback_(std::move(report_callback)) { DCHECK(report_callback_); - layer_observation_.Observe(layer); } AnimationTracker(const AnimationTracker& other) = delete; AnimationTracker& operator=(const AnimationTracker& other) = delete; - ~AnimationTracker() override { - // No auto delete in the observer callbacks since `this` is being - // destructed. - should_delete_ = false; + ~AnimationTracker() override = default; - // Cancels existing tracking if any. - throughput_tracker_.reset(); - - // Stops observing animations so that `animator` destruction does not call - // back into half destructed `this` if `this` holds the last reference of - // `animator_`. - StopObserving(); - } - - // Whether there are/will be animations to track. That is, there is an - // underlying layer and there are attached animation sequences. - bool HasAnimationsToTrack() const { - return layer_observation_.IsObserving() && !attached_sequences().empty(); - } + // Whether there are/will be animations to track. + bool HasAnimationsToTrack() const { return !attached_sequences().empty(); } void set_should_delete(bool should_delete) { should_delete_ = should_delete; } @@ -115,17 +94,6 @@ CallbackLayerAnimationObserver::OnLayerAnimationAborted(sequence); } - // LayerObserver: - void LayerDestroyed(Layer* layer) override { - DCHECK(layer_observation_.IsObservingSource(layer)); - - layer_observation_.Reset(); - - // No more tracking needed when underlying layer is gone. - if (should_delete_) - delete this; - } - void MaybeStartTracking() { // No tracking if no layer animation sequence is started. if (!first_animation_group_id_.has_value()) @@ -133,13 +101,12 @@ // No tracking if |animator_| is not attached to a timeline. Layer animation // sequence would not tick without a timeline. - if (!AnimationThroughputReporter::IsAnimatorAttachedToTimeline( - animator_.get())) { + if (!AnimationThroughputReporter::IsAnimatorAttachedToTimeline(animator_)) { return; } ui::Compositor* compositor = - AnimationThroughputReporter::GetCompositor(animator_.get()); + AnimationThroughputReporter::GetCompositor(animator_); throughput_tracker_ = compositor->RequestNewThroughputTracker(); throughput_tracker_->Start(report_callback_); } @@ -162,8 +129,7 @@ // Whether this class should delete itself on animation ended. bool should_delete_ = false; - base::ScopedObservation<Layer, LayerObserver> layer_observation_{this}; - scoped_refptr<LayerAnimator> animator_; + LayerAnimator* const animator_; base::Optional<ThroughputTracker> throughput_tracker_; @@ -174,11 +140,11 @@ }; AnimationThroughputReporter::AnimationThroughputReporter( - LayerAnimator* animator, + scoped_refptr<LayerAnimator> animator, ReportCallback report_callback) - : animator_(animator), + : animator_(std::move(animator)), animation_tracker_( - std::make_unique<AnimationTracker>(animator_->delegate()->GetLayer(), + std::make_unique<AnimationTracker>(animator_.get(), std::move(report_callback))) { animator_->AddObserver(animation_tracker_.get()); } @@ -189,6 +155,15 @@ // from the scheduled animation sequences. animator_->observers_.RemoveObserver(animation_tracker_.get()); + // Drop the animator reference. If this is the last reference, the animator + // will be destroyed. When the animator destruction happens, it destroys its + // LayerAnimationSequences and detach observers from them. As a result, + // AnimationTracker::OnAnimationEnded would be called after all animation + // sequences are detached. After this, animator will no longer be accessed + // by AnimationTracker and HasAnimationsToTrack() would correctly report + // that there are no animations to track. + animator_.reset(); + // |animation_tracker_| deletes itself when its tracked animations finish. if (animation_tracker_->HasAnimationsToTrack()) animation_tracker_.release()->set_should_delete(true);
diff --git a/ui/compositor/animation_throughput_reporter.h b/ui/compositor/animation_throughput_reporter.h index 334a9ed..59b728d 100644 --- a/ui/compositor/animation_throughput_reporter.h +++ b/ui/compositor/animation_throughput_reporter.h
@@ -8,6 +8,7 @@ #include <memory> #include "base/callback_forward.h" +#include "base/memory/scoped_refptr.h" #include "cc/metrics/frame_sequence_metrics.h" #include "ui/compositor/compositor_export.h" @@ -37,7 +38,7 @@ public: using ReportCallback = base::RepeatingCallback<void( const cc::FrameSequenceMetrics::CustomReportData&)>; - AnimationThroughputReporter(LayerAnimator* animator, + AnimationThroughputReporter(scoped_refptr<LayerAnimator> animator, ReportCallback report_callback); AnimationThroughputReporter(const AnimationThroughputReporter&) = delete; AnimationThroughputReporter& operator=(const AnimationThroughputReporter&) = @@ -57,7 +58,7 @@ // List here to access LayerAnimation's private |anmation_| member. static bool IsAnimatorAttachedToTimeline(LayerAnimator* animator); - LayerAnimator* const animator_; + scoped_refptr<LayerAnimator> animator_; std::unique_ptr<AnimationTracker> animation_tracker_; };
diff --git a/ui/file_manager/audio_player/manifest.json b/ui/file_manager/audio_player/manifest.json index 113b4da..f92d71c 100644 --- a/ui/file_manager/audio_player/manifest.json +++ b/ui/file_manager/audio_player/manifest.json
@@ -25,7 +25,6 @@ "fileSystem": ["requestFileSystem", "write"] }, "fullscreen", - "mediaPlayerPrivate", "power", "storage", "chrome://resources/",
diff --git a/ui/file_manager/file_manager/manifest.json b/ui/file_manager/file_manager/manifest.json index 5d06b97..b724030 100644 --- a/ui/file_manager/file_manager/manifest.json +++ b/ui/file_manager/file_manager/manifest.json
@@ -36,7 +36,6 @@ "https://drive.google.com/", "https://www.google-analytics.com/", "launcherSearchProvider", - "mediaPlayerPrivate", "metricsPrivate", "notifications", "power",
diff --git a/ui/file_manager/video_player/manifest.json b/ui/file_manager/video_player/manifest.json index c5c1781..8aa42d81 100644 --- a/ui/file_manager/video_player/manifest.json +++ b/ui/file_manager/video_player/manifest.json
@@ -25,7 +25,6 @@ "fileSystem": ["requestFileSystem", "write"] }, "fullscreen", - "mediaPlayerPrivate", "metricsPrivate", "power", "storage",
diff --git a/ui/gtk/gtk_ui.cc b/ui/gtk/gtk_ui.cc index 63f4dbc..9bd557d3 100644 --- a/ui/gtk/gtk_ui.cc +++ b/ui/gtk/gtk_ui.cc
@@ -932,19 +932,14 @@ const std::string header_selector_inactive = header_selector + ":backdrop"; const SkColor frame_color = SkColorSetA(GetBgColor(header_selector), SK_AlphaOPAQUE); - const SkColor frame_color_incognito = - color_utils::HSLShift(frame_color, kDefaultTintFrameIncognito); const SkColor frame_color_inactive = SkColorSetA(GetBgColor(header_selector_inactive), SK_AlphaOPAQUE); - const SkColor frame_color_incognito_inactive = - color_utils::HSLShift(frame_color_inactive, kDefaultTintFrameIncognito); color_map[ThemeProperties::COLOR_FRAME_ACTIVE] = frame_color; color_map[ThemeProperties::COLOR_FRAME_INACTIVE] = frame_color_inactive; - color_map[ThemeProperties::COLOR_FRAME_ACTIVE_INCOGNITO] = - frame_color_incognito; + color_map[ThemeProperties::COLOR_FRAME_ACTIVE_INCOGNITO] = frame_color; color_map[ThemeProperties::COLOR_FRAME_INACTIVE_INCOGNITO] = - frame_color_incognito_inactive; + frame_color_inactive; // Compose the window color on the frame color to ensure the resulting tab // color is opaque. @@ -969,20 +964,12 @@ background_tab_text_color; color_map[ThemeProperties:: COLOR_TAB_FOREGROUND_INACTIVE_FRAME_ACTIVE_INCOGNITO] = - color_utils::BlendForMinContrast( - color_utils::HSLShift(background_tab_text_color, - kDefaultTintFrameIncognito), - frame_color_incognito) - .color; + background_tab_text_color; color_map[ThemeProperties::COLOR_TAB_FOREGROUND_INACTIVE_FRAME_INACTIVE] = background_tab_text_color_inactive; color_map[ThemeProperties:: COLOR_TAB_FOREGROUND_INACTIVE_FRAME_INACTIVE_INCOGNITO] = - color_utils::BlendForMinContrast( - color_utils::HSLShift(background_tab_text_color_inactive, - kDefaultTintFrameIncognito), - frame_color_incognito_inactive) - .color; + background_tab_text_color_inactive; color_map[ThemeProperties::COLOR_OMNIBOX_TEXT] = native_theme_->GetSystemColor(
diff --git a/ui/gtk/gtk_util.cc b/ui/gtk/gtk_util.cc index b5c93b6..c2ea5d2 100644 --- a/ui/gtk/gtk_util.cc +++ b/ui/gtk/gtk_util.cc
@@ -116,11 +116,6 @@ namespace gtk { -// TODO(thomasanderson): ThemeService has a whole interface just for reading -// default constants. Figure out what to do with that more long term; for now, -// just copy the constant itself here. -const color_utils::HSL kDefaultTintFrameIncognito = {-1, 0.2f, 0.35f}; - void GtkInitFromCommandLine(const base::CommandLine& command_line) { CommonInitFromCommandLine(command_line); }
diff --git a/ui/gtk/gtk_util.h b/ui/gtk/gtk_util.h index 1512a55..2625cac 100644 --- a/ui/gtk/gtk_util.h +++ b/ui/gtk/gtk_util.h
@@ -26,18 +26,12 @@ class CommandLine; } -namespace color_utils { -struct HSL; -} - namespace ui { class KeyEvent; } namespace gtk { -extern const color_utils::HSL kDefaultTintFrameIncognito; - void GtkInitFromCommandLine(const base::CommandLine& command_line); // Sets |dialog| as transient for |parent|, which will keep it on top and center
diff --git a/ui/gtk/native_theme_gtk.cc b/ui/gtk/native_theme_gtk.cc index 5964c64..6a864eb 100644 --- a/ui/gtk/native_theme_gtk.cc +++ b/ui/gtk/native_theme_gtk.cc
@@ -9,7 +9,6 @@ #include "ui/gfx/color_palette.h" #include "ui/gfx/color_utils.h" #include "ui/gfx/geometry/rect.h" -#include "ui/gfx/skbitmap_operations.h" #include "ui/gfx/skia_util.h" #include "ui/gtk/gtk_util.h" @@ -711,13 +710,7 @@ SkBitmap bitmap = GetWidgetBitmap(rect.size(), context, BG_RENDER_RECURSIVE, false); - - if (frame_top_area.incognito) { - bitmap = SkBitmapOperations::CreateHSLShiftedBitmap( - bitmap, kDefaultTintFrameIncognito); - bitmap.setImmutable(); - } - + bitmap.setImmutable(); canvas->drawImage(cc::PaintImage::CreateFromBitmap(std::move(bitmap)), rect.x(), rect.y()); }
diff --git a/ui/native_theme/native_theme.h b/ui/native_theme/native_theme.h index 3df3fb35..d254838cfb 100644 --- a/ui/native_theme/native_theme.h +++ b/ui/native_theme/native_theme.h
@@ -172,7 +172,6 @@ // Distinguishes between active (foreground) and inactive // (background) window frame styles. bool is_active; - bool incognito; // True when Chromium renders the titlebar. False when the window // manager renders the titlebar. bool use_custom_frame;
diff --git a/ui/views/controls/menu/menu_host.cc b/ui/views/controls/menu/menu_host.cc index 19bb2bf..10612078 100644 --- a/ui/views/controls/menu/menu_host.cc +++ b/ui/views/controls/menu/menu_host.cc
@@ -20,6 +20,7 @@ #include "ui/views/controls/menu/menu_scroll_view_container.h" #include "ui/views/controls/menu/submenu_view.h" #include "ui/views/round_rect_painter.h" +#include "ui/views/views_delegate.h" #include "ui/views/widget/native_widget_private.h" #include "ui/views/widget/widget.h" #include "ui/views/widget/widget_delegate.h" @@ -235,6 +236,10 @@ void MenuHost::OnMouseCaptureLost() { if (destroying_ || ignore_capture_lost_) return; + + if (!ViewsDelegate::GetInstance()->ShouldCloseMenuIfMouseCaptureLost()) + return; + MenuController* menu_controller = submenu_->GetMenuItem()->GetMenuController(); if (menu_controller && !menu_controller->drag_in_progress())
diff --git a/ui/views/views_delegate.cc b/ui/views/views_delegate.cc index e9e7458..6e5bd4f 100644 --- a/ui/views/views_delegate.cc +++ b/ui/views/views_delegate.cc
@@ -73,6 +73,10 @@ return ProcessMenuAcceleratorResult::LEAVE_MENU_OPEN; } +bool ViewsDelegate::ShouldCloseMenuIfMouseCaptureLost() const { + return true; +} + #if defined(OS_WIN) HICON ViewsDelegate::GetDefaultWindowIcon() const { return nullptr;
diff --git a/ui/views/views_delegate.h b/ui/views/views_delegate.h index a28f8caf..87328d7 100644 --- a/ui/views/views_delegate.h +++ b/ui/views/views_delegate.h
@@ -125,6 +125,10 @@ virtual ProcessMenuAcceleratorResult ProcessAcceleratorWhileMenuShowing( const ui::Accelerator& accelerator); + // If a menu is showing and its window loses mouse capture, it will close if + // this returns true. + virtual bool ShouldCloseMenuIfMouseCaptureLost() const; + #if defined(OS_WIN) // Retrieves the default window icon to use for windows if none is specified. virtual HICON GetDefaultWindowIcon() const;
diff --git a/ui/views/widget/root_view.cc b/ui/views/widget/root_view.cc index 3911450..073d0b1 100644 --- a/ui/views/widget/root_view.cc +++ b/ui/views/widget/root_view.cc
@@ -13,6 +13,7 @@ #include "build/build_config.h" #include "ui/accessibility/ax_enums.mojom.h" #include "ui/accessibility/ax_node_data.h" +#include "ui/accessibility/platform/ax_platform_node.h" #include "ui/base/cursor/cursor.h" #include "ui/base/dragdrop/mojom/drag_drop_types.mojom-shared.h" #include "ui/base/ui_base_switches_util.h" @@ -21,6 +22,7 @@ #include "ui/events/event_utils.h" #include "ui/events/keycodes/keyboard_codes.h" #include "ui/gfx/canvas.h" +#include "ui/views/accessibility/view_accessibility.h" #include "ui/views/drag_controller.h" #include "ui/views/metadata/metadata_impl_macros.h" #include "ui/views/view_class_properties.h" @@ -261,9 +263,10 @@ void RootView::AnnounceText(const base::string16& text) { #if defined(OS_APPLE) - // MacOSX has its own API for making announcements; see AnnounceText() - // override in ax_platform_node_mac.[h|mm] - NOTREACHED(); + gfx::NativeViewAccessible native = GetViewAccessibility().GetNativeObject(); + auto* ax_node = ui::AXPlatformNode::FromNativeViewAccessible(native); + if (ax_node) + ax_node->AnnounceText(text); #else DCHECK(GetWidget()); DCHECK(GetContentsView());
diff --git a/ui/views/window/custom_frame_view.cc b/ui/views/window/custom_frame_view.cc index e046978d..2eb97a08 100644 --- a/ui/views/window/custom_frame_view.cc +++ b/ui/views/window/custom_frame_view.cc
@@ -192,7 +192,6 @@ frame_background_->set_frame_color(GetFrameColor()); frame_background_->set_use_custom_frame(true); frame_background_->set_is_active(ShouldPaintAsActive()); - frame_background_->set_incognito(false); const gfx::ImageSkia frame_image = GetFrameImage(); frame_background_->set_theme_image(frame_image); frame_background_->set_top_area_height(frame_image.height());
diff --git a/ui/views/window/frame_background.cc b/ui/views/window/frame_background.cc index 50e11d3..6a26e3f 100644 --- a/ui/views/window/frame_background.cc +++ b/ui/views/window/frame_background.cc
@@ -105,7 +105,6 @@ ui::NativeTheme::ExtraParams params; params.frame_top_area.use_custom_frame = use_custom_frame_; params.frame_top_area.is_active = is_active_; - params.frame_top_area.incognito = incognito_; params.frame_top_area.default_background_color = frame_color_; native_theme->Paint(canvas->sk_canvas(), ui::NativeTheme::kFrameTopArea, ui::NativeTheme::kNormal,
diff --git a/ui/views/window/frame_background.h b/ui/views/window/frame_background.h index ece082a..bf5b4e0 100644 --- a/ui/views/window/frame_background.h +++ b/ui/views/window/frame_background.h
@@ -36,9 +36,6 @@ // Sets whether the frame to be drawn should have focus. void set_is_active(bool is_active) { is_active_ = is_active; } - // Sets whether the frame to be drawn is in incognito mode. - void set_incognito(bool incognito) { incognito_ = incognito; } - // Sets the theme image for the top of the window. May be null (empty). // Memory is owned by the caller. void set_theme_image(const gfx::ImageSkia& image) { theme_image_ = image; } @@ -90,7 +87,6 @@ SkColor frame_color_ = 0; bool use_custom_frame_ = true; bool is_active_ = true; - bool incognito_ = false; gfx::ImageSkia theme_image_; int theme_image_y_inset_ = 0; gfx::ImageSkia theme_overlay_image_;
diff --git a/ui/webui/resources/cr_components/chromeos/network_health/network_diagnostics.html b/ui/webui/resources/cr_components/chromeos/network_health/network_diagnostics.html index 34cad29..9acf444 100644 --- a/ui/webui/resources/cr_components/chromeos/network_health/network_diagnostics.html +++ b/ui/webui/resources/cr_components/chromeos/network_health/network_diagnostics.html
@@ -26,6 +26,10 @@ <routine-group name="[[i18n('NetworkDiagnosticsDnsGroup')]]" routines="[[getRoutineGroup_(routines_.*, RoutineGroup_.DNS)]]"> </routine-group> + <routine-group name="[[i18n('NetworkDiagnosticsGoogleServicesGroup')]]" + routines= + "[[getRoutineGroup_(routines_.*, RoutineGroup_.GOOGLE_SERVICES)]]"> + </routine-group> </template> <script src="network_diagnostics.js"></script> </dom-module>
diff --git a/ui/webui/resources/cr_components/chromeos/network_health/network_diagnostics.js b/ui/webui/resources/cr_components/chromeos/network_health/network_diagnostics.js index f2b97dc..a721ccb 100644 --- a/ui/webui/resources/cr_components/chromeos/network_health/network_diagnostics.js +++ b/ui/webui/resources/cr_components/chromeos/network_health/network_diagnostics.js
@@ -131,6 +131,18 @@ }, ] }, + { + group: RoutineGroup.GOOGLE_SERVICES, + routines: [ + { + name: 'NetworkDiagnosticsVideoConferencing', + type: RoutineType.VIDEO_CONFERENCING, + // A null stun_server_hostname will use the routine default. + func: () => this.networkDiagnostics_.videoConferencing( + /*stun_server_hostname=*/ null), + }, + ] + }, ]; const routines = []; @@ -467,6 +479,22 @@ problemStrings.push(getString('CaptivePortalProblem_NoInternet')); break; } + + case RoutineType.VIDEO_CONFERENCING: + switch (problem) { + case diagnosticsMojom.VideoConferencingProblem.kUdpFailure: + problemStrings.push( + getString('VideoConferencingProblem_UdpFailure')); + break; + case diagnosticsMojom.VideoConferencingProblem.kTcpFailure: + problemStrings.push( + getString('VideoConferencingProblem_TcpFailure')); + break; + case diagnosticsMojom.VideoConferencingProblem.kMediaFailure: + problemStrings.push( + getString('VideoConferencingProblem_MediaFailure')); + break; + } } }
diff --git a/ui/webui/resources/cr_components/chromeos/network_health/network_diagnostics_types.js b/ui/webui/resources/cr_components/chromeos/network_health/network_diagnostics_types.js index 3696fff..e67a463 100644 --- a/ui/webui/resources/cr_components/chromeos/network_health/network_diagnostics_types.js +++ b/ui/webui/resources/cr_components/chromeos/network_health/network_diagnostics_types.js
@@ -55,6 +55,7 @@ HTTPS_FIREWALL: 8, HTTPS_LATENCY: 9, CAPTIVE_PORTAL: 10, + VIDEO_CONFERENCING: 11, }; /** @@ -68,6 +69,7 @@ GATEWAY: 3, FIREWALL: 4, DNS: 5, + GOOGLE_SERVICES: 6, }; /* #export */ const Icons = {
diff --git a/ui/webui/resources/js/list_property_update_behavior.js b/ui/webui/resources/js/list_property_update_behavior.js index 6812f541..6ac160b 100644 --- a/ui/webui/resources/js/list_property_update_behavior.js +++ b/ui/webui/resources/js/list_property_update_behavior.js
@@ -21,44 +21,60 @@ /* #export */ const ListPropertyUpdateBehavior = { /** * @param {string} propertyPath - * @param {function(!Object): string} itemUidGetter + * @param {function(!Object): (!Object|string)} identityGetter * @param {!Array<!Object>} updatedList - * @param {boolean} uidBasedUpdate + * @param {boolean=} identityBasedUpdate * @returns {boolean} True if notifySplices was called. */ - updateList(propertyPath, itemUidGetter, updatedList, uidBasedUpdate = false) { - const list = this.get(propertyPath); - const splices = Polymer.ArraySplice.calculateSplices( - updatedList.map(itemUidGetter), list.map(itemUidGetter)); - - splices.forEach(splice => { - const index = splice.index; - const deleteCount = splice.removed.length; - // Transform splices to the expected format of notifySplices(). - // Convert !Array<string> to !Array<!Object>. - splice.removed = list.slice(index, index + deleteCount); - splice.object = list; - splice.type = 'splice'; - - const added = updatedList.slice(index, index + splice.addedCount); - const spliceParams = [index, deleteCount].concat(added); - list.splice.apply(list, spliceParams); - }); - - let updated = splices.length > 0; - if (!uidBasedUpdate) { - list.forEach((item, index) => { - const updatedItem = updatedList[index]; - if (JSON.stringify(item) !== JSON.stringify(updatedItem)) { - this.set([propertyPath, index], updatedItem); - updated = true; - } - }); - } - - if (splices.length > 0) { - this.notifySplices(propertyPath, splices); - } - return updated; + updateList( + propertyPath, identityGetter, updatedList, identityBasedUpdate = false) { + return updateListProperty( + this, propertyPath, identityGetter, updatedList, identityBasedUpdate); }, }; + +/** + * @param {Object} instance + * @param {string} propertyPath + * @param {function(!Object): (!Object|string)} identityGetter + * @param {!Array<!Object>} updatedList + * @param {boolean=} identityBasedUpdate + * @returns {boolean} True if notifySplices was called. + */ +/* #export */ function updateListProperty( + instance, propertyPath, identityGetter, updatedList, + identityBasedUpdate = false) { + const list = instance.get(propertyPath); + const splices = Polymer.ArraySplice.calculateSplices( + updatedList.map(identityGetter), list.map(identityGetter)); + + splices.forEach(splice => { + const index = splice.index; + const deleteCount = splice.removed.length; + // Transform splices to the expected format of notifySplices(). + // Convert !Array<string> to !Array<!Object>. + splice.removed = list.slice(index, index + deleteCount); + splice.object = list; + splice.type = 'splice'; + + const added = updatedList.slice(index, index + splice.addedCount); + const spliceParams = [index, deleteCount].concat(added); + list.splice.apply(list, spliceParams); + }); + + let updated = splices.length > 0; + if (!identityBasedUpdate) { + list.forEach((item, index) => { + const updatedItem = updatedList[index]; + if (JSON.stringify(item) !== JSON.stringify(updatedItem)) { + instance.set([propertyPath, index], updatedItem); + updated = true; + } + }); + } + + if (splices.length > 0) { + instance.notifySplices(propertyPath, splices); + } + return updated; +}
diff --git a/url/origin_unittest.cc b/url/origin_unittest.cc index 26f9c37..97100ef 100644 --- a/url/origin_unittest.cc +++ b/url/origin_unittest.cc
@@ -229,8 +229,14 @@ "local-but-nonstandar:foo", // Prefix of registered scheme. "but-nonstandard:foo", // Suffix of registered scheme. "local-and-standard:", // Standard scheme needs a hostname. - "standard-but-noaccess:", // Standard scheme needs a hostname. "blob:blob:http://www.example.com/guid-goes-here", // Double blob. + + // Scheme (registered in SetUp()) that's standard but marked as noaccess. + // See also SecurityOriginTest.StandardNoAccessScheme and + // NavigationUrlRewriteBrowserTest.RewriteToNoAccess. + "standard-but-noaccess:", // Standard scheme needs a hostname. + "standard-but-noaccess:foo", // Standard scheme needs a hostname. + "standard-but-noaccess://bar", }; for (auto* test_url : urls) { @@ -349,12 +355,6 @@ {"local-but-nonstandard://bar", "local-but-nonstandard", "", 0}, {"also-local-but-nonstandard://bar", "also-local-but-nonstandard", "", 0}, - // Scheme (registered in SetUp()) that's standard but marked as noaccess. - // url::Origin doesn't currently take the noaccess property into account, - // so these aren't expected to result in opaque origins. - {"standard-but-noaccess:foo", "standard-but-noaccess", "foo", 0}, - {"standard-but-noaccess://bar", "standard-but-noaccess", "bar", 0}, - // file: URLs {"file:///etc/passwd", "file", "", 0}, {"file://example.com/etc/passwd", "file", "example.com", 0}, @@ -814,10 +814,10 @@ {"standard-but-noaccess://a.com/foo", ®ular_origin, false}, {"standard-but-noaccess://a.com/foo", &opaque_precursor_origin, false}, {"standard-but-noaccess://a.com/foo", &opaque_unique_origin, true}, - {"standard-but-noaccess://a.com/foo", &no_access_origin, false}, + {"standard-but-noaccess://a.com/foo", &no_access_origin, true}, {"standard-but-noaccess://a.com/foo", &no_access_opaque_precursor_origin, - false}, - {"standard-but-noaccess://b.com/foo", &no_access_origin, false}, + true}, + {"standard-but-noaccess://b.com/foo", &no_access_origin, true}, {"standard-but-noaccess://b.com/foo", &no_access_opaque_precursor_origin, true},
diff --git a/url/scheme_host_port.cc b/url/scheme_host_port.cc index 233c2923..61239b1 100644 --- a/url/scheme_host_port.cc +++ b/url/scheme_host_port.cc
@@ -49,6 +49,10 @@ return host == canon_host; } +// Note: When changing IsValidInput, consider also updating +// ShouldTreatAsOpaqueOrigin in Blink (there might be existing differences in +// behavior between these 2 layers, but we should avoid introducing new +// differences). bool IsValidInput(const base::StringPiece& scheme, const base::StringPiece& host, uint16_t port, @@ -57,25 +61,27 @@ if (scheme.empty()) return false; + // about:blank and other no-access schemes translate into an opaque origin. + // This helps consistency with ShouldTreatAsOpaqueOrigin in Blink. + if (base::Contains(GetNoAccessSchemes(), scheme)) + return false; + SchemeType scheme_type = SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION; bool is_standard = GetStandardSchemeType( scheme.data(), Component(0, base::checked_cast<int>(scheme.length())), &scheme_type); if (!is_standard) { - // To be consistent with blink, local non-standard schemes are currently - // allowed to be tuple origins. Nonstandard schemes don't have hostnames, - // so their tuple is just ("protocol", "", 0). + // To be consistent with ShouldTreatAsOpaqueOrigin in Blink, local + // non-standard schemes are currently allowed to be tuple origins. + // Nonstandard schemes don't have hostnames, so their tuple is just + // ("protocol", "", 0). // // TODO: Migrate "content:" and "externalfile:" to be standard schemes, and // remove this local scheme exception. if (base::Contains(GetLocalSchemes(), scheme) && host.empty() && port == 0) return true; - // about:blank and other no-access schemes translate into an opaque origin. - if (base::Contains(GetNoAccessSchemes(), scheme)) - return false; - // Otherwise, allow non-standard schemes only if the Android WebView // workaround is enabled. return AllowNonStandardSchemesForAndroidWebView();
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/INavigation.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/INavigation.aidl index 9787b7e..60824cf 100644 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/INavigation.aidl +++ b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/INavigation.aidl
@@ -38,5 +38,7 @@ boolean isUserDecidingIntentLaunch() = 14; boolean isKnownProtocol() = 15; boolean isServedFromBackForwardCache() = 16; + + // @since 88 void disableNetworkErrorAutoReload() = 17; }
diff --git a/weblayer/public/java/org/chromium/weblayer/NavigateParams.java b/weblayer/public/java/org/chromium/weblayer/NavigateParams.java index 0fc051ad..ea6dfed 100644 --- a/weblayer/public/java/org/chromium/weblayer/NavigateParams.java +++ b/weblayer/public/java/org/chromium/weblayer/NavigateParams.java
@@ -64,7 +64,7 @@ /** * Disables auto-reload for this navigation if the network is down and comes back later. - * Auto-reload is enabled by default. This is deprecated as of 89, instead use + * Auto-reload is enabled by default. This is deprecated as of 88, instead use * {@link Navigation#disableNetworkErrorAutoReload} which works for both embedder-initiated * navigations and also user-initiated navigations (such as back or forward). Auto-reload * is disabled if either method is called.
diff --git a/weblayer/public/java/org/chromium/weblayer/Navigation.java b/weblayer/public/java/org/chromium/weblayer/Navigation.java index 4b11aa66..ca637951 100644 --- a/weblayer/public/java/org/chromium/weblayer/Navigation.java +++ b/weblayer/public/java/org/chromium/weblayer/Navigation.java
@@ -261,12 +261,12 @@ * * @throws IllegalStateException If not called during start. * - * @since 89 + * @since 88 */ public void disableNetworkErrorAutoReload() { ThreadCheck.ensureOnUiThread(); if (WebLayer.shouldPerformVersionChecks() - && WebLayer.getSupportedMajorVersionInternal() < 89) { + && WebLayer.getSupportedMajorVersionInternal() < 88) { throw new UnsupportedOperationException(); } try {
diff --git a/weblayer/variables.gni b/weblayer/variables.gni index d84b100..0cb57fe 100644 --- a/weblayer/variables.gni +++ b/weblayer/variables.gni
@@ -9,7 +9,7 @@ webview_includes_weblayer = true # Whether WebLayer will be included as a DFM. - weblayer_in_split = android_channel != "stable" + weblayer_in_split = true } weblayer_product_config_java_package = "org.chromium.weblayer_private"