diff --git a/.gn b/.gn index 00cb71c..1c7897a 100644 --- a/.gn +++ b/.gn
@@ -65,7 +65,7 @@ no_check_targets = [ "//extensions/browser:*", # 20 errors "//extensions:*", # 28 errors - "//headless:*", # 167 errors + "//headless:*", # 107 errors "//ppapi/proxy:ipc_sources", # 13 errors "//ppapi/thunk:*", # 1071 errors "//remoting/host/security_key:*", # 10 errors
diff --git a/DEPS b/DEPS index b6499a8..580fa9f 100644 --- a/DEPS +++ b/DEPS
@@ -222,11 +222,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '224e3e257d06370581aed9e2450255a45c398362', + 'skia_revision': '7729e0a97ec36a34207ca74c1dde8136c6b89724', # 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': 'e1e303b9c19734fe54a459cb18fd496fe4518db8', + 'v8_revision': '2517643909a0743cdc0e6a487f1ca4e4f41e8bd6', # 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. @@ -293,7 +293,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': '3345f09ed65020a999e108ea37d30b49c87e14ed', + 'catapult_revision': '25ef034fbef738c4ff017d1ab1c42d7a6fad6a7f', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -301,7 +301,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling devtools-frontend # and whatever else without interference from each other. - 'devtools_frontend_revision': 'dfc8e51395fb91b0a4726a7dd2e2492c049df698', + 'devtools_frontend_revision': '517808797a7e612cc75202b0bcdd274b8d1f6b66', # 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. @@ -341,7 +341,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': '2103fa629e98a30b2c5e93bcc002e40cbd3f6d5f', + 'dawn_revision': 'f1c76f5dfe0669c2fb00a3a9b0a78f4b0788c465', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -385,11 +385,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. - 'libcxxabi_revision': 'cb34896ebd62f93f708ff9aad26159cf11dde6f4', + 'libcxxabi_revision': '6803464b0f46df0a51862347d39e0791b59cf568', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'libunwind_revision': 'e7ac0f84fc2f2f8bd2ad151a7348e7120d77648a', + 'libunwind_revision': 'a5feaf61658af4453e282142a76aeb6f9c045311', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -738,7 +738,7 @@ 'packages': [ { 'package': 'chromium/third_party/androidx', - 'version': '-umIXLPTAdxRy2iaK4QFSeOf4t7PAKglJP7ggvWhfRwC', + 'version': '_WEcXceOuK2XsUUyrM5doOfE06y8TtpBiamn4PkQp1YC', }, ], 'condition': 'checkout_android', @@ -954,7 +954,7 @@ # Tools used when building Chrome for Chrome OS. This affects both the Simple # Chrome workflow, as well as the chromeos-chrome ebuild. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'bb2bbaee0f48a65f562b01bedb0b93ba1a07f7da', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '7a515fb8020d3dd83999cab59923a70b890d46b8', 'condition': 'checkout_chromeos', }, @@ -1360,7 +1360,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + 'aecbd80f576686b67e29bdfae8c9c03bb9ce1996', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '51a1443c7cb98f1fd50e1bb87c183704b4f5c81b', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1553,7 +1553,7 @@ 'src/third_party/usrsctp/usrsctplib': Var('chromium_git') + '/external/github.com/sctplab/usrsctp' + '@' + '1ade45cbadfd19298d2c47dc538962d4425ad2dd', - 'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@36456846a4affb738fc3f012cc8f1c8c86ef0595', + 'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@bbd1a7b068ea2dfdda9910f1447147ff69e800cb', 'src/third_party/vulkan_memory_allocator': Var('chromium_git') + '/external/github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git' + '@' + 'f67d7fa397e83060b76a1ec53579116a0bbdff7a', @@ -1592,7 +1592,7 @@ Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + 'e2aeec9de7a742ae131b2f56fc22de6b17b8d0e1', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '76b0c2ce47347184fa051870234bd7698ab30f3e', + Var('webrtc_git') + '/src.git' + '@' + '51969310ef432a9c340bb091eea1f1553ca01587', 'src/third_party/libgifcodec': Var('skia_git') + '/libgifcodec' + '@'+ Var('libgifcodec_revision'), @@ -1683,7 +1683,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/media_app/app', - 'version': 'zYE4hb3r66pj55eKLN8KCScYBEIB4-LivvEUMOr7XG0C', + 'version': '4-IHCJ0juqQPEOL75uZN5C4bzT97E1hEJUh8masGfAEC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/WATCHLISTS b/WATCHLISTS index 5ca9249d..b3eead39 100644 --- a/WATCHLISTS +++ b/WATCHLISTS
@@ -2194,8 +2194,7 @@ 'blink_animation': ['alexis.menard@intel.com', 'gerchiko@microsoft.com', 'blink-reviews-animation@chromium.org'], - 'blink_audio': ['hongchan@chromium.org', - 'rtoy@chromium.org'], + 'blink_audio': ['hongchan@chromium.org'], 'blink_battery_status': ['timvolodine@chromium.org'], 'blink_bindings': ['blink-reviews-bindings@chromium.org', 'haraken@chromium.org'], 'blink_bindings_serialization': ['jbroman+watch@chromium.org'], @@ -2351,8 +2350,7 @@ 'pmonette+watch@chromium.org'], 'chrome_grc': ['chrome-grc-reviews@chromium.org'], 'chrome_performance_manager': ['performance-manager-reviews@chromium.org'], - 'chromecast': ['alokp+watch@chromium.org', - 'halliwell+watch@chromium.org', + 'chromecast': ['halliwell+watch@chromium.org', 'lcwu+watch@chromium.org'], 'chromecast_public': ['gfhuang+watch@chromium.org'], 'chromedriver': ['mathias@chromium.org'], @@ -2587,8 +2585,7 @@ 'media_gpu_cros': ['media-cros-reviews@chromium.org'], 'media_gpu_vaapi': ['vaapi-reviews@chromium.org'], 'media_gpu_win': ['media-win-reviews@chromium.org'], - 'media_mojo': ['alokp+watch@chromium.org', - 'xhwang+watch@chromium.org'], + 'media_mojo': ['xhwang+watch@chromium.org'], 'media_recorder': ['emircan+watch+mediarecorder@chromium.org', 'mcasas+mediarecorder@chromium.org'], 'media_remoting': ['erickung+watch@chromium.org',
diff --git a/android_webview/browser/component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy.h b/android_webview/browser/component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy.h index ca0f3e0e..5c839a6 100644 --- a/android_webview/browser/component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy.h +++ b/android_webview/browser/component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy.h
@@ -20,6 +20,7 @@ namespace base { class DictionaryValue; +class Time; class Version; } // namespace base
diff --git a/ash/accessibility/accessibility_controller_impl.cc b/ash/accessibility/accessibility_controller_impl.cc index b8a3065c6..4080621 100644 --- a/ash/accessibility/accessibility_controller_impl.cc +++ b/ash/accessibility/accessibility_controller_impl.cc
@@ -1758,7 +1758,7 @@ const base::DictionaryValue* key_codes_pref = active_user_prefs_->GetDictionary(pref_key); std::map<int, std::set<std::string>> key_codes; - for (const auto& v : key_codes_pref->DictItems()) { + for (const auto v : key_codes_pref->DictItems()) { int key_code; if (!base::StringToInt(v.first, &key_code)) { NOTREACHED();
diff --git a/ash/accessibility/ui/accessibility_layer.cc b/ash/accessibility/ui/accessibility_layer.cc index 725c5689..64a6406 100644 --- a/ash/accessibility/ui/accessibility_layer.cc +++ b/ash/accessibility/ui/accessibility_layer.cc
@@ -87,7 +87,7 @@ display::Screen::GetScreen()->GetDisplayMatching(bounds); ui::Compositor* compositor = root_window->layer()->GetCompositor(); if (compositor && !animation_observation_.IsObservingSource(compositor)) { - animation_observation_.Reset(); + Reset(); animation_observation_.Observe(compositor); } } @@ -101,13 +101,23 @@ } void AccessibilityLayer::OnAnimationStep(base::TimeTicks timestamp) { - if (delegate_->OnAnimationStep(timestamp)) - animation_observation_.Reset(); + if (!delegate_->OnAnimationStep(timestamp) || + !animation_observation_.IsObserving()) { + return; + } + + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::BindOnce(&AccessibilityLayer::Reset, weak_factory_.GetWeakPtr())); } void AccessibilityLayer::OnCompositingShuttingDown(ui::Compositor* compositor) { if (compositor && animation_observation_.IsObservingSource(compositor)) - animation_observation_.Reset(); + Reset(); +} + +void AccessibilityLayer::Reset() { + animation_observation_.Reset(); } } // namespace ash
diff --git a/ash/accessibility/ui/accessibility_layer.h b/ash/accessibility/ui/accessibility_layer.h index 8e84a2c..936457c 100644 --- a/ash/accessibility/ui/accessibility_layer.h +++ b/ash/accessibility/ui/accessibility_layer.h
@@ -102,6 +102,9 @@ void OnAnimationStep(base::TimeTicks timestamp) override; void OnCompositingShuttingDown(ui::Compositor* compositor) override; + // Reset internal observation and state. + void Reset(); + // The object that owns this layer. AccessibilityLayerDelegate* delegate_; @@ -111,6 +114,8 @@ &ui::Compositor::RemoveAnimationObserver> animation_observation_{this}; + base::WeakPtrFactory<AccessibilityLayer> weak_factory_{this}; + DISALLOW_COPY_AND_ASSIGN(AccessibilityLayer); };
diff --git a/ash/app_list/views/apps_container_view.cc b/ash/app_list/views/apps_container_view.cc index 577d1eab..abb8d23 100644 --- a/ash/app_list/views/apps_container_view.cc +++ b/ash/app_list/views/apps_container_view.cc
@@ -58,8 +58,8 @@ // The opacity the apps container UI should have when shown on non apps page UI. constexpr float kNonAppsStateOpacity = 0.1; -// The horizontal margin within the apps container for app list folder view. -constexpr int kFolderHorizontalMargin = 8; +// The margins within the apps container for app list folder view. +constexpr int kFolderMargin = 8; } // namespace @@ -271,8 +271,8 @@ // Set bounding box for the folder view - the folder may overlap with // suggestion chips, but not the search box. gfx::Rect folder_bounding_box = rect; - folder_bounding_box.set_y(chip_container_rect.y()); - folder_bounding_box.Inset(kFolderHorizontalMargin, 0); + folder_bounding_box.Inset(kFolderMargin, chip_container_rect.y(), + kFolderMargin, kFolderMargin); app_list_folder_view_->SetBoundingBox(folder_bounding_box); // Leave the same available bounds for the apps grid view in both @@ -282,7 +282,6 @@ rect.set_height(rect.height() - GetExpectedSuggestionChipY(kAppListFullscreenProgressValue) - chip_container_rect.height()); - const GridLayout grid_layout = CalculateGridLayout(); apps_grid_view_->SetLayout(grid_layout.columns, grid_layout.rows);
diff --git a/ash/display/display_prefs.cc b/ash/display/display_prefs.cc index b583b6e..4287a69 100644 --- a/ash/display/display_prefs.cc +++ b/ash/display/display_prefs.cc
@@ -200,7 +200,7 @@ GetDisplayManager()->layout_store(); const base::Value* layouts = local_state->Get(prefs::kSecondaryDisplays); - for (const auto& it : layouts->DictItems()) { + for (const auto it : layouts->DictItems()) { std::unique_ptr<display::DisplayLayout> layout(new display::DisplayLayout); if (!display::JsonToDisplayLayout(it.second, layout.get())) { LOG(WARNING) << "Invalid preference value for " << it.first; @@ -226,7 +226,7 @@ void LoadDisplayProperties(PrefService* local_state) { const base::Value* properties = local_state->Get(prefs::kDisplayProperties); - for (const auto& it : properties->DictItems()) { + for (const auto it : properties->DictItems()) { const base::DictionaryValue* dict_value = nullptr; if (!it.second.GetAsDictionary(&dict_value) || dict_value == nullptr) continue; @@ -300,7 +300,7 @@ DCHECK(properties->is_dict()); display::TouchDeviceManager::TouchAssociationMap touch_associations; - for (const auto& item : properties->DictItems()) { + for (const auto item : properties->DictItems()) { uint32_t identifier_raw; if (!base::StringToUint(item.first, &identifier_raw)) continue; @@ -309,7 +309,7 @@ identifier, display::TouchDeviceManager::AssociationInfoMap()); if (!item.second.is_dict()) continue; - for (const auto& association_info_item : item.second.DictItems()) { + for (const auto association_info_item : item.second.DictItems()) { display::TouchDeviceManager::TouchAssociationInfo info; int64_t display_id; if (!base::StringToInt64(association_info_item.first, &display_id)) @@ -337,7 +337,7 @@ const display::TouchDeviceIdentifier& fallback_identifier = display::TouchDeviceIdentifier::GetFallbackTouchDeviceIdentifier(); properties = local_state->Get(prefs::kDisplayProperties); - for (const auto& it : properties->DictItems()) { + for (const auto it : properties->DictItems()) { const base::DictionaryValue* dict_value = nullptr; if (!it.second.GetAsDictionary(&dict_value) || dict_value == nullptr) continue; @@ -366,7 +366,7 @@ // Retrieve port association information. properties = local_state->Get(prefs::kDisplayTouchPortAssociations); display::TouchDeviceManager::PortAssociationMap port_associations; - for (const auto& item : properties->DictItems()) { + for (const auto item : properties->DictItems()) { // Retrieve the secondary id that identifies the port. uint32_t secondary_id_raw; if (!base::StringToUint(item.first, &secondary_id_raw))
diff --git a/ash/quick_pair/BUILD.gn b/ash/quick_pair/BUILD.gn index 7eed7ab..7c23b87 100644 --- a/ash/quick_pair/BUILD.gn +++ b/ash/quick_pair/BUILD.gn
@@ -12,6 +12,7 @@ "//ash/quick_pair/common", "//ash/quick_pair/feature_status_tracker", "//ash/quick_pair/keyed_service", + "//ash/quick_pair/repository", "//ash/quick_pair/scanning", "//ash/quick_pair/ui", ]
diff --git a/ash/quick_pair/repository/BUILD.gn b/ash/quick_pair/repository/BUILD.gn new file mode 100644 index 0000000..de88f01 --- /dev/null +++ b/ash/quick_pair/repository/BUILD.gn
@@ -0,0 +1,23 @@ +# Copyright 2021 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//build/config/chromeos/ui_mode.gni") + +assert(is_chromeos_ash, + "Quick Pair protocols (e.g. Fast Pair) are ash-chrome only") + +source_set("repository") { + sources = [ + "fast_pair_device_metadata_service.cc", + "fast_pair_device_metadata_service.h", + ] + + deps = [ + "//ash/quick_pair/common", + "//ash/quick_pair/proto:fastpair_proto", + "//base", + "//device/bluetooth", + "//third_party/grpc:grpc++", + ] +}
diff --git a/ash/quick_pair/repository/fast_pair_device_metadata_service.cc b/ash/quick_pair/repository/fast_pair_device_metadata_service.cc new file mode 100644 index 0000000..0df7fe3 --- /dev/null +++ b/ash/quick_pair/repository/fast_pair_device_metadata_service.cc
@@ -0,0 +1,51 @@ +// 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/quick_pair/repository/fast_pair_device_metadata_service.h" + +#include "ash/quick_pair/common/logging.h" +#include "device/bluetooth/bluetooth_device.h" + +namespace ash { +namespace quick_pair { + +FastPairDeviceMetadataService::FastPairDeviceMetadataService() = default; +FastPairDeviceMetadataService::~FastPairDeviceMetadataService() = default; + +void FastPairDeviceMetadataService::GetDeviceMetadata( + const std::string& hex_model_id, + base::OnceCallback<void(absl::optional<nearby::fastpair::Device>)> + callback) { + QP_LOG(INFO) << __func__; + std::move(callback).Run(absl::nullopt); +} + +void FastPairDeviceMetadataService::IsValidModelId( + const std::string& hex_model_id, + base::OnceCallback<void(bool)> callback) { + QP_LOG(INFO) << __func__; + std::move(callback).Run(false); +} + +void FastPairDeviceMetadataService::GetAssociatedAccountKey( + const std::string& address, + const std::string& account_key_filter, + base::OnceCallback<void(absl::optional<std::string>)> callback) { + QP_LOG(INFO) << __func__; + std::move(callback).Run(absl::nullopt); +} + +void FastPairDeviceMetadataService::AssociateAccountKey( + const Device& device, + const std::string& account_key) { + QP_LOG(INFO) << __func__; +} + +void FastPairDeviceMetadataService::DeleteAssociatedDevice( + const device::BluetoothDevice* device) { + QP_LOG(INFO) << __func__; +} + +} // namespace quick_pair +} // namespace ash
diff --git a/ash/quick_pair/repository/fast_pair_device_metadata_service.h b/ash/quick_pair/repository/fast_pair_device_metadata_service.h new file mode 100644 index 0000000..b1c079f --- /dev/null +++ b/ash/quick_pair/repository/fast_pair_device_metadata_service.h
@@ -0,0 +1,62 @@ +// 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 ASH_QUICK_PAIR_REPOSITORY_FAST_PAIR_DEVICE_METADATA_SERVICE_H_ +#define ASH_QUICK_PAIR_REPOSITORY_FAST_PAIR_DEVICE_METADATA_SERVICE_H_ + +#include "ash/quick_pair/common/device.h" +#include "ash/quick_pair/proto/fastpair.pb.h" +#include "base/callback.h" +#include "third_party/abseil-cpp/absl/types/optional.h" + +namespace device { +class BluetoothDevice; +} + +namespace ash { +namespace quick_pair { + +// The entry point for the Repository component in the Quick Pair system, +// responsible for connecting to back-end services. +class FastPairDeviceMetadataService { + public: + FastPairDeviceMetadataService(); + FastPairDeviceMetadataService(const FastPairDeviceMetadataService&) = delete; + FastPairDeviceMetadataService& operator=( + const FastPairDeviceMetadataService&) = delete; + virtual ~FastPairDeviceMetadataService(); + + // Returns the DeviceMetadata for a given |hex_model_id| to the provided + // |callback|, if available. + void GetDeviceMetadata( + const std::string& hex_model_id, + base::OnceCallback<void(absl::optional<nearby::fastpair::Device>)> + callback); + + // Checks if the input |hex_model_id| is valid and notifies the requester + // through the provided |callback|. + void IsValidModelId(const std::string& hex_model_id, + base::OnceCallback<void(bool)> callback); + + // Looks up the key associated with either |address| or |account_key_filter| + // and returns it to the provided |callback|, if available. If this + // information is available locally that will be returned immediately, + // otherwise this will request data from the footprints server. + void GetAssociatedAccountKey( + const std::string& address, + const std::string& account_key_filter, + base::OnceCallback<void(absl::optional<std::string>)> callback); + + // Stores the given |account_key| for a |device| on the server. + void AssociateAccountKey(const Device& device, + const std::string& account_key); + + // Deletes the associated data for a given |device|. + void DeleteAssociatedDevice(const device::BluetoothDevice* device); +}; + +} // namespace quick_pair +} // namespace ash + +#endif // ASH_QUICK_PAIR_REPOSITORY_FAST_PAIR_DEVICE_METADATA_SERVICE_H_
diff --git a/ash/webui/scanning/resources/scan_preview.html b/ash/webui/scanning/resources/scan_preview.html index 2856269..3d4f0a9 100644 --- a/ash/webui/scanning/resources/scan_preview.html +++ b/ash/webui/scanning/resources/scan_preview.html
@@ -48,12 +48,17 @@ max-height: calc(100vh - var(--panel-container-margin-top)); outline: none; overflow-y: auto; + padding-top: 2px; } .preview:focus { box-shadow: 0 0 0 2px rgba(var(--google-blue-600-rgb), .4); } + .preview:hover { + box-shadow: none; + } + .preview-item { border: 1px solid var(--google-grey-300); border-radius: 4px; @@ -69,6 +74,10 @@ width: calc(100% - 24px); } + .preview:hover .focused-scanned-image { + box-shadow: rgba(var(--google-blue-600-rgb), .4) 0 0 0 2px; + } + paper-progress { border-radius: 4px; height: 4px;
diff --git a/ash/webui/scanning/resources/scan_preview.js b/ash/webui/scanning/resources/scan_preview.js index 75a7c5d..7542679 100644 --- a/ash/webui/scanning/resources/scan_preview.js +++ b/ash/webui/scanning/resources/scan_preview.js
@@ -7,6 +7,7 @@ import './scanning_shared_css.js'; import 'chrome://resources/polymer/v3_0/paper-progress/paper-progress.js'; +import {assert} from 'chrome://resources/js/assert.m.js'; import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js'; import {afterNextRender, html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; @@ -102,12 +103,19 @@ type: Number, value: 1, }, + + /** @private {number} */ + previousPageInView_: { + type: Number, + value: -1, + }, }, observers: [ 'setPreviewAriaLabel_(showScannedImages_, showCancelingProgress_,' + ' showHelperText_)', 'setScanProgressTimer_(showScanProgress_, progressPercent)', + 'setFocusedScannedImage_(objectUrls.length, currentPageInView_)', ], /** @override */ @@ -216,6 +224,8 @@ onScannedImagesScroll_() { const imageHeight = this.$$('.scanned-image').height; const scrollTop = this.$$('#previewDiv').scrollTop - (imageHeight * .5); + assert(this.currentPageInView_ > 0); + this.previousPageInView_ = this.currentPageInView_; // This is a special case for the first page since there is no margin or // previous page above it. @@ -226,5 +236,30 @@ this.currentPageInView_ = 2 + Math.floor(scrollTop / (imageHeight + SCANNED_IMG_MARGIN_BOTTOM_PX)); + assert(this.currentPageInView_ > 0); + }, + + /** + * Sets the CSS class for the current scanned image in view so the blue border + * will show on the correct page when hovered. + * @private + */ + setFocusedScannedImage_() { + // Need to wait for the scanned images to render. + afterNextRender(this, () => { + const scannedImages = + this.$$('#scannedImages').getElementsByClassName('scanned-image'); + if (scannedImages.length === 0) { + return; + } + + if (this.previousPageInView_ > 0) { + scannedImages[this.previousPageInView_ - 1].classList.remove( + 'focused-scanned-image'); + } + assert(this.currentPageInView_ > 0); + scannedImages[this.currentPageInView_ - 1].classList.add( + 'focused-scanned-image'); + }); }, });
diff --git a/base/trace_event/trace_event_unittest.cc b/base/trace_event/trace_event_unittest.cc index c43bce7..c6b1ddf5 100644 --- a/base/trace_event/trace_event_unittest.cc +++ b/base/trace_event/trace_event_unittest.cc
@@ -325,7 +325,7 @@ } bool IsStringInDict(const char* string_to_match, const Value* dict) { - for (const auto& pair : dict->DictItems()) { + for (const auto pair : dict->DictItems()) { if (pair.first.find(string_to_match) != std::string::npos) return true;
diff --git a/base/values_unittest.cc b/base/values_unittest.cc index 73a5c45..29aa5ea 100644 --- a/base/values_unittest.cc +++ b/base/values_unittest.cc
@@ -1677,27 +1677,21 @@ ASSERT_TRUE(copy_bool); ASSERT_NE(copy_bool, bool_weak); ASSERT_TRUE(copy_bool->is_bool()); - bool copy_bool_value = false; - ASSERT_TRUE(copy_bool->GetAsBoolean(©_bool_value)); - ASSERT_TRUE(copy_bool_value); + ASSERT_TRUE(copy_bool->GetBool()); Value* copy_int = nullptr; ASSERT_TRUE(copy_dict->Get("int", ©_int)); ASSERT_TRUE(copy_int); ASSERT_NE(copy_int, int_weak); ASSERT_TRUE(copy_int->is_int()); - int copy_int_value = 0; - ASSERT_TRUE(copy_int->GetAsInteger(©_int_value)); - ASSERT_EQ(42, copy_int_value); + ASSERT_EQ(42, copy_int->GetInt()); Value* copy_double = nullptr; ASSERT_TRUE(copy_dict->Get("double", ©_double)); ASSERT_TRUE(copy_double); ASSERT_NE(copy_double, double_weak); ASSERT_TRUE(copy_double->is_double()); - double copy_double_value = 0; - ASSERT_TRUE(copy_double->GetAsDouble(©_double_value)); - ASSERT_EQ(3.14, copy_double_value); + ASSERT_EQ(3.14, copy_double->GetDouble()); Value* copy_string = nullptr; ASSERT_TRUE(copy_dict->Get("string", ©_string)); @@ -1743,17 +1737,15 @@ ASSERT_TRUE(copy_list->Get(0, ©_list_element_0)); ASSERT_TRUE(copy_list_element_0); ASSERT_NE(copy_list_element_0, list_element_0_weak); - int copy_list_element_0_value; - ASSERT_TRUE(copy_list_element_0->GetAsInteger(©_list_element_0_value)); - ASSERT_EQ(0, copy_list_element_0_value); + ASSERT_TRUE(copy_list_element_0->is_int()); + ASSERT_EQ(0, copy_list_element_0->GetInt()); Value* copy_list_element_1; ASSERT_TRUE(copy_list->Get(1, ©_list_element_1)); ASSERT_TRUE(copy_list_element_1); ASSERT_NE(copy_list_element_1, list_element_1_weak); - int copy_list_element_1_value; - ASSERT_TRUE(copy_list_element_1->GetAsInteger(©_list_element_1_value)); - ASSERT_EQ(1, copy_list_element_1_value); + ASSERT_TRUE(copy_list_element_1->is_int()); + ASSERT_EQ(1, copy_list_element_1->GetInt()); copy_value = nullptr; ASSERT_TRUE(copy_dict->Get("dictionary", ©_value));
diff --git a/build/config/mac/BUILD.gn b/build/config/mac/BUILD.gn index 0919208e..8005ed5 100644 --- a/build/config/mac/BUILD.gn +++ b/build/config/mac/BUILD.gn
@@ -117,7 +117,8 @@ # # The symbolic link for $mac_sdk_path is set up by # //build/config/apple/sdk_info.py in //build/config/mac/mac_sdk.gni. -if (use_system_xcode && use_goma && target_os == "mac") { +if (use_system_xcode && use_goma && target_os == "mac" && + current_toolchain == default_toolchain) { action("sdk_inputs") { script = "//build/noop.py" outputs = [ @@ -128,5 +129,8 @@ } } else { group("sdk_inputs") { + if (current_toolchain != default_toolchain) { + public_deps = [ ":sdk_inputs($default_toolchain)" ] + } } }
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index aa378246..61e0a1e8 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -5.20210713.0.1 +5.20210713.1.1
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index aa378246..61e0a1e8 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -5.20210713.0.1 +5.20210713.1.1
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni index f3383a4..93dc43ba 100644 --- a/chrome/android/chrome_java_sources.gni +++ b/chrome/android/chrome_java_sources.gni
@@ -671,6 +671,7 @@ "java/src/org/chromium/chrome/browser/incognito/IncognitoNotificationServiceImpl.java", "java/src/org/chromium/chrome/browser/incognito/IncognitoProfileDestroyer.java", "java/src/org/chromium/chrome/browser/incognito/IncognitoTabLauncher.java", + "java/src/org/chromium/chrome/browser/incognito/IncognitoTabPersistence.java", "java/src/org/chromium/chrome/browser/incognito/IncognitoTabSnapshotController.java", "java/src/org/chromium/chrome/browser/incognito/IncognitoUtils.java", "java/src/org/chromium/chrome/browser/infobar/AutofillCreditCardFillingInfoBar.java",
diff --git a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/ExploreSurfaceCoordinator.java b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/ExploreSurfaceCoordinator.java index baf7cad..97c1acf 100644 --- a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/ExploreSurfaceCoordinator.java +++ b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/ExploreSurfaceCoordinator.java
@@ -59,12 +59,6 @@ */ FeedSurfaceCoordinator createFeedSurfaceCoordinator(boolean isInNightMode, boolean isPlaceholderShown, @NewTabPageLaunchOrigin int launchOrigin); - - /** Shows the Feeds surface. */ - void showFeedSurface(); - - /** Hides the Feeds surface. */ - void hideFeedSurface(); } /** @@ -107,20 +101,6 @@ isPlaceholderShown, bottomSheetController, scrollableContainerDelegate, launchOrigin, feedLaunchReliabilityLoggingState); } - - @Override - public void showFeedSurface() { - if (mExploreSurfaceFeedLifecycleManager != null) { - mExploreSurfaceFeedLifecycleManager.showFeedSurface(); - } - } - - @Override - public void hideFeedSurface() { - if (mExploreSurfaceFeedLifecycleManager != null) { - mExploreSurfaceFeedLifecycleManager.hideFeedSurface(); - } - } }; }
diff --git a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/ExploreSurfaceFeedLifecycleManager.java b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/ExploreSurfaceFeedLifecycleManager.java index e7b242c2..eb7471e 100644 --- a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/ExploreSurfaceFeedLifecycleManager.java +++ b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/ExploreSurfaceFeedLifecycleManager.java
@@ -55,12 +55,4 @@ String state = mCoordinator.getSavedInstanceStateString(); StartSurfaceUserData.getInstance().saveFeedInstanceState(state); } - - public void showFeedSurface() { - super.show(); - } - - public void hideFeedSurface() { - super.hide(); - } -} +} \ No newline at end of file
diff --git a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceMediator.java b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceMediator.java index 682e35f..500be7b0 100644 --- a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceMediator.java +++ b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceMediator.java
@@ -53,7 +53,6 @@ import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; import org.chromium.chrome.browser.preferences.Pref; import org.chromium.chrome.browser.tab.Tab; -import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.browser.tabmodel.TabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModelSelector; @@ -575,8 +574,6 @@ mFeedSurfaceController.createFeedSurfaceCoordinator( ColorUtils.inNightMode(mContext), shouldShowFeedPlaceholder(), mLaunchOrigin)); - } else { - showFeedSurfaceCoordinator(); } mTabModelSelector.addObserver(mTabModelSelectorObserver); @@ -679,13 +676,7 @@ } mPropertyModel.set(IS_SHOWING_OVERVIEW, false); - if (mTabModelSelector.getCurrentTab() == null - || mTabModelSelector.getCurrentTab().getLaunchType() - != TabLaunchType.FROM_START_SURFACE) { - destroyFeedSurfaceCoordinator(); - } else { - hideFeedSurfaceCoordinator(); - } + destroyFeedSurfaceCoordinator(); if (mNormalTabModelObserver != null) { if (mNormalTabModel != null) { mNormalTabModel.removeObserver(mNormalTabModelObserver); @@ -721,14 +712,6 @@ mPropertyModel.set(FEED_SURFACE_COORDINATOR, null); } - private void hideFeedSurfaceCoordinator() { - if (mFeedSurfaceController != null) mFeedSurfaceController.hideFeedSurface(); - } - - private void showFeedSurfaceCoordinator() { - if (mFeedSurfaceController != null) mFeedSurfaceController.showFeedSurface(); - } - // TODO(crbug.com/982018): turn into onClickMoreTabs() and hide the OnClickListener signature // inside. Implements View.OnClickListener, which listens for the more tabs button. @Override
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutPerfTest.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutPerfTest.java index 931f2691..8863735 100644 --- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutPerfTest.java +++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutPerfTest.java
@@ -352,6 +352,7 @@ @Test @EnormousTest @CommandLineFlags.Add({BASE_PARAMS}) + @FlakyTest(message = "https://crbug.com/1225926") public void testGridToTabToOtherLive() throws InterruptedException { prepareTabs(2, mUrl); reportGridToTabPerf(true, false, "Grid-to-Tab to other live tab");
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java index ce4a3f1..eefb377 100644 --- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java +++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java
@@ -99,12 +99,12 @@ import org.chromium.chrome.browser.flags.CachedFeatureFlags; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeSwitches; -import org.chromium.chrome.browser.incognito.IncognitoUtils; import org.chromium.chrome.browser.night_mode.ChromeNightModeTestUtils; import org.chromium.chrome.browser.search_engines.TemplateUrlServiceFactory; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab.TabStateExtractor; +import org.chromium.chrome.browser.tabmodel.IncognitoTabHostUtils; import org.chromium.chrome.browser.tabmodel.TabCreator; import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabModelObserver; @@ -2037,7 +2037,7 @@ CriteriaHelper.pollUiThread(() -> newActivity.getCurrentTabModel().isIncognito(), "New Activity current TabModel is not incognito"); - TestThreadUtils.runOnUiThreadBlocking(IncognitoUtils::closeAllIncognitoTabs); + TestThreadUtils.runOnUiThreadBlocking(IncognitoTabHostUtils::closeAllIncognitoTabs); assertTrue("Deferred startup never completed", mActivityTestRule.waitForDeferredStartup());
diff --git a/chrome/android/features/start_surface/internal/junit/src/org/chromium/chrome/features/start_surface/StartSurfaceMediatorUnitTest.java b/chrome/android/features/start_surface/internal/junit/src/org/chromium/chrome/features/start_surface/StartSurfaceMediatorUnitTest.java index 18f9954b..88d2047 100644 --- a/chrome/android/features/start_surface/internal/junit/src/org/chromium/chrome/features/start_surface/StartSurfaceMediatorUnitTest.java +++ b/chrome/android/features/start_surface/internal/junit/src/org/chromium/chrome/features/start_surface/StartSurfaceMediatorUnitTest.java
@@ -8,7 +8,6 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.mockito.ArgumentMatchers.anyBoolean; @@ -1081,18 +1080,10 @@ mediator.hideOverview(true); mOverviewModeObserverCaptor.getValue().startedHiding(); mOverviewModeObserverCaptor.getValue().finishedHiding(); - verify(mFeedSurfaceController).hideFeedSurface(); - assertThat(mPropertyModel.get(FEED_SURFACE_COORDINATOR), equalTo(mFeedSurfaceCoordinator)); + assertNull(mPropertyModel.get(FEED_SURFACE_COORDINATOR)); - FeedSurfaceCoordinator feedSurfaceCoordinator = mock(FeedSurfaceCoordinator.class); - assertNotEquals(mFeedSurfaceCoordinator, feedSurfaceCoordinator); - when(mFeedSurfaceController.createFeedSurfaceCoordinator( - anyBoolean(), anyBoolean(), anyInt())) - .thenReturn(feedSurfaceCoordinator); mediator.setOverviewState(StartSurfaceState.SHOWING_PREVIOUS); mediator.showOverview(false); - verify(mFeedSurfaceController).showFeedSurface(); - mainTabGridController.verify(mMainTabGridController).showOverview(eq(false)); assertThat(mediator.getStartSurfaceState(), equalTo(StartSurfaceState.SHOWN_HOMEPAGE)); assertThat(mPropertyModel.get(FEED_SURFACE_COORDINATOR), equalTo(mFeedSurfaceCoordinator));
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java index bf0a39c1..e2cc4a0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -145,6 +145,7 @@ import org.chromium.chrome.browser.tabmodel.ChromeTabCreator; import org.chromium.chrome.browser.tabmodel.IncognitoTabHost; import org.chromium.chrome.browser.tabmodel.IncognitoTabHostRegistry; +import org.chromium.chrome.browser.tabmodel.IncognitoTabHostUtils; import org.chromium.chrome.browser.tabmodel.NextTabPolicy.NextTabPolicySupplier; import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.browser.tabmodel.TabModelSelector; @@ -798,7 +799,7 @@ // Check for incognito tabs to handle the case where Chrome was swiped away in the // background. - if (!IncognitoUtils.doIncognitoTabsExist()) { + if (!IncognitoTabHostUtils.doIncognitoTabsExist()) { IncognitoNotificationManager.dismissIncognitoNotification(); DownloadNotificationService.getInstance().cancelOffTheRecordDownloads(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java index a8724d7..8f1c018 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java
@@ -1567,6 +1567,19 @@ } } + /** + * Whether bundle has any extra that indicates an incognito tab will be launched. + * @param extras A bundle that carries extras + * @return True if there is any incognito related extra, otherwise return false. + */ + public static boolean hasAnyIncognitoExtra(@Nullable Bundle extras) { + if (extras == null) return false; + return IntentUtils.safeGetBoolean(extras, EXTRA_INCOGNITO_MODE, false) + || IntentUtils.safeGetBoolean(extras, EXTRA_OPEN_NEW_INCOGNITO_TAB, false) + || IntentUtils.safeGetBoolean( + extras, EXTRA_INVOKED_FROM_LAUNCH_NEW_INCOGNITO_TAB, false); + } + @NativeMethods interface Natives { boolean isCorsSafelistedHeader(String name, String value);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java index 1a80e58..c1125e7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java
@@ -58,7 +58,6 @@ import org.chromium.chrome.browser.browserservices.SessionHandler; import org.chromium.chrome.browser.device.DeviceClassManager; import org.chromium.chrome.browser.flags.ChromeFeatureList; -import org.chromium.chrome.browser.incognito.IncognitoUtils; import org.chromium.chrome.browser.init.ChainedTasks; import org.chromium.chrome.browser.init.ChromeBrowserInitializer; import org.chromium.chrome.browser.metrics.PageLoadMetrics; @@ -495,7 +494,7 @@ // creation in incognito mode not to have inconsistent modes between tab model and // hidden tab. (crbug.com/1190971) boolean canUseHiddenTab = mClientManager.getCanUseHiddenTab(session) - && !IncognitoUtils.hasAnyIncognitoExtra(extras); + && !IntentHandler.hasAnyIncognitoExtra(extras); startSpeculation(session, url, canUseHiddenTab, extras, uid); } preconnectUrls(otherLikelyBundles); @@ -553,7 +552,7 @@ // mayLaunchUrl should not be executed for Incognito CCT since all setup is created with // regular profile. If we need to enable mayLaunchUrl for off-the-record profiles, we need // to update the profile used. Please see crbug.com/1106757. - if (IncognitoUtils.hasAnyIncognitoExtra(extras)) return false; + if (IntentHandler.hasAnyIncognitoExtra(extras)) return false; final boolean lowConfidence = (url == null || TextUtils.isEmpty(url.toString())) && otherLikelyBundles != null;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoNotificationPresenceController.java b/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoNotificationPresenceController.java index da61835..d8b54bf6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoNotificationPresenceController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoNotificationPresenceController.java
@@ -4,6 +4,7 @@ package org.chromium.chrome.browser.incognito; +import org.chromium.chrome.browser.tabmodel.IncognitoTabHostUtils; import org.chromium.chrome.browser.tabmodel.IncognitoTabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModelSelector; @@ -32,7 +33,7 @@ @Override public void didBecomeEmpty() { - if (!IncognitoUtils.doIncognitoTabsExist()) { + if (!IncognitoTabHostUtils.doIncognitoTabsExist()) { IncognitoNotificationManager.dismissIncognitoNotification(); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoNotificationServiceImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoNotificationServiceImpl.java index cfdcd24..f249cc5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoNotificationServiceImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoNotificationServiceImpl.java
@@ -22,6 +22,7 @@ import org.chromium.chrome.browser.ChromeTabbedActivity; import org.chromium.chrome.browser.document.ChromeLauncherActivity; import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.chrome.browser.tabmodel.IncognitoTabHostUtils; import org.chromium.chrome.browser.util.AndroidTaskUtils; import org.chromium.components.browser_ui.notifications.PendingIntentProvider; import org.chromium.content_public.browser.BrowserStartupController; @@ -48,15 +49,15 @@ @Override protected void onHandleIntent(Intent intent) { PostTask.runSynchronously( - UiThreadTaskTraits.DEFAULT, IncognitoUtils::closeAllIncognitoTabs); + UiThreadTaskTraits.DEFAULT, IncognitoTabHostUtils::closeAllIncognitoTabs); - boolean clearedIncognito = IncognitoUtils.deleteIncognitoStateFiles(); + boolean clearedIncognito = IncognitoTabPersistence.deleteIncognitoStateFiles(); // If we failed clearing all of the incognito tabs, then do not dismiss the notification. if (!clearedIncognito) return; PostTask.runSynchronously(UiThreadTaskTraits.DEFAULT, () -> { - if (IncognitoUtils.doIncognitoTabsExist()) { + if (IncognitoTabHostUtils.doIncognitoTabsExist()) { assert false : "Not all incognito tabs closed as expected"; return; } @@ -78,28 +79,6 @@ }); } - private void focusChromeIfNecessary() { - Set<Integer> visibleTaskIds = getTaskIdsForVisibleActivities(); - int tabbedTaskId = -1; - - for (Activity activity : ApplicationStatus.getRunningActivities()) { - if (activity instanceof ChromeTabbedActivity) { - tabbedTaskId = activity.getTaskId(); - break; - } - } - - // If the task containing the tabbed activity is visible, then do nothing as there is no - // snapshot that would need to be regenerated. - if (visibleTaskIds.contains(tabbedTaskId)) return; - - Context context = ContextUtils.getApplicationContext(); - Intent startIntent = new Intent(Intent.ACTION_MAIN); - startIntent.setPackage(context.getPackageName()); - startIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - context.startActivity(startIntent); - } - private void removeNonVisibleChromeTabbedRecentEntries() { Set<Integer> visibleTaskIds = getTaskIdsForVisibleActivities();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoProfileDestroyer.java b/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoProfileDestroyer.java index e9f3dde7..e3de455 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoProfileDestroyer.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoProfileDestroyer.java
@@ -5,6 +5,7 @@ package org.chromium.chrome.browser.incognito; import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.chrome.browser.tabmodel.IncognitoTabHostUtils; import org.chromium.chrome.browser.tabmodel.IncognitoTabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModelSelector; @@ -32,7 +33,8 @@ @Override public void didBecomeEmpty() { - if (!IncognitoUtils.doIncognitoTabsExist() && !IncognitoUtils.isIncognitoTabModelActive()) { + if (!IncognitoTabHostUtils.doIncognitoTabsExist() + && !IncognitoTabHostUtils.isIncognitoTabModelActive()) { // Only delete the incognito profile if there are no incognito tabs open in any tab // model selector as the profile is shared between them. Profile profile = mTabModelSelector.getModel(true).getProfile();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoTabPersistence.java b/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoTabPersistence.java new file mode 100644 index 0000000..fb65a56 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoTabPersistence.java
@@ -0,0 +1,38 @@ +// 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. + +package org.chromium.chrome.browser.incognito; + +import android.util.Pair; + +import org.chromium.chrome.browser.tabpersistence.TabStateDirectory; +import org.chromium.chrome.browser.tabpersistence.TabStateFileManager; + +import java.io.File; + +/** + * Manages tab state files for incognito tabs. + */ +public class IncognitoTabPersistence { + /** + * Deletes files with saved state of incognito tabs. + * @return whether successful. + */ + static boolean deleteIncognitoStateFiles() { + File directory = TabStateDirectory.getOrCreateTabbedModeStateDirectory(); + File[] tabStateFiles = directory.listFiles(); + if (tabStateFiles == null) return true; + + boolean deletionSuccessful = true; + for (File file : tabStateFiles) { + Pair<Integer, Boolean> tabInfo = + TabStateFileManager.parseInfoFromFilename(file.getName()); + boolean isIncognito = tabInfo != null && tabInfo.second; + if (isIncognito) { + deletionSuccessful &= file.delete(); + } + } + return deletionSuccessful; + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoUtils.java index 899d812e..42ccb4f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoUtils.java
@@ -8,30 +8,22 @@ import android.app.Activity; import android.app.ActivityManager; import android.content.Context; -import android.os.Bundle; -import android.util.Pair; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import org.chromium.base.ApplicationStatus; import org.chromium.base.ContextUtils; -import org.chromium.base.IntentUtils; import org.chromium.base.annotations.NativeMethods; import org.chromium.chrome.browser.ChromeTabbedActivity; -import org.chromium.chrome.browser.IntentHandler; import org.chromium.chrome.browser.customtabs.CustomTabIncognitoManager; import org.chromium.chrome.browser.profiles.OTRProfileID; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.profiles.ProfileKey; -import org.chromium.chrome.browser.tabmodel.IncognitoTabHost; -import org.chromium.chrome.browser.tabmodel.IncognitoTabHostRegistry; -import org.chromium.chrome.browser.tabpersistence.TabStateDirectory; -import org.chromium.chrome.browser.tabpersistence.TabStateFileManager; +import org.chromium.chrome.browser.tabmodel.IncognitoTabHostUtils; import org.chromium.chrome.browser.util.AndroidTaskUtils; import org.chromium.ui.base.WindowAndroid; -import java.io.File; import java.util.HashSet; import java.util.Set; @@ -83,7 +75,7 @@ // any incognito tabs exist and the current tab model isn't incognito. If so, we should // destroy the incognito profile; otherwise it's not safe to do so yet. if (tabbedModeTaskIds.size() == 0) { - return !(doIncognitoTabsExist() || selectedTabModelIsIncognito); + return !(IncognitoTabHostUtils.doIncognitoTabsExist() || selectedTabModelIsIncognito); } // In this case, we have tabbed mode activities listed in recents that do not have an @@ -94,60 +86,6 @@ } /** - * Determine whether there are any incognito tabs. - */ - public static boolean doIncognitoTabsExist() { - for (IncognitoTabHost host : IncognitoTabHostRegistry.getInstance().getHosts()) { - if (host.hasIncognitoTabs()) { - return true; - } - } - return false; - } - - /** - * Determine whether the incognito tab model is active. - */ - public static boolean isIncognitoTabModelActive() { - for (IncognitoTabHost host : IncognitoTabHostRegistry.getInstance().getHosts()) { - if (host.isActiveModel()) { - return true; - } - } - return false; - } - - /** - * Closes all incognito tabs. - */ - public static void closeAllIncognitoTabs() { - for (IncognitoTabHost host : IncognitoTabHostRegistry.getInstance().getHosts()) { - host.closeAllIncognitoTabs(); - } - } - - /** - * Deletes files with saved state of incognito tabs. - * @return whether successful. - */ - public static boolean deleteIncognitoStateFiles() { - File directory = TabStateDirectory.getOrCreateTabbedModeStateDirectory(); - File[] tabStateFiles = directory.listFiles(); - if (tabStateFiles == null) return true; - - boolean deletionSuccessful = true; - for (File file : tabStateFiles) { - Pair<Integer, Boolean> tabInfo = - TabStateFileManager.parseInfoFromFilename(file.getName()); - boolean isIncognito = tabInfo != null && tabInfo.second; - if (isIncognito) { - deletionSuccessful &= file.delete(); - } - } - return deletionSuccessful; - } - - /** * @return true if incognito mode is enabled. */ public static boolean isIncognitoModeEnabled() { @@ -165,20 +103,6 @@ } /** - * Whether bundle has any extra that indicates an incognito tab will be launched. - * @param extras A bundle that carries extras - * @return True if there is any incognito related extra, otherwise return false. - */ - public static boolean hasAnyIncognitoExtra(@Nullable Bundle extras) { - if (extras == null) return false; - return IntentUtils.safeGetBoolean(extras, IntentHandler.EXTRA_INCOGNITO_MODE, false) - || IntentUtils.safeGetBoolean( - extras, IntentHandler.EXTRA_OPEN_NEW_INCOGNITO_TAB, false) - || IntentUtils.safeGetBoolean( - extras, IntentHandler.EXTRA_INVOKED_FROM_LAUNCH_NEW_INCOGNITO_TAB, false); - } - - /** * Returns either a regular profile or a (primary/non-primary) Incognito profile. * * <p>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/init/AsyncInitializationActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/init/AsyncInitializationActivity.java index f00d0a72..aefc7b2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/init/AsyncInitializationActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/init/AsyncInitializationActivity.java
@@ -38,7 +38,6 @@ import org.chromium.chrome.browser.LaunchIntentDispatcher; import org.chromium.chrome.browser.WarmupManager; import org.chromium.chrome.browser.firstrun.FirstRunFlowSequencer; -import org.chromium.chrome.browser.incognito.IncognitoUtils; import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher; import org.chromium.chrome.browser.multiwindow.MultiWindowModeStateDispatcher; import org.chromium.chrome.browser.multiwindow.MultiWindowModeStateDispatcherImpl; @@ -254,7 +253,7 @@ String url = IntentHandler.getUrlFromIntent(intent); if (url == null) return; // Blocking pre-connect for all off-the-record profiles. - if (!IncognitoUtils.hasAnyIncognitoExtra(intent.getExtras())) { + if (!IntentHandler.hasAnyIncognitoExtra(intent.getExtras())) { WarmupManager.getInstance().maybePreconnectUrlAndSubResources( Profile.getLastUsedRegularProfile(), url); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/previewtab/PreviewTabTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/previewtab/PreviewTabTest.java index b03a530..751bb96e 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/previewtab/PreviewTabTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/previewtab/PreviewTabTest.java
@@ -21,9 +21,9 @@ import org.chromium.chrome.browser.compositor.bottombar.ephemeraltab.EphemeralTabCoordinator; import org.chromium.chrome.browser.contextualsearch.ContextualSearchManager; import org.chromium.chrome.browser.firstrun.DisableFirstRun; -import org.chromium.chrome.browser.incognito.IncognitoUtils; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tabbed_mode.TabbedRootUiCoordinator; +import org.chromium.chrome.browser.tabmodel.IncognitoTabHostUtils; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; import org.chromium.chrome.test.util.browser.contextmenu.ContextMenuUtils; @@ -144,7 +144,7 @@ TestThreadUtils.runOnUiThreadBlocking(() -> { bottomSheet.expandSheet(); endAnimations(); - IncognitoUtils.closeAllIncognitoTabs(); + IncognitoTabHostUtils.closeAllIncognitoTabs(); endAnimations(); }); Assert.assertEquals(SheetState.HIDDEN, bottomSheet.getSheetState());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SyncConsentFragmentTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SyncConsentFragmentTest.java index 43c8f30..272c3ad 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SyncConsentFragmentTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SyncConsentFragmentTest.java
@@ -67,7 +67,7 @@ import org.chromium.components.signin.ChildAccountStatus; import org.chromium.components.signin.base.CoreAccountInfo; import org.chromium.components.signin.metrics.SigninAccessPoint; -import org.chromium.components.signin.test.util.FakeProfileDataSource; +import org.chromium.components.signin.test.util.FakeAccountInfoService; import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.ui.modaldialog.ModalDialogManager; import org.chromium.ui.modaldialog.ModalDialogManager.ModalDialogType; @@ -112,7 +112,7 @@ @Rule public final AccountManagerTestRule mAccountManagerTestRule = - new AccountManagerTestRule(new FakeProfileDataSource()); + new AccountManagerTestRule(new FakeAccountInfoService()); @Rule public final ChromeTabbedActivityTestRule mChromeActivityTestRule =
diff --git a/chrome/android/javatests/src/org/chromium/chrome/test/smoke/ChromeBundleSmokeTest.java b/chrome/android/javatests/src/org/chromium/chrome/test/smoke/ChromeBundleSmokeTest.java index c6bd6e2..ad40d5922 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/test/smoke/ChromeBundleSmokeTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/test/smoke/ChromeBundleSmokeTest.java
@@ -7,7 +7,6 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; -import android.os.Build; import android.support.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; @@ -21,7 +20,6 @@ import org.junit.runner.RunWith; import org.chromium.base.test.BaseJUnit4ClassRunner; -import org.chromium.base.test.util.DisableIf; import org.chromium.chrome.test.pagecontroller.rules.ChromeUiApplicationTestRule; import org.chromium.chrome.test.pagecontroller.rules.ChromeUiAutomatorTestRule; import org.chromium.chrome.test.pagecontroller.utils.IUi2Locator; @@ -73,38 +71,22 @@ } @Test - @DisableIf.Build(message = "Flaky on Android Marshmallow, see crbug.com/1178106", - sdk_is_greater_than = Build.VERSION_CODES.LOLLIPOP_MR1, - sdk_is_less_than = Build.VERSION_CODES.N) - public void - testModuleJavaCodeExecution() { + public void testModuleJavaCodeExecution() { runTestActivity(0); // Test case EXECUTE_JAVA. } @Test - @DisableIf.Build(message = "Flaky on Android Marshmallow, see crbug.com/1178106", - sdk_is_greater_than = Build.VERSION_CODES.LOLLIPOP_MR1, - sdk_is_less_than = Build.VERSION_CODES.N) - public void - testModuleNativeCodeExecution() { + public void testModuleNativeCodeExecution() { runTestActivity(1); // Test case EXECUTE_NATIVE. } @Test - @DisableIf.Build(message = "Flaky on Android Marshmallow, see crbug.com/1178106", - sdk_is_greater_than = Build.VERSION_CODES.LOLLIPOP_MR1, - sdk_is_less_than = Build.VERSION_CODES.N) - public void - testModuleJavaResourceLoading() { + public void testModuleJavaResourceLoading() { runTestActivity(2); // Test case LOAD_JAVA_RESOURCE. } @Test - @DisableIf.Build(message = "Flaky on Android Marshmallow, see crbug.com/1178106", - sdk_is_greater_than = Build.VERSION_CODES.LOLLIPOP_MR1, - sdk_is_less_than = Build.VERSION_CODES.N) - public void - testModuleNativeResourceLoading() { + public void testModuleNativeResourceLoading() { runTestActivity(3); // Test case LOAD_NATIVE_RESOURCE. } }
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index 225ad70..261769d5 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp
@@ -3539,9 +3539,15 @@ <message name="IDS_ARC_OOBE_TERMS_HEADING" desc="Heading of the Arc Terms OOBE dialog."> Google Play apps and services </message> + <message name="IDS_ARC_OOBE_TERMS_HEADING_CHILD" desc="Heading of the Arc Terms OOBE dialog, when a child account is in use."> + Review Google Play apps and services + </message> <message name="IDS_ARC_OOBE_TERMS_DESCRIPTION" desc="Description of the Arc Terms OOBE dialog."> Use Google Play to install Android apps </message> + <message name="IDS_ARC_OOBE_TERMS_DESCRIPTION_CHILD" desc="Description of the Arc Terms OOBE dialog, when a child account is in use."> + With your permission, your child can use Google Play to install apps + </message> <message name="IDS_ARC_OOBE_TERMS_LOADING" desc="Loading message of the Arc Terms OOBE dialog."> Loading... </message>
diff --git a/chrome/app/chromeos_strings_grdp/IDS_ARC_OOBE_TERMS_DESCRIPTION_CHILD.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_ARC_OOBE_TERMS_DESCRIPTION_CHILD.png.sha1 new file mode 100644 index 0000000..911f482f --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_ARC_OOBE_TERMS_DESCRIPTION_CHILD.png.sha1
@@ -0,0 +1 @@ +b144c1fbf4f55db93b3b8dbb2eb9f137aca464d6 \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_ARC_OOBE_TERMS_HEADING_CHILD.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_ARC_OOBE_TERMS_HEADING_CHILD.png.sha1 new file mode 100644 index 0000000..911f482f --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_ARC_OOBE_TERMS_HEADING_CHILD.png.sha1
@@ -0,0 +1 @@ +b144c1fbf4f55db93b3b8dbb2eb9f137aca464d6 \ No newline at end of file
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp index 024321c..e2874e6 100644 --- a/chrome/app/settings_strings.grdp +++ b/chrome/app/settings_strings.grdp
@@ -272,7 +272,7 @@ <message name="IDS_SETTINGS_AUTOFILL_ADDRESSES_EMAIL" desc="This is the label for the field that lets a user modify the email address that will be used when auto-filling forms on the web."> Email </message> - <message name="IDS_SETTINGS_AUTOFILL_ADDRESS_HONORIFIC_LABEL" desc="This is the label for the field that lets the user modify their honorific for an address. A honorific is an optional, title like Mr, Dr, etc, which can accompany one's name."> + <message name="IDS_SETTINGS_AUTOFILL_ADDRESS_HONORIFIC_LABEL" desc="This is the label for the field that lets the user modify the title that will be used when auto-filling forms on the web. A 'Title' field in a web form could be a prefix like Ms., Mx., or Dr. or a position held, like Captain or Rabbi." meaning="Honorific"> Title </message> <message name="IDS_SETTINGS_AUTOFILL_CREDIT_CARD_TYPE_COLUMN_LABEL" desc="Label for the column containing the type of credit card that is saved. The type is in the format: `Visa ****1234`.">
diff --git a/chrome/app/vector_icons/BUILD.gn b/chrome/app/vector_icons/BUILD.gn index be2d68c..9418ca1 100644 --- a/chrome/app/vector_icons/BUILD.gn +++ b/chrome/app/vector_icons/BUILD.gn
@@ -61,7 +61,6 @@ "incognito_profile.icon", "input.icon", "key.icon", - "key_crossed.icon", "keyboard_arrow_down.icon", "keyboard_arrow_right.icon", "keyboard_arrow_up.icon",
diff --git a/chrome/app/vector_icons/key_crossed.icon b/chrome/app/vector_icons/key_crossed.icon deleted file mode 100644 index 8733381..0000000 --- a/chrome/app/vector_icons/key_crossed.icon +++ /dev/null
@@ -1,57 +0,0 @@ -// Copyright 2021 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -CANVAS_DIMENSIONS, 32, -CIRCLE, 16, 16, 16, -MOVE_TO, 17.42f, 12, -H_LINE_TO, 30, -R_V_LINE_TO, 5, -R_H_LINE_TO, -2, -R_V_LINE_TO, 5, -R_H_LINE_TO, -4, -R_V_LINE_TO, -5, -R_H_LINE_TO, -6.25f, -CUBIC_TO, 16.86f, 20.45f, 13.73f, 23, 10, 23, -R_CUBIC_TO, -4.42f, 0, -8, -3.58f, -8, -8, -R_CUBIC_TO, 0, -4.42f, 3.58f, -8, 8, -8, -R_CUBIC_TO, 3.36f, 0, 6.23f, 2.07f, 7.42f, 5, -CLOSE, -MOVE_TO, 10, 18, -R_CUBIC_TO, 1.66f, 0, 3, -1.34f, 3, -3, -R_CUBIC_TO, 0, -1.66f, -1.34f, -3, -3, -3, -R_CUBIC_TO, -1.66f, 0, -3, 1.34f, -3, 3, -R_CUBIC_TO, 0, 1.66f, 1.34f, 3, 3, 3, -CLOSE, -LINE_TO, 24.78f, 28.18f, -LINE_TO, 26.46f, 26.5f, -LINE_TO, 5.52f, 5.52f, -LINE_TO, 3.82f, 7.22f, -CLOSE - -CANVAS_DIMENSIONS, 16, -CIRCLE, 8, 8, 8, -MOVE_TO, 8.41f, 6, -CUBIC_TO, 7.89f, 4.44f, 6.48f, 3.33f, 4.82f, 3.33f, -CUBIC_TO, 2.71f, 3.33f, 1, 5.12f, 1, 7.33f, -CUBIC_TO, 1, 9.54f, 2.71f, 11.33f, 4.82f, 11.33f, -CUBIC_TO, 6.48f, 11.33f, 7.89f, 10.22f, 8.41f, 8.66f, -LINE_TO, 11.18f, 8.66f, -LINE_TO, 11.18f, 11.33f, -LINE_TO, 13.73f, 11.33f, -LINE_TO, 13.73f, 8.66f, -LINE_TO, 15, 8.66f, -LINE_TO, 15, 6, -LINE_TO, 8.41f, 6, -CLOSE, -MOVE_TO, 4.82f, 8.67f, -CUBIC_TO, 4.12f, 8.67f, 3.55f, 8.08f, 3.55f, 7.34f, -CUBIC_TO, 3.55f, 6.6f, 4.12f, 6.01f, 4.82f, 6.01f, -CUBIC_TO, 5.52f, 6.01f, 6.09f, 6.6f, 6.09f, 7.34f, -CUBIC_TO, 6.09f, 8.08f, 5.52f, 8.67f, 4.82f, 8.67f, -CLOSE, -LINE_TO, 12.39f, 14.09f, -LINE_TO, 13.23f, 13.25f, -LINE_TO, 2.76f, 2.76f, -LINE_TO, 1.91f, 3.61f, -CLOSE
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 6a53ea8..67b4993 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -3451,6 +3451,9 @@ FEATURE_WITH_PARAMS_VALUE_TYPE(content_creation::kWebNotesStylizeEnabled, kWebNoteStylizeVariations, "WebNotesStylize")}, + {"sharing-hub-link-toggle", flag_descriptions::kSharingHubLinkToggleName, + flag_descriptions::kSharingHubLinkToggleDescription, kOsAndroid, + FEATURE_VALUE_TYPE(chrome::android::kSharingHubLinkToggle)}, #endif // OS_ANDROID {"in-product-help-demo-mode-choice", flag_descriptions::kInProductHelpDemoModeChoiceName, @@ -7449,10 +7452,6 @@ FEATURE_VALUE_TYPE(ash::features::kBorealisDiskManagement)}, #endif // BUILDFLAG(IS_CHROMEOS_ASH) - {"https-only-mode-setting", flag_descriptions::kHttpsOnlyModeName, - flag_descriptions::kHttpsOnlyModeDescription, kOsDesktop | kOsAndroid, - FEATURE_VALUE_TYPE(features::kHttpsOnlyMode)}, - #if defined(OS_ANDROID) {"dynamic-color-android", flag_descriptions::kDynamicColorAndroidName, flag_descriptions::kDynamicColorAndroidDescription, kOsAndroid,
diff --git a/chrome/browser/ash/customization/customization_document.cc b/chrome/browser/ash/customization/customization_document.cc index a01cce4..bea9e25 100644 --- a/chrome/browser/ash/customization/customization_document.cc +++ b/chrome/browser/ash/customization/customization_document.cc
@@ -51,6 +51,7 @@ #include "net/base/load_flags.h" #include "net/http/http_response_headers.h" #include "net/http/http_status_code.h" +#include "services/network/public/cpp/resource_request.h" #include "services/network/public/cpp/shared_url_loader_factory.h" #include "services/network/public/cpp/simple_url_loader.h"
diff --git a/chrome/browser/ash/dbus/ash_dbus_helper.cc b/chrome/browser/ash/dbus/ash_dbus_helper.cc index 10f744ed..a81de804 100644 --- a/chrome/browser/ash/dbus/ash_dbus_helper.cc +++ b/chrome/browser/ash/dbus/ash_dbus_helper.cc
@@ -89,7 +89,7 @@ chromeos::SystemSaltGetter::Initialize(); // Initialize DBusThreadManager for the browser. - chromeos::DBusThreadManager::Initialize(DBusThreadManager::kAll); + chromeos::DBusThreadManager::Initialize(); // Initialize Chrome dbus clients. dbus::Bus* bus = chromeos::DBusThreadManager::Get()->GetSystemBus();
diff --git a/chrome/browser/ash/dbus/dlp_files_policy_service_provider.cc b/chrome/browser/ash/dbus/dlp_files_policy_service_provider.cc index 6da1a91..dfd9d0e55 100644 --- a/chrome/browser/ash/dbus/dlp_files_policy_service_provider.cc +++ b/chrome/browser/ash/dbus/dlp_files_policy_service_provider.cc
@@ -120,9 +120,10 @@ policy::DlpRulesManager* dlp_rules_manager = policy::DlpRulesManagerFactory::GetForPrimaryProfile(); if (dlp_rules_manager) { - policy::DlpRulesManager::Level level = dlp_rules_manager->IsRestricted( - GURL(request.source_url()), - policy::DlpRulesManager::Restriction::kFiles); + policy::DlpRulesManager::Level level = + dlp_rules_manager->IsRestrictedByAnyRule( + GURL(request.source_url()), + policy::DlpRulesManager::Restriction::kFiles); if (level == policy::DlpRulesManager::Level::kBlock) restricted = true; }
diff --git a/chrome/browser/ash/login/session/user_session_manager.cc b/chrome/browser/ash/login/session/user_session_manager.cc index 936dba00..bcfa22d3 100644 --- a/chrome/browser/ash/login/session/user_session_manager.cc +++ b/chrome/browser/ash/login/session/user_session_manager.cc
@@ -620,6 +620,10 @@ // TODO(nkostylev): Fix this hack by improving Authenticator dependencies. authenticator_->SetConsumer(consumer); } + + for (auto& observer : authenticator_observer_list_) { + observer.OnAuthAttemptStarted(); + } return authenticator_; } @@ -966,6 +970,16 @@ session_state_observer_list_.RemoveObserver(observer); } +void UserSessionManager::AddUserAuthenticatorObserver( + ash::UserAuthenticatorObserver* observer) { + authenticator_observer_list_.AddObserver(observer); +} + +void UserSessionManager::RemoveUserAuthenticatorObserver( + ash::UserAuthenticatorObserver* observer) { + authenticator_observer_list_.RemoveObserver(observer); +} + void UserSessionManager::OnSessionRestoreStateChanged( Profile* user_profile, OAuth2LoginManager::SessionRestoreState state) {
diff --git a/chrome/browser/ash/login/session/user_session_manager.h b/chrome/browser/ash/login/session/user_session_manager.h index 9fdcc5b..816045d 100644 --- a/chrome/browser/ash/login/session/user_session_manager.h +++ b/chrome/browser/ash/login/session/user_session_manager.h
@@ -92,6 +92,12 @@ virtual ~UserSessionStateObserver(); }; +class UserAuthenticatorObserver : public base::CheckedObserver { + public: + // Called when authentication is started. + virtual void OnAuthAttemptStarted() {} +}; + // UserSessionManager is responsible for starting user session which includes: // * load and initialize Profile (including custom Profile preferences), // * mark user as logged in and notify observers, @@ -276,6 +282,10 @@ void AddSessionStateObserver(ash::UserSessionStateObserver* observer); void RemoveSessionStateObserver(ash::UserSessionStateObserver* observer); + void AddUserAuthenticatorObserver(ash::UserAuthenticatorObserver* observer); + void RemoveUserAuthenticatorObserver( + ash::UserAuthenticatorObserver* observer); + void ActiveUserChanged(user_manager::User* active_user) override; // Returns default IME state for user session. @@ -588,6 +598,9 @@ base::ObserverList<ash::UserSessionStateObserver>::Unchecked session_state_observer_list_; + base::ObserverList<ash::UserAuthenticatorObserver> + authenticator_observer_list_; + // Set of user_id for those users that we should restore authentication // session when notified about online state change. SigninSessionRestoreStateSet pending_signin_restore_sessions_;
diff --git a/chrome/browser/ash/policy/dlp/dlp_rules_manager.h b/chrome/browser/ash/policy/dlp/dlp_rules_manager.h index 7bbfb9a..e782018 100644 --- a/chrome/browser/ash/policy/dlp/dlp_rules_manager.h +++ b/chrome/browser/ash/policy/dlp/dlp_rules_manager.h
@@ -72,6 +72,12 @@ virtual Level IsRestricted(const GURL& source, Restriction restriction) const = 0; + // Returns the highest possible restriction enforcement level for + // 'restriction' given that data comes from 'source' and the destination might + // be any. ALLOW level rules are ignored. + virtual Level IsRestrictedByAnyRule(const GURL& source, + Restriction restriction) const = 0; + // Returns the enforcement level for `restriction` given that data comes // from `source` and requested to be shared to `destination`. ALLOW is // returned if there is no matching rule. Requires `restriction` to be
diff --git a/chrome/browser/ash/policy/dlp/dlp_rules_manager_impl.cc b/chrome/browser/ash/policy/dlp/dlp_rules_manager_impl.cc index 5df9ec9..59a26b01 100644 --- a/chrome/browser/ash/policy/dlp/dlp_rules_manager_impl.cc +++ b/chrome/browser/ash/policy/dlp/dlp_rules_manager_impl.cc
@@ -143,8 +143,8 @@ const DlpRulesManager::Restriction restriction, const std::map<RuleId, T>& selected_rules, const std::map<DlpRulesManager::Restriction, - std::map<RuleId, DlpRulesManager::Level>>& - restrictions_map) { + std::map<RuleId, DlpRulesManager::Level>>& restrictions_map, + const bool ignore_allow = false) { auto restriction_it = restrictions_map.find(restriction); if (restriction_it == restrictions_map.end()) return std::make_pair(DlpRulesManager::Level::kAllow, absl::nullopt); @@ -160,6 +160,10 @@ if (restriction_rule_itr == restriction_rules.end()) { continue; } + if (ignore_allow && + restriction_rule_itr->second == DlpRulesManager::Level::kAllow) { + continue; + } if (restriction_rule_itr->second > max_level.first) { max_level.first = restriction_rule_itr->second; max_level.second = rule_pair.second; @@ -219,6 +223,19 @@ .first; } +DlpRulesManager::Level DlpRulesManagerImpl::IsRestrictedByAnyRule( + const GURL& source, + Restriction restriction) const { + DCHECK(src_url_matcher_); + + const RulesConditionsMap src_rules_map = MatchUrlAndGetRulesMapping( + source, src_url_matcher_.get(), src_url_rules_mapping_); + + return GetMaxJoinRestrictionLevel(restriction, src_rules_map, + restrictions_map_, /*ignore_allow=*/true) + .first; +} + DlpRulesManager::Level DlpRulesManagerImpl::IsRestrictedDestination( const GURL& source, const GURL& destination,
diff --git a/chrome/browser/ash/policy/dlp/dlp_rules_manager_impl.h b/chrome/browser/ash/policy/dlp/dlp_rules_manager_impl.h index add659bc..b49b3ed 100644 --- a/chrome/browser/ash/policy/dlp/dlp_rules_manager_impl.h +++ b/chrome/browser/ash/policy/dlp/dlp_rules_manager_impl.h
@@ -34,6 +34,8 @@ // DlpRulesManager: Level IsRestricted(const GURL& source, Restriction restriction) const override; + Level IsRestrictedByAnyRule(const GURL& source, + Restriction restriction) const override; Level IsRestrictedDestination( const GURL& source, const GURL& destination,
diff --git a/chrome/browser/ash/policy/dlp/dlp_rules_manager_impl_unittest.cc b/chrome/browser/ash/policy/dlp/dlp_rules_manager_impl_unittest.cc index 629218f..74bed70 100644 --- a/chrome/browser/ash/policy/dlp/dlp_rules_manager_impl_unittest.cc +++ b/chrome/browser/ash/policy/dlp/dlp_rules_manager_impl_unittest.cc
@@ -148,6 +148,9 @@ EXPECT_EQ(DlpRulesManager::Level::kBlock, dlp_rules_manager_.IsRestricted( GURL(kExampleUrl), DlpRulesManager::Restriction::kScreenshot)); + EXPECT_EQ(DlpRulesManager::Level::kBlock, + dlp_rules_manager_.IsRestrictedByAnyRule( + GURL(kExampleUrl), DlpRulesManager::Restriction::kClipboard)); histogram_tester_.ExpectUniqueSample( GetDlpHistogramPrefix() + dlp::kDlpPolicyPresentUMA, true, 1); histogram_tester_.ExpectBucketCount("Enterprise.Dlp.RestrictionConfigured",
diff --git a/chrome/browser/ash/policy/dlp/mock_dlp_rules_manager.h b/chrome/browser/ash/policy/dlp/mock_dlp_rules_manager.h index f0ed747..a1da57d 100644 --- a/chrome/browser/ash/policy/dlp/mock_dlp_rules_manager.h +++ b/chrome/browser/ash/policy/dlp/mock_dlp_rules_manager.h
@@ -18,6 +18,9 @@ MOCK_CONST_METHOD2(IsRestricted, Level(const GURL& source, Restriction restriction)); + MOCK_CONST_METHOD2(IsRestrictedByAnyRule, + Level(const GURL& source, Restriction restriction)); + MOCK_CONST_METHOD5(IsRestrictedDestination, Level(const GURL& source, const GURL& destination,
diff --git a/chrome/browser/browser_switcher/browser_switcher_prefs.h b/chrome/browser/browser_switcher/browser_switcher_prefs.h index 8ac4729..c6ce08b 100644 --- a/chrome/browser/browser_switcher/browser_switcher_prefs.h +++ b/chrome/browser/browser_switcher/browser_switcher_prefs.h
@@ -42,8 +42,8 @@ // values in policy_templates.json. enum class ParsingMode { kDefault = 0, - kStrict = 1, - kMaxValue = kStrict, // Always keep up-to-date. + kIESiteListMode = 1, + kMaxValue = kIESiteListMode, // Always keep up-to-date. }; // Contains the current state of the prefs related to LBS. For sensitive prefs,
diff --git a/chrome/browser/browser_switcher/browser_switcher_sitelist.cc b/chrome/browser/browser_switcher/browser_switcher_sitelist.cc index 81dced4b..a2b0ec2 100644 --- a/chrome/browser/browser_switcher/browser_switcher_sitelist.cc +++ b/chrome/browser/browser_switcher/browser_switcher_sitelist.cc
@@ -36,16 +36,35 @@ base::StringPiece spec_without_port; }; -// Returns true if |input| contains |token|, ignoring case for ASCII -// characters. -bool StringContainsInsensitiveASCII(base::StringPiece input, - base::StringPiece token) { - const char* found = - std::search(input.begin(), input.end(), token.begin(), token.end(), - [](char a, char b) { - return base::ToLowerASCII(a) == base::ToLowerASCII(b); - }); - return found != input.end(); +// Find the position of |token| inside |input|, if present. Ignore case for +// ASCII characters. +// +// If |token| is not in |input|, return a pointer to the null-byte at the end +// of |input|. +const char* StringFindInsensitiveASCII(base::StringPiece input, + base::StringPiece token) { + return std::search(input.begin(), input.end(), token.begin(), token.end(), + [](char a, char b) { + return base::ToLowerASCII(a) == base::ToLowerASCII(b); + }); +} + +// Find the position of |token| inside |input|, much like StringPiece::find(). +// Search case-sensitively if |case_sensitive_ascii| is true, or +// case-insensitively otherwise. +// +// Returns StringPiece::npos if not found. +size_t StringFind(base::StringPiece input, + base::StringPiece token, + bool case_sensitive_ascii) { + if (case_sensitive_ascii) { + return input.find(token); + } else { + const char* pos = StringFindInsensitiveASCII(input, token); + if (pos == input.end()) + return base::StringPiece::npos; + return pos - input.data(); + } } // Case-insensitively compare the hostname of |host_and_port| with the hostname @@ -100,15 +119,16 @@ return true; } if (pattern.find('/') != base::StringPiece::npos) { - // Check prefix using the normalized URL. Case sensitive, but with - // case-insensitive scheme/hostname. - size_t pos = url.spec.find(pattern); + // Check that the prefix is valid. The URL's hostname/scheme have already + // been case-normalized, so that part of the URL is always case-insensitive. + bool case_sensitive = parsing_mode == ParsingMode::kDefault; + size_t pos = StringFind(url.spec, pattern, case_sensitive); if (pos != base::StringPiece::npos && IsValidPrefix(base::StringPiece(url.spec.data(), pos))) { return true; } if (!url.spec_without_port.empty()) { - pos = url.spec_without_port.find(pattern); + pos = StringFind(url.spec_without_port, pattern, case_sensitive); return pos != base::StringPiece::npos && IsValidPrefix( base::StringPiece(url.spec_without_port.data(), pos)); @@ -118,12 +138,14 @@ // Compare hosts and ports, case-insensitive. switch (parsing_mode) { - case ParsingMode::kStrict: + case ParsingMode::kIESiteListMode: return MatchesHostNameAtEnd(url.host_and_port, pattern); - case ParsingMode::kDefault: + case ParsingMode::kDefault: { // Simple substring search. - return StringContainsInsensitiveASCII(url.host_and_port, pattern); + const char* it = StringFindInsensitiveASCII(url.host_and_port, pattern); + return it != url.host_and_port.end(); + } default: // This should've been caught in
diff --git a/chrome/browser/browser_switcher/browser_switcher_sitelist_unittest.cc b/chrome/browser/browser_switcher/browser_switcher_sitelist_unittest.cc index 511e747..7f9fa63 100644 --- a/chrome/browser/browser_switcher/browser_switcher_sitelist_unittest.cc +++ b/chrome/browser/browser_switcher/browser_switcher_sitelist_unittest.cc
@@ -134,7 +134,7 @@ // For backwards compatibility, this should also match, even if it's not the // same host. - EXPECT_EQ(parsing_mode() != ParsingMode::kStrict, + EXPECT_EQ(parsing_mode() != ParsingMode::kIESiteListMode, ShouldSwitch(GURL("https://notexample.com/"))); } @@ -159,7 +159,8 @@ EXPECT_TRUE(ShouldSwitch(GURL("http://example.com/foobar?query=param"))); EXPECT_FALSE(ShouldSwitch(GURL("http://example.com/"))); EXPECT_FALSE(ShouldSwitch(GURL("https://example.com/foobar"))); - EXPECT_FALSE(ShouldSwitch(GURL("HTTP://EXAMPLE.COM/FOOBAR"))); + EXPECT_EQ(parsing_mode() == ParsingMode::kIESiteListMode, + ShouldSwitch(GURL("HTTP://EXAMPLE.COM/FOOBAR"))); EXPECT_FALSE(ShouldSwitch(GURL("http://subdomain.example.com/"))); EXPECT_FALSE(ShouldSwitch(GURL("http://google.com/"))); } @@ -220,11 +221,11 @@ // A hostname rule (no "/") can match at the beginning of the hostname, not // just at the end. Initialize({"10.", "subdomain"}, {}); - EXPECT_EQ(parsing_mode() == ParsingMode::kStrict + EXPECT_EQ(parsing_mode() == ParsingMode::kIESiteListMode ? Decision(kStay, kDefault, "") : Decision(kGo, kSitelist, "10."), GetDecision(GURL("http://10.0.0.1/"))); - EXPECT_EQ(parsing_mode() == ParsingMode::kStrict + EXPECT_EQ(parsing_mode() == ParsingMode::kIESiteListMode ? Decision(kStay, kDefault, "") : Decision(kGo, kSitelist, "subdomain"), GetDecision(GURL("http://subdomain.example.com/"))); @@ -330,7 +331,7 @@ INSTANTIATE_TEST_SUITE_P(ParsingMode, BrowserSwitcherSitelistTest, testing::Values(ParsingMode::kDefault, - ParsingMode::kStrict, + ParsingMode::kIESiteListMode, // 999 should behave like kDefault static_cast<ParsingMode>(999)));
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc index 31404dc0..070745d3 100644 --- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc +++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc
@@ -888,9 +888,13 @@ .get(); if (password_store) { - password_store->RemoveStatisticsByOriginAndTime( - nullable_filter, delete_begin_, delete_end_, - CreateTaskCompletionClosure(TracingDataType::kPasswordsStatistics)); + password_manager::SmartBubbleStatsStore* stats_store = + password_store->GetSmartBubbleStatsStore(); + if (stats_store) { + stats_store->RemoveStatisticsByOriginAndTime( + nullable_filter, delete_begin_, delete_end_, + CreateTaskCompletionClosure(TracingDataType::kPasswordsStatistics)); + } password_store->RemoveFieldInfoByTime( delete_begin_, delete_end_, CreateTaskCompletionClosure(TracingDataType::kFieldInfo));
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc index 0f388a1..562fa0b 100644 --- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc +++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc
@@ -1166,6 +1166,30 @@ return completion_observer.failed_data_types(); } + void ExpectRemoveLoginsByURLAndTime( + password_manager::MockPasswordStore* store) { + EXPECT_CALL(*store, RemoveLoginsByURLAndTime) + .WillOnce( + testing::WithArgs<3, 4>([](auto callback, auto sync_callback) { + std::move(callback).Run(); + if (sync_callback) + std::move(sync_callback).Run(false); + })); + } + + void ExpectRemoveLoginsByURLAndTimeWithFilter( + password_manager::MockPasswordStore* store, + base::RepeatingCallback<bool(const GURL&)> filter) { + EXPECT_CALL(*store, RemoveLoginsByURLAndTime(ProbablySameFilter(filter), _, + _, _, _)) + .WillOnce( + testing::WithArgs<3, 4>([](auto callback, auto sync_callback) { + std::move(callback).Run(); + if (sync_callback) + std::move(sync_callback).Run(false); + })); + } + void BlockUntilOriginDataRemoved( const base::Time& delete_begin, const base::Time& delete_end, @@ -1418,7 +1442,7 @@ // Expect that passwords will be deleted, as they do not depend // on |prefs::kAllowDeletingBrowserHistory|. RemovePasswordsTester tester(GetProfile()); - EXPECT_CALL(*tester.profile_store(), RemoveLoginsByURLAndTimeImpl(_, _, _)); + ExpectRemoveLoginsByURLAndTime(tester.profile_store()); uint64_t removal_mask = constants::DATA_TYPE_HISTORY | constants::DATA_TYPE_PASSWORDS; @@ -1991,12 +2015,8 @@ TEST_F(ChromeBrowsingDataRemoverDelegateTest, RemovePasswordsByTimeOnly) { RemovePasswordsTester tester(GetProfile()); - base::RepeatingCallback<bool(const GURL&)> filter = - BrowsingDataFilterBuilder::BuildNoopFilter(); - EXPECT_CALL(*tester.profile_store(), - RemoveLoginsByURLAndTimeImpl(ProbablySameFilter(filter), _, _)) - .WillOnce(Return(password_manager::PasswordStoreChangeList())); + ExpectRemoveLoginsByURLAndTime(tester.profile_store()); BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(), constants::DATA_TYPE_PASSWORDS, false); @@ -2012,9 +2032,7 @@ builder->AddRegisterableDomain(kTestRegisterableDomain1); base::RepeatingCallback<bool(const GURL&)> filter = builder->BuildUrlFilter(); - EXPECT_CALL(*tester.profile_store(), - RemoveLoginsByURLAndTimeImpl(ProbablySameFilter(filter), _, _)) - .WillOnce(Return(password_manager::PasswordStoreChangeList())); + ExpectRemoveLoginsByURLAndTimeWithFilter(tester.profile_store(), filter); BlockUntilOriginDataRemoved(base::Time(), base::Time::Max(), constants::DATA_TYPE_PASSWORDS, std::move(builder)); @@ -2040,8 +2058,7 @@ base::RepeatingCallback<bool(const GURL&)> empty_filter = BrowsingDataFilterBuilder::BuildNoopFilter(); - EXPECT_CALL(*tester.profile_store(), RemoveLoginsByURLAndTimeImpl(_, _, _)) - .WillOnce(Return(password_manager::PasswordStoreChangeList())); + ExpectRemoveLoginsByURLAndTime(tester.profile_store()); EXPECT_CALL(*tester.profile_store(), DisableAutoSignInForOriginsImpl(ProbablySameFilter(empty_filter))) .WillOnce(Return(password_manager::PasswordStoreChangeList())); @@ -3081,12 +3098,9 @@ RemovePasswordsByTimeOnly_WithAccountStore) { RemovePasswordsTester tester(GetProfile()); - EXPECT_CALL(*tester.profile_store(), RemoveLoginsByURLAndTimeImpl(_, _, _)) - .WillOnce(Return(password_manager::PasswordStoreChangeList())); - + ExpectRemoveLoginsByURLAndTime(tester.profile_store()); // Only DATA_TYPE_PASSWORDS is cleared. Accounts passwords are not affected. - EXPECT_CALL(*tester.account_store(), RemoveLoginsByURLAndTimeImpl(_, _, _)) - .Times(0); + EXPECT_CALL(*tester.account_store(), RemoveLoginsByURLAndTime).Times(0); BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(), constants::DATA_TYPE_PASSWORDS, false); @@ -3096,11 +3110,8 @@ RemoveAccountPasswordsByTimeOnly_WithAccountStore) { RemovePasswordsTester tester(GetProfile()); - EXPECT_CALL(*tester.profile_store(), RemoveLoginsByURLAndTimeImpl(_, _, _)) - .Times(0); - - EXPECT_CALL(*tester.account_store(), RemoveLoginsByURLAndTimeImpl(_, _, _)) - .WillOnce(Return(password_manager::PasswordStoreChangeList())); + EXPECT_CALL(*tester.profile_store(), RemoveLoginsByURLAndTime).Times(0); + ExpectRemoveLoginsByURLAndTime(tester.account_store()); // For the account store, the remover delegate also waits until all the // deletions have propagated to the Sync server. Pretend that happens // immediately. @@ -3115,19 +3126,13 @@ RemoveAccountPasswordsByTimeOnly_WithAccountStore_Failure) { RemovePasswordsTester tester(GetProfile()); - EXPECT_CALL(*tester.profile_store(), RemoveLoginsByURLAndTimeImpl(_, _, _)) - .Times(0); - - EXPECT_CALL(*tester.account_store(), RemoveLoginsByURLAndTimeImpl(_, _, _)) - .WillOnce(Return(password_manager::PasswordStoreChangeList())); + EXPECT_CALL(*tester.profile_store(), RemoveLoginsByURLAndTime).Times(0); + ExpectRemoveLoginsByURLAndTime(tester.account_store()); // For the account store, the remover delegate also waits until all the // deletions have propagated to the Sync server. In this test, that never // happens. EXPECT_CALL(*tester.account_metadata_store(), HasUnsyncedDeletions()) .WillRepeatedly(Return(true)); - // Bypass the (usually 30-second) timeout until the PasswordStore reports - // failure. - tester.account_store()->SetSyncTaskTimeoutForTest(base::TimeDelta()); uint64_t failed_data_types = BlockUntilBrowsingDataRemoved( base::Time(), base::Time::Max(), constants::DATA_TYPE_ACCOUNT_PASSWORDS,
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index 7b8c65164..59e2665 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -2943,8 +2943,6 @@ "policy/server_backed_state/server_backed_state_keys_broker.h", "policy/status_collector/activity_storage.cc", "policy/status_collector/activity_storage.h", - "policy/status_collector/affiliated_session_service.cc", - "policy/status_collector/affiliated_session_service.h", "policy/status_collector/app_info_generator.cc", "policy/status_collector/app_info_generator.h", "policy/status_collector/child_activity_storage.cc", @@ -2956,6 +2954,8 @@ "policy/status_collector/enterprise_activity_storage.cc", "policy/status_collector/enterprise_activity_storage.h", "policy/status_collector/interval_map.h", + "policy/status_collector/managed_session_service.cc", + "policy/status_collector/managed_session_service.h", "policy/status_collector/status_collector.cc", "policy/status_collector/status_collector.h", "policy/status_collector/status_collector_state.cc", @@ -4236,10 +4236,10 @@ "policy/server_backed_state/device_cloud_state_keys_uploader_unittest.cc", "policy/server_backed_state/server_backed_state_keys_broker_unittest.cc", "policy/status_collector/activity_storage_unittest.cc", - "policy/status_collector/affiliated_session_service_unittest.cc", "policy/status_collector/app_info_generator_unittest.cc", "policy/status_collector/enterprise_activity_storage_unittest.cc", "policy/status_collector/interval_map_unittest.cc", + "policy/status_collector/managed_session_service_unittest.cc", "policy/uploading/heartbeat_scheduler_unittest.cc", "policy/uploading/status_uploader_unittest.cc", "policy/uploading/system_log_uploader_unittest.cc",
diff --git a/chrome/browser/chromeos/extensions/accessibility_features_apitest.cc b/chrome/browser/chromeos/extensions/accessibility_features_apitest.cc index 57c0419..cbe5f8e 100644 --- a/chrome/browser/chromeos/extensions/accessibility_features_apitest.cc +++ b/chrome/browser/chromeos/extensions/accessibility_features_apitest.cc
@@ -271,9 +271,7 @@ // Tests that an extension with modify permission can modify accessibility // features, while an extension that doesn't have the permission can't. -// -// Disabled for being flaky (https://crbug.com/1225390). -IN_PROC_BROWSER_TEST_P(AccessibilityFeaturesApiTest, DISABLED_Set) { +IN_PROC_BROWSER_TEST_P(AccessibilityFeaturesApiTest, Set) { // WARNING: Make sure that features which load Chrome extension are not // enabled at this point (before the test app is loaded), as that may break // the test:
diff --git a/chrome/browser/chromeos/full_restore/full_restore_app_launch_handler_browsertest.cc b/chrome/browser/chromeos/full_restore/full_restore_app_launch_handler_browsertest.cc index 924287d7..ab25997 100644 --- a/chrome/browser/chromeos/full_restore/full_restore_app_launch_handler_browsertest.cc +++ b/chrome/browser/chromeos/full_restore/full_restore_app_launch_handler_browsertest.cc
@@ -199,17 +199,6 @@ ::full_restore::SaveWindowInfo(window_info); } -void WaitForAppLaunchInfoSaved() { - ::full_restore::FullRestoreSaveHandler* save_handler = - ::full_restore::FullRestoreSaveHandler::GetInstance(); - base::OneShotTimer* timer = save_handler->GetTimerForTesting(); - if (timer->IsRunning()) { - // Simulate timeout, and the launch info is saved. - timer->FireNow(); - } - content::RunAllTasksUntilIdle(); -} - std::string GetTestApp1Id(const std::string& package_name) { return ArcAppListPrefs::GetAppId(package_name, kTestAppActivity); } @@ -329,6 +318,20 @@ return nullptr; } + void WaitForAppLaunchInfoSaved() { + ::full_restore::FullRestoreSaveHandler* save_handler = + ::full_restore::FullRestoreSaveHandler::GetInstance(); + base::OneShotTimer* timer = save_handler->GetTimerForTesting(); + if (timer->IsRunning()) { + // Simulate timeout, and the launch info is saved. + timer->FireNow(); + } + content::RunAllTasksUntilIdle(); + + ::full_restore::FullRestoreReadHandler::GetInstance() + ->profile_path_to_restore_data_.clear(); + } + void SaveChromeAppLaunchInfo(const std::string& app_id) { ::full_restore::SaveAppLaunchInfo( profile()->GetPath(), @@ -2142,6 +2145,20 @@ web_app::SystemAppType::MEDIA); } + void WaitForAppLaunchInfoSaved() { + ::full_restore::FullRestoreSaveHandler* save_handler = + ::full_restore::FullRestoreSaveHandler::GetInstance(); + base::OneShotTimer* timer = save_handler->GetTimerForTesting(); + if (timer->IsRunning()) { + // Simulate timeout, and the launch info is saved. + timer->FireNow(); + } + content::RunAllTasksUntilIdle(); + + ::full_restore::FullRestoreReadHandler::GetInstance() + ->profile_path_to_restore_data_.clear(); + } + private: base::test::ScopedFeatureList scoped_feature_list_; };
diff --git a/chrome/browser/chromeos/full_restore/full_restore_service_unittest.cc b/chrome/browser/chromeos/full_restore/full_restore_service_unittest.cc index 5e70d0e..1429e62 100644 --- a/chrome/browser/chromeos/full_restore/full_restore_service_unittest.cc +++ b/chrome/browser/chromeos/full_restore/full_restore_service_unittest.cc
@@ -12,6 +12,7 @@ #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h" #include "chrome/browser/chromeos/full_restore/full_restore_prefs.h" #include "chrome/browser/chromeos/full_restore/full_restore_service_factory.h" +#include "chrome/browser/first_run/first_run.h" #include "chrome/browser/notifications/notification_display_service_tester.h" #include "chrome/browser/prefs/session_startup_pref.h" #include "chrome/common/chrome_switches.h" @@ -21,8 +22,10 @@ #include "components/full_restore/app_launch_info.h" #include "components/full_restore/features.h" #include "components/full_restore/full_restore_info.h" +#include "components/full_restore/full_restore_read_handler.h" #include "components/full_restore/full_restore_save_handler.h" #include "components/full_restore/full_restore_utils.h" +#include "components/full_restore/restore_data.h" #include "components/sync/base/client_tag_hash.h" #include "components/sync/base/model_type.h" #include "components/sync/model/sync_change.h" @@ -243,6 +246,9 @@ timer->FireNow(); content::RunAllTasksUntilIdle(); + + ::full_restore::FullRestoreReadHandler::GetInstance() + ->profile_path_to_restore_data_.clear(); } }; @@ -290,6 +296,7 @@ kRestoreAppsAndPagesPrefName, static_cast<int>(RestoreOption::kAskEveryTime)); + first_run::ResetCachedSentinelDataForTesting(); base::CommandLine::ForCurrentProcess()->AppendSwitch( switches::kForceFirstRun); @@ -298,6 +305,10 @@ EXPECT_EQ(RestoreOption::kAskEveryTime, GetRestoreOption()); VerifyNotification(false, false); + + base::CommandLine::ForCurrentProcess()->RemoveSwitch( + switches::kForceFirstRun); + first_run::ResetCachedSentinelDataForTesting(); } // For a brand new user, if sync off, set 'Ask Every Time' as the default value,
diff --git a/chrome/browser/chromeos/policy/status_collector/affiliated_session_service.cc b/chrome/browser/chromeos/policy/status_collector/affiliated_session_service.cc deleted file mode 100644 index 5162988d..0000000 --- a/chrome/browser/chromeos/policy/status_collector/affiliated_session_service.cc +++ /dev/null
@@ -1,104 +0,0 @@ -// 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 "chrome/browser/chromeos/policy/status_collector/affiliated_session_service.h" - -#include "base/logging.h" -#include "chrome/browser/ash/profiles/profile_helper.h" - -namespace policy { - -namespace { - -constexpr base::TimeDelta kMinimumSuspendDuration = - base::TimeDelta::FromMinutes(1); - -bool IsPrimaryAndAffiliated(Profile* profile) { - user_manager::User* user = - chromeos::ProfileHelper::Get()->GetUserByProfile(profile); - bool is_primary = chromeos::ProfileHelper::Get()->IsPrimaryProfile(profile); - bool is_affiliated = user && user->IsAffiliated(); - if (!is_primary || !is_affiliated) { - VLOG(1) << "The profile for the primary user is not associated with an " - "affiliated user."; - } - return is_primary && is_affiliated; -} - -} // namespace - -AffiliatedSessionService::AffiliatedSessionService(base::Clock* clock) - : clock_(clock), session_manager_(session_manager::SessionManager::Get()) { - if (session_manager_) { - // To alleviate tight coupling in unit tests to DeviceStatusCollector. - session_manager_observation_.Observe(session_manager_); - is_session_locked_ = session_manager_->IsScreenLocked(); - } - power_manager_observation_.Observe(chromeos::PowerManagerClient::Get()); -} - -AffiliatedSessionService::~AffiliatedSessionService() = default; - -void AffiliatedSessionService::AddObserver( - AffiliatedSessionService::Observer* observer) { - observers_.AddObserver(observer); -} - -void AffiliatedSessionService::RemoveObserver( - AffiliatedSessionService::Observer* observer) { - observers_.RemoveObserver(observer); -} - -void AffiliatedSessionService::OnSessionStateChanged() { - bool is_session_locked = session_manager_->IsScreenLocked(); - if (is_session_locked_ == is_session_locked) { - return; - } - is_session_locked_ = is_session_locked; - - if (is_session_locked_) { - for (auto& observer : observers_) { - observer.OnLocked(); - } - } else { - for (auto& observer : observers_) { - observer.OnUnlocked(); - } - } -} - -void AffiliatedSessionService::OnUserProfileLoaded( - const AccountId& account_id) { - Profile* profile = - chromeos::ProfileHelper::Get()->GetProfileByAccountId(account_id); - if (!IsPrimaryAndAffiliated(profile)) { - return; - } - profile_observations_.AddObservation(profile); - for (auto& observer : observers_) { - observer.OnAffiliatedLogin(profile); - } -} - -void AffiliatedSessionService::OnProfileWillBeDestroyed(Profile* profile) { - is_session_locked_ = false; - if (!IsPrimaryAndAffiliated(profile)) { - return; - } - for (auto& observer : observers_) { - observer.OnAffiliatedLogout(profile); - } - profile_observations_.RemoveObservation(profile); -} - -void AffiliatedSessionService::SuspendDone(base::TimeDelta sleep_duration) { - if (sleep_duration < kMinimumSuspendDuration) { - return; - } - for (auto& observer : observers_) { - observer.OnResumeActive(clock_->Now() - sleep_duration); - } -} - -} // namespace policy
diff --git a/chrome/browser/chromeos/policy/status_collector/affiliated_session_service.h b/chrome/browser/chromeos/policy/status_collector/affiliated_session_service.h deleted file mode 100644 index ca2b1b2..0000000 --- a/chrome/browser/chromeos/policy/status_collector/affiliated_session_service.h +++ /dev/null
@@ -1,88 +0,0 @@ -// 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 CHROME_BROWSER_CHROMEOS_POLICY_STATUS_COLLECTOR_AFFILIATED_SESSION_SERVICE_H_ -#define CHROME_BROWSER_CHROMEOS_POLICY_STATUS_COLLECTOR_AFFILIATED_SESSION_SERVICE_H_ - -#include "base/observer_list.h" -#include "base/observer_list_types.h" -#include "base/scoped_multi_source_observation.h" -#include "base/scoped_observation.h" -#include "base/time/clock.h" -#include "base/time/default_clock.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/profiles/profile_observer.h" -#include "chromeos/dbus/power/power_manager_client.h" -#include "components/account_id/account_id.h" -#include "components/session_manager/core/session_manager.h" -#include "components/session_manager/core/session_manager_observer.h" - -namespace policy { - -class AffiliatedSessionService : public session_manager::SessionManagerObserver, - public ProfileObserver, - public chromeos::PowerManagerClient::Observer { - public: - class Observer : public base::CheckedObserver { - public: - // Occurs when an affiliated primary user has logged in. - virtual void OnAffiliatedLogin(Profile* profile) {} - - // Occurs when an affiliated primary user has logged out. - virtual void OnAffiliatedLogout(Profile* profile) {} - - // Occurs when the active user has locked the user session. - virtual void OnLocked() {} - - // Occurs when the active user has unlocked the user session. - virtual void OnUnlocked() {} - - // Occurs when the device recovers from a suspend state, where - // |suspend_time| is the time when the suspend state - // first occurred. Short duration suspends are not reported. - virtual void OnResumeActive(base::Time suspend_time) {} - }; - - explicit AffiliatedSessionService( - base::Clock* clock = base::DefaultClock::GetInstance()); - AffiliatedSessionService(const AffiliatedSessionService&) = delete; - AffiliatedSessionService& operator=(const AffiliatedSessionService&) = delete; - ~AffiliatedSessionService() override; - - void AddObserver(Observer* observer); - - void RemoveObserver(Observer* observer); - - // session_manager::SessionManagerObserver::Observer - void OnSessionStateChanged() override; - void OnUserProfileLoaded(const AccountId& account_id) override; - - // ProfileObserver - void OnProfileWillBeDestroyed(Profile* profile) override; - - // chromeos::PowerManagerClient::Observer - void SuspendDone(base::TimeDelta sleep_duration) override; - - private: - bool is_session_locked_; - - base::Clock* clock_; - - base::ObserverList<Observer> observers_; - - session_manager::SessionManager* const session_manager_; - - base::ScopedMultiSourceObservation<Profile, ProfileObserver> - profile_observations_{this}; - base::ScopedObservation<session_manager::SessionManager, - session_manager::SessionManagerObserver> - session_manager_observation_{this}; - base::ScopedObservation<chromeos::PowerManagerClient, - chromeos::PowerManagerClient::Observer> - power_manager_observation_{this}; -}; - -} // namespace policy - -#endif // CHROME_BROWSER_CHROMEOS_POLICY_STATUS_COLLECTOR_AFFILIATED_SESSION_SERVICE_H_
diff --git a/chrome/browser/chromeos/policy/status_collector/app_info_generator.cc b/chrome/browser/chromeos/policy/status_collector/app_info_generator.cc index 1f96fc0..1178770 100644 --- a/chrome/browser/chromeos/policy/status_collector/app_info_generator.cc +++ b/chrome/browser/chromeos/policy/status_collector/app_info_generator.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/chromeos/policy/status_collector/app_info_generator.h" #include "chrome/browser/apps/app_service/app_service_proxy_factory.h" +#include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/web_applications/web_app_provider_factory.h" #include "chrome/browser/web_applications/web_app_registrar.h" @@ -19,6 +20,18 @@ namespace { +bool IsPrimaryAndAffiliated(Profile* profile) { + user_manager::User* user = + chromeos::ProfileHelper::Get()->GetUserByProfile(profile); + bool is_primary = chromeos::ProfileHelper::Get()->IsPrimaryProfile(profile); + bool is_affiliated = user && user->IsAffiliated(); + if (!is_primary || !is_affiliated) { + VLOG(1) << "The profile for the primary user is not associated with an " + "affiliated user."; + } + return is_primary && is_affiliated; +} + em::AppInfo::Status ExtractStatus(const apps::mojom::Readiness readiness) { switch (readiness) { case apps::mojom::Readiness::kReady: @@ -78,10 +91,15 @@ AppInfoGenerator::AppInfoProvider::~AppInfoProvider() = default; AppInfoGenerator::AppInfoGenerator( + ManagedSessionService* managed_session_service, base::TimeDelta max_stored_past_activity_interval, base::Clock* clock) : max_stored_past_activity_interval_(max_stored_past_activity_interval), - clock_(*clock) {} + clock_(*clock) { + if (managed_session_service) { + managed_session_observation_.Observe(managed_session_service); + } +} AppInfoGenerator::AppInstances::AppInstances(const base::Time start_time_) : start_time(start_time_) {} @@ -153,7 +171,11 @@ SetIdleDurationsToOpen(); } -void AppInfoGenerator::OnAffiliatedLogin(Profile* profile) { +void AppInfoGenerator::OnLogin(Profile* profile) { + if (!IsPrimaryAndAffiliated(profile)) { + return; + } + if (!apps::AppServiceProxyFactory::IsAppServiceAvailableForProfile(profile)) { VLOG(1) << "No apps available. Will not track usage."; return; @@ -168,7 +190,11 @@ } } -void AppInfoGenerator::OnAffiliatedLogout(Profile* profile) { +void AppInfoGenerator::OnLogout(Profile* profile) { + if (!IsPrimaryAndAffiliated(profile)) { + return; + } + if (provider_) { if (should_report_) { provider_->app_service_proxy.InstanceRegistry().RemoveObserver(this);
diff --git a/chrome/browser/chromeos/policy/status_collector/app_info_generator.h b/chrome/browser/chromeos/policy/status_collector/app_info_generator.h index c315a1b..89d0b601 100644 --- a/chrome/browser/chromeos/policy/status_collector/app_info_generator.h +++ b/chrome/browser/chromeos/policy/status_collector/app_info_generator.h
@@ -13,7 +13,7 @@ #include "base/time/default_clock.h" #include "chrome/browser/apps/app_service/app_service_proxy.h" #include "chrome/browser/chromeos/policy/status_collector/activity_storage.h" -#include "chrome/browser/chromeos/policy/status_collector/affiliated_session_service.h" +#include "chrome/browser/chromeos/policy/status_collector/managed_session_service.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "components/prefs/pref_registry_simple.h" #include "components/services/app_service/public/cpp/instance.h" @@ -30,11 +30,12 @@ // A class that is responsible for collecting application inventory and usage // information. class AppInfoGenerator : public apps::InstanceRegistry::Observer, - public AffiliatedSessionService::Observer { + public ManagedSessionService::Observer { public: using Result = absl::optional<std::vector<enterprise_management::AppInfo>>; explicit AppInfoGenerator( + ManagedSessionService* managed_session_service, base::TimeDelta max_stored_past_activity_interval, base::Clock* clock = base::DefaultClock::GetInstance()); AppInfoGenerator(const AppInfoGenerator&) = delete; @@ -59,9 +60,9 @@ // up until the current time, so it may be reported. void OnWillReport(); - // AffiliatedSessionManager::Observer - void OnAffiliatedLogin(Profile* profile) override; - void OnAffiliatedLogout(Profile* profile) override; + // ManagedSessionService::Observer + void OnLogin(Profile* profile) override; + void OnLogout(Profile* profile) override; void OnLocked() override; void OnUnlocked() override; void OnResumeActive(base::Time suspend_time) override; @@ -122,6 +123,10 @@ base::TimeDelta max_stored_past_activity_interval_; const base::Clock& clock_; + + base::ScopedObservation<ManagedSessionService, + ManagedSessionService::Observer> + managed_session_observation_{this}; }; } // namespace policy
diff --git a/chrome/browser/chromeos/policy/status_collector/app_info_generator_unittest.cc b/chrome/browser/chromeos/policy/status_collector/app_info_generator_unittest.cc index 5b646ea..cb504b0e 100644 --- a/chrome/browser/chromeos/policy/status_collector/app_info_generator_unittest.cc +++ b/chrome/browser/chromeos/policy/status_collector/app_info_generator_unittest.cc
@@ -166,11 +166,24 @@ GetInstanceRegistry().OnInstances(deltas); } + std::unique_ptr<TestingProfile> CreateProfile(const AccountId& account_id, + bool is_affiliated = true) { + TestingProfile::Builder profile_builder; + profile_builder.SetProfileName(account_id.GetUserEmail()); + auto profile = profile_builder.Build(); + user_manager_->AddUserWithAffiliationAndTypeAndProfile( + account_id, is_affiliated, user_manager::UserType::USER_TYPE_REGULAR, + profile.get()); + return profile; + } + void SetUp() override { auto user_manager = std::make_unique<ash::FakeChromeUserManager>(); + user_manager_ = user_manager.get(); user_manager_enabler_ = std::make_unique<user_manager::ScopedUserManager>( std::move(user_manager)); - profile_ = std::make_unique<TestingProfile>(); + account_id_ = AccountId::FromUserEmail("affiliated@managed.com"); + profile_ = CreateProfile(account_id_); test_clock().SetNow(MakeLocalTime("25-MAR-2020 1:30am")); web_app::WebAppProviderFactory::GetInstance()->SetTestingFactoryAndUse( @@ -206,13 +219,13 @@ std::unique_ptr<AppInfoGenerator> GetGenerator( base::TimeDelta max_stored_past_activity_interval = base::TimeDelta::FromDays(0)) { - return std::make_unique<AppInfoGenerator>(max_stored_past_activity_interval, - &test_clock()); + return std::make_unique<AppInfoGenerator>( + nullptr, max_stored_past_activity_interval, &test_clock()); } std::unique_ptr<AppInfoGenerator> GetReadyGenerator() { auto generator = GetGenerator(); - generator->OnAffiliatedLogin(profile()); + generator->OnLogin(profile()); generator->OnReportingChanged(true); return generator; } @@ -239,6 +252,10 @@ Profile* profile() { return profile_.get(); } + ash::FakeChromeUserManager* user_manager() { return user_manager_; } + + AccountId account_id() { return account_id_; } + static auto EqActivity(const base::Time& start_time, const base::Time& end_time) { return AllOf( @@ -265,8 +282,10 @@ apps::ScopedOmitPluginVmAppsForTesting scoped_omit_plugin_vm_apps_for_testing_; content::BrowserTaskEnvironment task_environment_; + AccountId account_id_; std::unique_ptr<TestingProfile> profile_; web_app::WebAppRegistrarMutable* app_registrar_; + ash::FakeChromeUserManager* user_manager_; std::unique_ptr<user_manager::ScopedUserManager> user_manager_enabler_; TestingPrefServiceSimple pref_service_; @@ -283,6 +302,7 @@ PushApp("c", "ThirdApp", apps::mojom::Readiness::kUninstalledByUser, "", apps::mojom::AppType::kCrostini); + user_manager()->LoginUser(account_id(), true); auto generator = GetReadyGenerator(); auto result = generator->Generate(); @@ -297,6 +317,7 @@ } TEST_F(AppInfoGeneratorTest, GenerateWebApp) { + user_manager()->LoginUser(account_id(), true); auto generator = GetReadyGenerator(); PushApp("c", "App", apps::mojom::Readiness::kUninstalledByUser, "", apps::mojom::AppType::kWeb); @@ -321,6 +342,7 @@ } TEST_F(AppInfoGeneratorTest, MultipleInstances) { + user_manager()->LoginUser(account_id(), true); auto generator = GetReadyGenerator(); PushApp("a", "FirstApp", apps::mojom::Readiness::kDisabledByPolicy, "1.1", apps::mojom::AppType::kArc); @@ -347,18 +369,54 @@ } TEST_F(AppInfoGeneratorTest, ShouldNotReport) { + user_manager()->LoginUser(account_id(), true); PushApp("a", "FirstApp", apps::mojom::Readiness::kDisabledByPolicy, "1.1", apps::mojom::AppType::kArc); auto generator = GetGenerator(); generator->OnReportingChanged(false); - generator->OnAffiliatedLogin(profile()); + generator->OnLogin(profile()); + auto result = generator->Generate(); + + EXPECT_FALSE(result.has_value()); +} + +TEST_F(AppInfoGeneratorTest, UnaffiliatedUser) { + auto unaffiliated_account_id = + AccountId::FromUserEmail("unaffiliated@unmanaged.com"); + auto unaffiliated_profile = + CreateProfile(unaffiliated_account_id, /* is_affiliated= */ false); + user_manager()->LoginUser(unaffiliated_account_id, true); + PushApp("a", "FirstApp", apps::mojom::Readiness::kDisabledByPolicy, "1.1", + apps::mojom::AppType::kArc); + + auto generator = GetGenerator(); + generator->OnReportingChanged(true); + generator->OnLogin(unaffiliated_profile.get()); + auto result = generator->Generate(); + + EXPECT_FALSE(result.has_value()); +} + +TEST_F(AppInfoGeneratorTest, SecondaryUser) { + user_manager()->LoginUser(account_id(), true); + auto secondary_account_id = AccountId::FromUserEmail("secondary@managed.com"); + auto secondary_profile = + CreateProfile(secondary_account_id, /* is_affiliated= */ true); + user_manager()->LoginUser(secondary_account_id, true); + PushApp("a", "FirstApp", apps::mojom::Readiness::kDisabledByPolicy, "1.1", + apps::mojom::AppType::kArc); + + auto generator = GetGenerator(); + generator->OnReportingChanged(true); + generator->OnLogin(secondary_profile.get()); auto result = generator->Generate(); EXPECT_FALSE(result.has_value()); } TEST_F(AppInfoGeneratorTest, OnReportedSuccessfully) { + user_manager()->LoginUser(account_id(), true); auto generator = GetReadyGenerator(); PushApp("a", "FirstApp", apps::mojom::Readiness::kDisabledByPolicy, "1.1", apps::mojom::AppType::kArc); @@ -388,6 +446,7 @@ } TEST_F(AppInfoGeneratorTest, OnWillReport) { + user_manager()->LoginUser(account_id(), true); auto generator = GetReadyGenerator(); PushApp("a", "FirstApp", apps::mojom::Readiness::kDisabledByPolicy, "1.1", apps::mojom::AppType::kArc); @@ -426,12 +485,13 @@ } TEST_F(AppInfoGeneratorTest, OnLogoutOnLogin) { + user_manager()->LoginUser(account_id(), true); PushApp("a", "FirstApp", apps::mojom::Readiness::kDisabledByPolicy, "1.1", apps::mojom::AppType::kArc); auto generator = GetGenerator(); generator->OnReportingChanged(true); - generator->OnAffiliatedLogin(profile()); - generator->OnAffiliatedLogout(profile()); + generator->OnLogin(profile()); + generator->OnLogout(profile()); Instance app_instance("a"); test_clock().SetNow(MakeLocalTime("29-MAR-2020 1:30pm")); PushAppInstance(app_instance, apps::InstanceState::kStarted); @@ -443,7 +503,7 @@ EXPECT_FALSE(result.has_value()); - generator->OnAffiliatedLogin(profile()); + generator->OnLogin(profile()); test_clock().SetNow(MakeLocalTime("30-MAR-2020 2:30pm")); PushAppInstance(app_instance, apps::InstanceState::kStarted); @@ -462,6 +522,7 @@ } TEST_F(AppInfoGeneratorTest, OnLocked) { + user_manager()->LoginUser(account_id(), true); auto generator = GetReadyGenerator(); PushApp("a", "FirstApp", apps::mojom::Readiness::kDisabledByPolicy, "1.1", apps::mojom::AppType::kArc); @@ -484,6 +545,7 @@ } TEST_F(AppInfoGeneratorTest, OnUnlocked) { + user_manager()->LoginUser(account_id(), true); auto generator = GetReadyGenerator(); PushApp("a", "FirstApp", apps::mojom::Readiness::kDisabledByPolicy, "1.1", apps::mojom::AppType::kArc); @@ -512,6 +574,7 @@ } TEST_F(AppInfoGeneratorTest, OnResumeActive) { + user_manager()->LoginUser(account_id(), true); auto generator = GetReadyGenerator(); PushApp("a", "FirstApp", apps::mojom::Readiness::kDisabledByPolicy, "1.1", apps::mojom::AppType::kArc); @@ -540,6 +603,7 @@ } TEST_F(AppInfoGeneratorTest, OnLoginRemoveOldUsage) { + user_manager()->LoginUser(account_id(), true); PushApp("a", "FirstApp", apps::mojom::Readiness::kDisabledByPolicy, "1.1", apps::mojom::AppType::kArc); PushApp("b", "SecondApp", apps::mojom::Readiness::kReady, "1.2", @@ -548,7 +612,7 @@ 1); // Exclude all past usage except for UTC today and yesterday. auto generator = GetGenerator(max_days_past); generator->OnReportingChanged(true); - generator->OnAffiliatedLogin(profile()); + generator->OnLogin(profile()); Instance app_instance1("a"); test_clock().SetNow(MakeLocalTime("28-MAR-2020 1:30am")); @@ -561,9 +625,9 @@ test_clock().SetNow(MakeLocalTime("29-MAR-2020 3:30am")); PushAppInstance(app_instance2, apps::InstanceState::kDestroyed); - generator->OnAffiliatedLogout(profile()); + generator->OnLogout(profile()); test_clock().SetNow(MakeLocalTime("30-MAR-2020 11:00am")); - generator->OnAffiliatedLogin(profile()); + generator->OnLogin(profile()); auto result = generator->Generate();
diff --git a/chrome/browser/chromeos/policy/status_collector/device_status_collector.cc b/chrome/browser/chromeos/policy/status_collector/device_status_collector.cc index 127983a4..3d8f2a4 100644 --- a/chrome/browser/chromeos/policy/status_collector/device_status_collector.cc +++ b/chrome/browser/chromeos/policy/status_collector/device_status_collector.cc
@@ -1443,7 +1443,9 @@ graphics_status_fetcher_(graphics_status_fetcher), crash_report_info_fetcher_(crash_report_info_fetcher), power_manager_(chromeos::PowerManagerClient::Get()), - app_info_generator_(kMaxStoredPastActivityInterval, clock_) { + app_info_generator_(&managed_session_service_, + kMaxStoredPastActivityInterval, + clock_) { // protected fields of `StatusCollector`. max_stored_past_activity_interval_ = kMaxStoredPastActivityInterval; max_stored_future_activity_interval_ = kMaxStoredFutureActivityInterval; @@ -1547,8 +1549,7 @@ stats_reporting_pref_subscription_ = cros_settings_->AddSettingsObserver( chromeos::kStatsReportingPref, callback); - affiliated_session_service_.AddObserver(&app_info_generator_); - + // TODO(b/191986061):: consider using ScopedObservation instead. power_manager_->AddObserver(this); // Fetch the current values of the policies. @@ -1603,7 +1604,6 @@ DeviceStatusCollector::~DeviceStatusCollector() { power_manager_->RemoveObserver(this); - affiliated_session_service_.RemoveObserver(&app_info_generator_); } // static
diff --git a/chrome/browser/chromeos/policy/status_collector/device_status_collector.h b/chrome/browser/chromeos/policy/status_collector/device_status_collector.h index b64d0cd7..7816073 100644 --- a/chrome/browser/chromeos/policy/status_collector/device_status_collector.h +++ b/chrome/browser/chromeos/policy/status_collector/device_status_collector.h
@@ -211,8 +211,8 @@ static void RegisterPrefs(PrefRegistrySimple* registry); - AffiliatedSessionService* GetAffiliatedSessionServiceForTesting() { - return &affiliated_session_service_; + ManagedSessionService* GetManagedSessionServiceForTesting() { + return &managed_session_service_; } // How often to poll to see if the user is idle. @@ -480,7 +480,7 @@ base::CallbackListSubscription app_info_subscription_; base::CallbackListSubscription stats_reporting_pref_subscription_; - AffiliatedSessionService affiliated_session_service_; + ManagedSessionService managed_session_service_; AppInfoGenerator app_info_generator_;
diff --git a/chrome/browser/chromeos/policy/status_collector/device_status_collector_browsertest.cc b/chrome/browser/chromeos/policy/status_collector/device_status_collector_browsertest.cc index 4704e9e..a8e183d8 100644 --- a/chrome/browser/chromeos/policy/status_collector/device_status_collector_browsertest.cc +++ b/chrome/browser/chromeos/policy/status_collector/device_status_collector_browsertest.cc
@@ -947,7 +947,7 @@ options->crash_report_info_fetcher = base::BindRepeating(&GetEmptyCrashReportInfo); options->app_info_generator = std::make_unique<policy::AppInfoGenerator>( - base::TimeDelta::FromDays(0)); + nullptr, base::TimeDelta::FromDays(0)); return options; } @@ -3608,8 +3608,8 @@ MockRegularUserWithAffiliation(account_id, true); scoped_testing_cros_settings_.device_settings()->SetBoolean( chromeos::kReportDeviceAppInfo, true); - status_collector_->GetAffiliatedSessionServiceForTesting() - ->OnUserProfileLoaded(account_id); + status_collector_->GetManagedSessionServiceForTesting()->OnUserProfileLoaded( + account_id); auto* app_proxy = apps::AppServiceProxyFactory::GetForProfile(testing_profile_.get()); auto app1 = apps::mojom::App::New();
diff --git a/chrome/browser/chromeos/policy/status_collector/managed_session_service.cc b/chrome/browser/chromeos/policy/status_collector/managed_session_service.cc new file mode 100644 index 0000000..35184f3 --- /dev/null +++ b/chrome/browser/chromeos/policy/status_collector/managed_session_service.cc
@@ -0,0 +1,110 @@ +// 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 "chrome/browser/chromeos/policy/status_collector/managed_session_service.h" + +#include "base/logging.h" +#include "chrome/browser/ash/login/existing_user_controller.h" +#include "chrome/browser/ash/profiles/profile_helper.h" +#include "components/user_manager/user_manager.h" + +namespace policy { + +namespace { + +constexpr base::TimeDelta kMinimumSuspendDuration = + base::TimeDelta::FromMinutes(1); + +} // namespace + +ManagedSessionService::ManagedSessionService(base::Clock* clock) + : clock_(clock), session_manager_(session_manager::SessionManager::Get()) { + if (session_manager_) { + // To alleviate tight coupling in unit tests to DeviceStatusCollector. + session_manager_observation_.Observe(session_manager_); + is_session_locked_ = session_manager_->IsScreenLocked(); + } + if (user_manager::UserManager::IsInitialized()) { + authenticator_observation_.Observe(ash::UserSessionManager::GetInstance()); + } + power_manager_observation_.Observe(chromeos::PowerManagerClient::Get()); +} + +ManagedSessionService::~ManagedSessionService() { + if (ash::ExistingUserController::current_controller()) { + ash::ExistingUserController::current_controller() + ->RemoveLoginStatusConsumer(this); + } +} + +void ManagedSessionService::AddObserver( + ManagedSessionService::Observer* observer) { + observers_.AddObserver(observer); +} + +void ManagedSessionService::RemoveObserver( + ManagedSessionService::Observer* observer) { + observers_.RemoveObserver(observer); +} + +void ManagedSessionService::OnSessionStateChanged() { + bool is_session_locked = session_manager_->IsScreenLocked(); + if (is_session_locked_ == is_session_locked) { + return; + } + is_session_locked_ = is_session_locked; + + if (is_session_locked_) { + for (auto& observer : observers_) { + observer.OnLocked(); + } + } else { + for (auto& observer : observers_) { + observer.OnUnlocked(); + } + } +} + +void ManagedSessionService::OnUserProfileLoaded(const AccountId& account_id) { + Profile* profile = + chromeos::ProfileHelper::Get()->GetProfileByAccountId(account_id); + profile_observations_.AddObservation(profile); + for (auto& observer : observers_) { + observer.OnLogin(profile); + } +} + +void ManagedSessionService::OnProfileWillBeDestroyed(Profile* profile) { + is_session_locked_ = false; + for (auto& observer : observers_) { + observer.OnLogout(profile); + } + profile_observations_.RemoveObservation(profile); +} + +void ManagedSessionService::SuspendDone(base::TimeDelta sleep_duration) { + if (sleep_duration < kMinimumSuspendDuration) { + return; + } + for (auto& observer : observers_) { + observer.OnResumeActive(clock_->Now() - sleep_duration); + } +} + +void ManagedSessionService::OnAuthAttemptStarted() { + if (ash::ExistingUserController::current_controller()) { + ash::ExistingUserController::current_controller() + ->RemoveLoginStatusConsumer(this); + ash::ExistingUserController::current_controller()->AddLoginStatusConsumer( + this); + } +} + +void ManagedSessionService::OnAuthFailure(const chromeos::AuthFailure& error) { + for (auto& observer : observers_) { + observer.OnLoginFailure(error); + } +} + +} // namespace policy
diff --git a/chrome/browser/chromeos/policy/status_collector/managed_session_service.h b/chrome/browser/chromeos/policy/status_collector/managed_session_service.h new file mode 100644 index 0000000..52f6d4bb --- /dev/null +++ b/chrome/browser/chromeos/policy/status_collector/managed_session_service.h
@@ -0,0 +1,107 @@ +// 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 CHROME_BROWSER_CHROMEOS_POLICY_STATUS_COLLECTOR_MANAGED_SESSION_SERVICE_H_ +#define CHROME_BROWSER_CHROMEOS_POLICY_STATUS_COLLECTOR_MANAGED_SESSION_SERVICE_H_ + +#include "base/observer_list.h" +#include "base/observer_list_types.h" +#include "base/scoped_multi_source_observation.h" +#include "base/scoped_observation.h" +#include "base/time/clock.h" +#include "base/time/default_clock.h" +#include "chrome/browser/ash/login/session/user_session_manager.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_observer.h" +#include "chromeos/dbus/power/power_manager_client.h" +#include "chromeos/login/auth/auth_status_consumer.h" +#include "components/account_id/account_id.h" +#include "components/session_manager/core/session_manager.h" +#include "components/session_manager/core/session_manager_observer.h" + +namespace policy { + +class ManagedSessionService : public session_manager::SessionManagerObserver, + public ProfileObserver, + public chromeos::PowerManagerClient::Observer, + public chromeos::AuthStatusConsumer, + public ash::UserAuthenticatorObserver { + public: + class Observer : public base::CheckedObserver { + public: + // Occurs when a user's login attempt fails. + virtual void OnLoginFailure(const chromeos::AuthFailure& error) {} + + // Occurs when a user has logged in. + virtual void OnLogin(Profile* profile) {} + + // Occurs when a user has logged out. + virtual void OnLogout(Profile* profile) {} + + // Occurs when the active user has locked the user session. + virtual void OnLocked() {} + + // Occurs when the active user has unlocked the user session. + virtual void OnUnlocked() {} + + // Occurs when the device recovers from a suspend state, where + // |suspend_time| is the time when the suspend state + // first occurred. Short duration suspends are not reported. + virtual void OnResumeActive(base::Time suspend_time) {} + }; + + explicit ManagedSessionService( + base::Clock* clock = base::DefaultClock::GetInstance()); + ManagedSessionService(const ManagedSessionService&) = delete; + ManagedSessionService& operator=(const ManagedSessionService&) = delete; + ~ManagedSessionService() override; + + void AddObserver(Observer* observer); + + void RemoveObserver(Observer* observer); + + // session_manager::SessionManagerObserver::Observer + void OnSessionStateChanged() override; + void OnUserProfileLoaded(const AccountId& account_id) override; + + // ProfileObserver + void OnProfileWillBeDestroyed(Profile* profile) override; + + // chromeos::PowerManagerClient::Observer + void SuspendDone(base::TimeDelta sleep_duration) override; + + void OnAuthSuccess(const ash::UserContext& user_context) override {} + + void OnAuthFailure(const chromeos::AuthFailure& error) override; + + void OnAuthAttemptStarted() override; + + private: + bool is_session_locked_; + + base::Clock* clock_; + + base::ObserverList<Observer> observers_; + + session_manager::SessionManager* const session_manager_; + + base::ScopedMultiSourceObservation<Profile, ProfileObserver> + profile_observations_{this}; + base::ScopedObservation<session_manager::SessionManager, + session_manager::SessionManagerObserver> + session_manager_observation_{this}; + base::ScopedObservation<chromeos::PowerManagerClient, + chromeos::PowerManagerClient::Observer> + power_manager_observation_{this}; + base::ScopedObservation< + ash::UserSessionManager, + ash::UserAuthenticatorObserver, + &ash::UserSessionManager::AddUserAuthenticatorObserver, + &ash::UserSessionManager::RemoveUserAuthenticatorObserver> + authenticator_observation_{this}; +}; + +} // namespace policy + +#endif // CHROME_BROWSER_CHROMEOS_POLICY_STATUS_COLLECTOR_MANAGED_SESSION_SERVICE_H_
diff --git a/chrome/browser/chromeos/policy/status_collector/affiliated_session_service_unittest.cc b/chrome/browser/chromeos/policy/status_collector/managed_session_service_unittest.cc similarity index 73% rename from chrome/browser/chromeos/policy/status_collector/affiliated_session_service_unittest.cc rename to chrome/browser/chromeos/policy/status_collector/managed_session_service_unittest.cc index cffd115..da195126 100644 --- a/chrome/browser/chromeos/policy/status_collector/affiliated_session_service_unittest.cc +++ b/chrome/browser/chromeos/policy/status_collector/managed_session_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/chromeos/policy/status_collector/affiliated_session_service.h" +#include "chrome/browser/chromeos/policy/status_collector/managed_session_service.h" #include "base/test/simple_test_clock.h" #include "chrome/browser/ash/login/users/chrome_user_manager.h" @@ -17,9 +17,9 @@ namespace policy { -class AffiliatedSessionServiceTest +class ManagedSessionServiceTest : public ::testing::Test, - public policy::AffiliatedSessionService::Observer { + public policy::ManagedSessionService::Observer { protected: using SessionState = session_manager::SessionState; @@ -30,12 +30,12 @@ user_manager_enabler_ = std::make_unique<user_manager::ScopedUserManager>( std::move(user_manager)); - affiliated_session_service_ = - std::make_unique<AffiliatedSessionService>(&test_clock_); + managed_session_service_ = + std::make_unique<ManagedSessionService>(&test_clock_); } void TearDown() override { - affiliated_session_service_.reset(); + managed_session_service_.reset(); chromeos::PowerManagerClient::Shutdown(); } @@ -54,8 +54,8 @@ return profile; } - AffiliatedSessionService* affiliated_session_service() { - return affiliated_session_service_.get(); + ManagedSessionService* managed_session_service() { + return managed_session_service_.get(); } session_manager::SessionManager* session_manager() { @@ -68,14 +68,19 @@ base::SimpleTestClock* test_clock() { return &test_clock_; } - void OnAffiliatedLogin(Profile* profile) override { logged_in_ = profile; } - void OnAffiliatedLogout(Profile* profile) override { logged_out_ = profile; } + void OnLoginFailure(const chromeos::AuthFailure& error) override { + auth_failure_ = error; + } + void OnLogin(Profile* profile) override { logged_in_ = profile; } + void OnLogout(Profile* profile) override { logged_out_ = profile; } void OnLocked() override { locked_ = true; } void OnUnlocked() override { unlocked_ = true; } void OnResumeActive(base::Time time) override { suspend_time_ = std::make_unique<base::Time>(time); } + chromeos::AuthFailure auth_failure_ = + chromeos::AuthFailure::AuthFailureNone(); Profile* logged_in_ = nullptr; Profile* logged_out_ = nullptr; bool locked_ = false; @@ -92,11 +97,11 @@ base::SimpleTestClock test_clock_; - std::unique_ptr<AffiliatedSessionService> affiliated_session_service_; + std::unique_ptr<ManagedSessionService> managed_session_service_; }; -TEST_F(AffiliatedSessionServiceTest, OnSessionStateChanged) { - affiliated_session_service()->AddObserver(this); +TEST_F(ManagedSessionServiceTest, OnSessionStateChanged) { + managed_session_service()->AddObserver(this); session_manager()->SetSessionState(SessionState::LOCKED); session_manager()->SetSessionState(SessionState::ACTIVE); @@ -129,49 +134,49 @@ EXPECT_TRUE(unlocked_); } -TEST_F(AffiliatedSessionServiceTest, OnUserProfileLoadedAffiliatedAndPrimary) { +TEST_F(ManagedSessionServiceTest, OnUserProfileLoadedAffiliatedAndPrimary) { AccountId affiliated_account_id = AccountId::FromUserEmail("user0@managed.com"); std::unique_ptr<TestingProfile> affiliated_profile = CreateProfile( affiliated_account_id, true /* affiliated */, true /* login */); - affiliated_session_service()->AddObserver(this); + managed_session_service()->AddObserver(this); session_manager()->NotifyUserProfileLoaded(affiliated_account_id); EXPECT_TRUE(affiliated_profile->IsSameOrParent(logged_in_)); } -TEST_F(AffiliatedSessionServiceTest, OnUserProfileLoadedAffiliated) { +TEST_F(ManagedSessionServiceTest, OnUserProfileLoadedAffiliated) { AccountId secondary_account_id = AccountId::FromUserEmail("user3@managed.com"); std::unique_ptr<TestingProfile> secondary_profile = CreateProfile( secondary_account_id, true /* affiliated */, false /* login */); - affiliated_session_service()->AddObserver(this); + managed_session_service()->AddObserver(this); session_manager()->NotifyUserProfileLoaded(secondary_account_id); - EXPECT_EQ(logged_in_, nullptr); + EXPECT_TRUE(secondary_profile->IsSameOrParent(logged_in_)); } -TEST_F(AffiliatedSessionServiceTest, OnUserProfileLoadedPrimary) { +TEST_F(ManagedSessionServiceTest, OnUserProfileLoadedPrimary) { AccountId unaffiliated_account_id = AccountId::FromUserEmail("user2@managed.com"); std::unique_ptr<TestingProfile> unaffiliated_profile = CreateProfile( unaffiliated_account_id, false /* affiliated */, true /* login */); - affiliated_session_service()->AddObserver(this); + managed_session_service()->AddObserver(this); session_manager()->NotifyUserProfileLoaded(unaffiliated_account_id); - EXPECT_EQ(logged_in_, nullptr); + EXPECT_TRUE(unaffiliated_profile->IsSameOrParent(logged_in_)); } -TEST_F(AffiliatedSessionServiceTest, +TEST_F(ManagedSessionServiceTest, OnProfileWillBeDestroyedAffiliatedAndPrimary) { AccountId affiliated_account_id = AccountId::FromUserEmail("user0@managed.com"); std::unique_ptr<TestingProfile> affiliated_profile = CreateProfile( affiliated_account_id, true /* affiliated */, true /* login */); - affiliated_session_service()->AddObserver(this); + managed_session_service()->AddObserver(this); session_manager()->NotifyUserProfileLoaded(affiliated_account_id); affiliated_profile->MaybeSendDestroyedNotification(); @@ -179,34 +184,34 @@ EXPECT_TRUE(affiliated_profile->IsSameOrParent(logged_out_)); } -TEST_F(AffiliatedSessionServiceTest, OnProfileWillBeDestroyedAffiliated) { +TEST_F(ManagedSessionServiceTest, OnProfileWillBeDestroyedAffiliated) { AccountId secondary_account_id = AccountId::FromUserEmail("user3@managed.com"); std::unique_ptr<TestingProfile> secondary_profile = CreateProfile( secondary_account_id, true /* affiliated */, false /* login */); - affiliated_session_service()->AddObserver(this); + managed_session_service()->AddObserver(this); session_manager()->NotifyUserProfileLoaded(secondary_account_id); secondary_profile->MaybeSendDestroyedNotification(); - EXPECT_EQ(logged_out_, nullptr); + EXPECT_TRUE(secondary_profile->IsSameOrParent(logged_in_)); } -TEST_F(AffiliatedSessionServiceTest, OnProfileWillBeDestroyedPrimary) { +TEST_F(ManagedSessionServiceTest, OnProfileWillBeDestroyedPrimary) { AccountId unaffiliated_account_id = AccountId::FromUserEmail("user2@managed.com"); std::unique_ptr<TestingProfile> unaffiliated_profile = CreateProfile( unaffiliated_account_id, false /* affiliated */, true /* login */); - affiliated_session_service()->AddObserver(this); + managed_session_service()->AddObserver(this); session_manager()->NotifyUserProfileLoaded(unaffiliated_account_id); unaffiliated_profile->MaybeSendDestroyedNotification(); - EXPECT_EQ(logged_out_, nullptr); + EXPECT_TRUE(unaffiliated_profile->IsSameOrParent(logged_in_)); } -TEST_F(AffiliatedSessionServiceTest, SuspendDone) { - affiliated_session_service()->AddObserver(this); +TEST_F(ManagedSessionServiceTest, SuspendDone) { + managed_session_service()->AddObserver(this); test_clock()->SetNow(base::Time::Now()); base::TimeDelta sleep_duration = base::TimeDelta::FromHours(2); @@ -215,13 +220,13 @@ EXPECT_EQ(*suspend_time_, test_clock()->Now() - sleep_duration); } -TEST_F(AffiliatedSessionServiceTest, RemoveObserver) { +TEST_F(ManagedSessionServiceTest, RemoveObserver) { AccountId account_id = AccountId::FromUserEmail("user0@managed.com"); std::unique_ptr<TestingProfile> profile = CreateProfile(account_id, true /* affiliated */, true /* login */); - affiliated_session_service()->AddObserver(this); + managed_session_service()->AddObserver(this); - affiliated_session_service()->RemoveObserver(this); + managed_session_service()->RemoveObserver(this); session_manager()->SetSessionState(SessionState::LOCKED); session_manager()->SetSessionState(SessionState::ACTIVE); @@ -236,4 +241,14 @@ EXPECT_FALSE(profile->IsSameOrParent(logged_out_)); } +TEST_F(ManagedSessionServiceTest, LoginFailure) { + managed_session_service()->AddObserver(this); + + managed_session_service()->OnAuthFailure(chromeos::AuthFailure( + chromeos::AuthFailure::FailureReason::OWNER_REQUIRED)); + + EXPECT_EQ(auth_failure_.reason(), + chromeos::AuthFailure::FailureReason::OWNER_REQUIRED); +} + } // namespace policy
diff --git a/chrome/browser/device_api/device_attribute_api.cc b/chrome/browser/device_api/device_attribute_api.cc index 31311476..66bc6edd 100644 --- a/chrome/browser/device_api/device_attribute_api.cc +++ b/chrome/browser/device_api/device_attribute_api.cc
@@ -22,9 +22,13 @@ using Result = blink::mojom::DeviceAttributeResult; +const char kNotAllowedOriginErrorMessage[] = + "The current origin cannot use this web API because it is not allowed by " + "the DeviceAttributesAllowedForOrigins policy."; + #if !BUILDFLAG(IS_CHROMEOS_ASH) && !BUILDFLAG(IS_CHROMEOS_LACROS) const char kNotSupportedPlatformErrorMessage[] = - "This restricted web API is not supported on the current platform."; + "This web API is not supported on the current platform."; #endif #if BUILDFLAG(IS_CHROMEOS_LACROS) @@ -46,6 +50,12 @@ } // namespace +void ReportNotAllowedError( + base::OnceCallback<void(DeviceAttributeResultPtr)> callback) { + std::move(callback).Run( + Result::NewErrorMessage(kNotAllowedOriginErrorMessage)); +} + void GetDirectoryId(DeviceAPIService::GetDirectoryIdCallback callback) { #if BUILDFLAG(IS_CHROMEOS_ASH) const std::string attribute = g_browser_process->platform_part()
diff --git a/chrome/browser/device_api/device_attribute_api.h b/chrome/browser/device_api/device_attribute_api.h index 9275d53..e13fea68 100644 --- a/chrome/browser/device_api/device_attribute_api.h +++ b/chrome/browser/device_api/device_attribute_api.h
@@ -8,9 +8,12 @@ #include "third_party/blink/public/mojom/device/device.mojom.h" using blink::mojom::DeviceAPIService; +using blink::mojom::DeviceAttributeResultPtr; namespace device_attribute_api { +void ReportNotAllowedError( + base::OnceCallback<void(DeviceAttributeResultPtr)> callback); void GetDirectoryId(DeviceAPIService::GetDirectoryIdCallback callback); void GetHostname(DeviceAPIService::GetHostnameCallback callback); void GetSerialNumber(DeviceAPIService::GetSerialNumberCallback callback);
diff --git a/chrome/browser/device_api/device_service_impl.cc b/chrome/browser/device_api/device_service_impl.cc index a8167a1..2fbe734a 100644 --- a/chrome/browser/device_api/device_service_impl.cc +++ b/chrome/browser/device_api/device_service_impl.cc
@@ -5,6 +5,9 @@ #include <memory> +#include "base/containers/contains.h" +#include "build/chromeos_buildflags.h" +#include "chrome/browser/app_mode/app_mode_utils.h" #include "chrome/browser/device_api/device_attribute_api.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/web_applications/components/policy/web_app_policy_constants.h" @@ -15,8 +18,64 @@ #include "mojo/public/cpp/bindings/pending_receiver.h" #include "url/origin.h" +#if BUILDFLAG(IS_CHROMEOS_ASH) +#include "chrome/browser/ash/app_mode/web_app/web_kiosk_app_data.h" +#include "chrome/browser/ash/app_mode/web_app/web_kiosk_app_manager.h" +#include "chrome/browser/ash/login/app_mode/kiosk_launch_controller.h" +#endif + namespace { +// Check whether the target origin is allowed to access to the device +// attributes. +bool CanAccessDeviceAttributes(const PrefService* prefs, + const url::Origin& origin) { + const base::ListValue* prefs_list = + prefs->GetList(prefs::kDeviceAttributesAllowedForOrigins); + if (!prefs_list) + return false; + + return base::Contains(prefs_list->GetList(), origin, [](const auto& entry) { + return url::Origin::Create(GURL(entry.GetString())); + }); +} + +// Check whether the target origin is the same as the main application running +// in the Kiosk session. +// TODO(anqing): After Kiosk is migrated to Lacros, the launch url needs to be +// stored in the lacros-browser when the app is launched. Then it can be used to +// compare with |origin|. +bool IsEqualToKioskOrigin(const url::Origin& origin) { +#if BUILDFLAG(IS_CHROMEOS_ASH) + const AccountId& account_id = + user_manager::UserManager::Get()->GetPrimaryUser()->GetAccountId(); + const ash::WebKioskAppData* app_data = + ash::WebKioskAppManager::Get()->GetAppByAccountId(account_id); + return url::Origin::Create(app_data->install_url()) == origin; +#else + return false; +#endif +} + +// Check whether the target origin is included in the WebAppInstallForceList +// policy. +bool IsForceInstalledOrigin(const PrefService* prefs, + const url::Origin& origin) { + const base::ListValue* prefs_list = + prefs->GetList(prefs::kWebAppInstallForceList); + if (!prefs_list) + return false; + + return base::Contains(prefs_list->GetList(), origin, [](const auto& entry) { + std::string entry_url = entry.FindKey(web_app::kUrlKey)->GetString(); + return url::Origin::Create(GURL(entry_url)); + }); +} + +const PrefService* GetPrefs(content::RenderFrameHost* host) { + return Profile::FromBrowserContext(host->GetBrowserContext())->GetPrefs(); +} + bool IsTrustedContext(content::RenderFrameHost* host, const url::Origin& origin) { // TODO(anqing): This feature flag is turned on by default for origin trial. @@ -24,23 +83,11 @@ if (!base::FeatureList::IsEnabled(features::kEnableRestrictedWebApis)) return false; - PrefService* prefs = - Profile::FromBrowserContext(host->GetBrowserContext())->GetPrefs(); - - if (!prefs->GetBoolean( - prefs::kManagedWebAppsAccessToDeviceAttributesAllowed)) { - return false; + if (chrome::IsRunningInAppMode()) { + return IsEqualToKioskOrigin(origin); + } else { + return IsForceInstalledOrigin(GetPrefs(host), origin); } - - // TODO(apotapchuk): Implement a more efficient way of checking the trustness - // status of the app. - for (const base::Value& entry : - prefs->GetList(prefs::kWebAppInstallForceList)->GetList()) { - if (origin == - url::Origin::Create(GURL(entry.FindKey(web_app::kUrlKey)->GetString()))) - return true; - } - return false; } } // namespace @@ -52,7 +99,7 @@ pref_change_registrar_.Init( Profile::FromBrowserContext(host->GetBrowserContext())->GetPrefs()); pref_change_registrar_.Add( - prefs::kManagedWebAppsAccessToDeviceAttributesAllowed, + prefs::kDeviceAttributesAllowedForOrigins, base::BindRepeating(&DeviceServiceImpl::OnDisposingIfNeeded, base::Unretained(this))); pref_change_registrar_.Add( @@ -82,8 +129,7 @@ // static void DeviceServiceImpl::RegisterProfilePrefs(PrefRegistrySimple* registry) { - registry->RegisterBooleanPref( - prefs::kManagedWebAppsAccessToDeviceAttributesAllowed, true); + registry->RegisterListPref(prefs::kDeviceAttributesAllowedForOrigins); } void DeviceServiceImpl::OnDisposingIfNeeded() { @@ -95,23 +141,39 @@ } void DeviceServiceImpl::GetDirectoryId(GetDirectoryIdCallback callback) { - device_attribute_api::GetDirectoryId(std::move(callback)); + GetDeviceAttribute(base::BindOnce(device_attribute_api::GetDirectoryId), + std::move(callback)); } void DeviceServiceImpl::GetHostname(GetHostnameCallback callback) { - device_attribute_api::GetHostname(std::move(callback)); + GetDeviceAttribute(base::BindOnce(device_attribute_api::GetHostname), + std::move(callback)); } void DeviceServiceImpl::GetSerialNumber(GetSerialNumberCallback callback) { - device_attribute_api::GetSerialNumber(std::move(callback)); + GetDeviceAttribute(base::BindOnce(device_attribute_api::GetSerialNumber), + std::move(callback)); } void DeviceServiceImpl::GetAnnotatedAssetId( GetAnnotatedAssetIdCallback callback) { - device_attribute_api::GetAnnotatedAssetId(std::move(callback)); + GetDeviceAttribute(base::BindOnce(device_attribute_api::GetAnnotatedAssetId), + std::move(callback)); } void DeviceServiceImpl::GetAnnotatedLocation( GetAnnotatedLocationCallback callback) { - device_attribute_api::GetAnnotatedLocation(std::move(callback)); + GetDeviceAttribute(base::BindOnce(device_attribute_api::GetAnnotatedLocation), + std::move(callback)); +} + +void DeviceServiceImpl::GetDeviceAttribute( + base::OnceCallback<void(DeviceAttributeCallback)> handler, + DeviceAttributeCallback callback) { + if (!CanAccessDeviceAttributes(GetPrefs(host_), origin())) { + device_attribute_api::ReportNotAllowedError(std::move(callback)); + return; + } + + std::move(handler).Run(std::move(callback)); }
diff --git a/chrome/browser/device_api/device_service_impl.h b/chrome/browser/device_api/device_service_impl.h index d1f4091f..bcdc3493 100644 --- a/chrome/browser/device_api/device_service_impl.h +++ b/chrome/browser/device_api/device_service_impl.h
@@ -19,6 +19,9 @@ class DeviceServiceImpl final : public content::DocumentServiceBase<blink::mojom::DeviceAPIService> { public: + using DeviceAttributeCallback = + base::OnceCallback<void(blink::mojom::DeviceAttributeResultPtr)>; + // Tries to attach this mojo service to |host| for trusted web applications. // Will dynamically disconnect if the trustness status is revoked. static void Create( @@ -44,6 +47,10 @@ content::RenderFrameHost* host, mojo::PendingReceiver<blink::mojom::DeviceAPIService> receiver); + void GetDeviceAttribute( + base::OnceCallback<void(DeviceAttributeCallback)> handler, + DeviceAttributeCallback callback); + void OnDisposingIfNeeded(); content::RenderFrameHost* const host_;
diff --git a/chrome/browser/device_api/device_service_unittest.cc b/chrome/browser/device_api/device_service_unittest.cc index 5586a88..925cb43 100644 --- a/chrome/browser/device_api/device_service_unittest.cc +++ b/chrome/browser/device_api/device_service_unittest.cc
@@ -15,13 +15,34 @@ #include "components/prefs/scoped_user_pref_update.h" #include "content/public/test/browser_task_environment.h" #include "content/public/test/navigation_simulator.h" +#include "content/public/test/web_contents_tester.h" #include "url/gurl.h" +#if BUILDFLAG(IS_CHROMEOS_ASH) +#include "base/command_line.h" +#include "base/test/scoped_command_line.h" +#include "chrome/browser/ash/app_mode/web_app/web_kiosk_app_manager.h" +#include "chrome/browser/ash/login/users/fake_chrome_user_manager.h" +#include "chrome/common/chrome_switches.h" +#include "components/user_manager/scoped_user_manager.h" +#endif + namespace { -constexpr char kDefaultAppInstallUrl[] = "https://example.com/"; +constexpr char kDefaultAppInstallUrl[] = "https://example.com/install"; constexpr char kTrustedUrl[] = "https://example.com/sample"; constexpr char kUntrustedUrl[] = "https://non-example.com/sample"; +constexpr char kKioskAppInstallUrl[] = "https://kiosk.com/install"; + +#if BUILDFLAG(IS_CHROMEOS_ASH) +constexpr char kAppEmail[] = "email@example.com"; +constexpr char kKioskAppUrl[] = "https://kiosk.com/sample"; +constexpr char kInvalidKioskAppUrl[] = "https://invalid-kiosk.com/sample"; +#endif + +void VerifyErrorMessageResult(blink::mojom::DeviceAttributeResultPtr result) { + result->is_error_message(); +} } // namespace @@ -30,6 +51,7 @@ void SetUp() override { ChromeRenderViewHostTestHarness::SetUp(); InstallTrustedApp(); + SetAllowedOrigin(); } void InstallTrustedApp() { @@ -46,15 +68,28 @@ update->ClearList(); } - void TryCreatingService(const GURL& url) { - content::NavigationSimulator::NavigateAndCommitFromBrowser(web_contents(), + void SetAllowedOrigin() { + base::Value allowed_origins(base::Value::Type::LIST); + allowed_origins.Append(base::Value(kTrustedUrl)); + allowed_origins.Append(base::Value(kKioskAppInstallUrl)); + profile()->GetPrefs()->Set(prefs::kDeviceAttributesAllowedForOrigins, + allowed_origins); + } + + void RemoveAllowedOrigin() { + ListPrefUpdate update(profile()->GetPrefs(), + prefs::kDeviceAttributesAllowedForOrigins); + update->ClearList(); + } + + void TryCreatingService(content::WebContents* web_contents, const GURL& url) { + content::NavigationSimulator::NavigateAndCommitFromBrowser(web_contents, url); DeviceServiceImpl::Create(main_rfh(), remote_.BindNewPipeAndPassReceiver()); } - void SetWebAppDeviceAttributesQueryPref(bool allowed) { - profile()->GetPrefs()->SetBoolean( - prefs::kManagedWebAppsAccessToDeviceAttributesAllowed, allowed); + void TryCreatingService(const GURL& url) { + TryCreatingService(web_contents(), url); } mojo::Remote<blink::mojom::DeviceAPIService>* remote() { return &remote_; } @@ -69,20 +104,105 @@ ASSERT_TRUE(remote()->is_connected()); } -TEST_F(DeviceAPIServiceTest, EnableServiceByTurnOnPrefs) { - SetWebAppDeviceAttributesQueryPref(true); +TEST_F(DeviceAPIServiceTest, ReportErrorForDisallowedOrigin) { TryCreatingService(GURL(kTrustedUrl)); + RemoveAllowedOrigin(); + + remote()->get()->GetDirectoryId(base::BindOnce(VerifyErrorMessageResult)); + remote()->get()->GetHostname(base::BindOnce(VerifyErrorMessageResult)); + remote()->get()->GetSerialNumber(base::BindOnce(VerifyErrorMessageResult)); + remote()->get()->GetAnnotatedAssetId( + base::BindOnce(VerifyErrorMessageResult)); + remote()->get()->GetAnnotatedLocation( + base::BindOnce(VerifyErrorMessageResult)); remote()->FlushForTesting(); ASSERT_TRUE(remote()->is_connected()); } -TEST_F(DeviceAPIServiceTest, DisableServiceByTurnOffPrefs) { - SetWebAppDeviceAttributesQueryPref(false); +// The service should be disabled in the Incognito mode. +TEST_F(DeviceAPIServiceTest, IncognitoProfile) { + std::unique_ptr<content::WebContents> incognito_web_contents = + content::WebContentsTester::CreateTestWebContents( + profile()->GetPrimaryOTRProfile(/*create_if_needed=*/true), nullptr); + TryCreatingService(incognito_web_contents.get(), GURL(kTrustedUrl)); + + remote()->FlushForTesting(); + ASSERT_FALSE(remote()->is_connected()); +} + +#if BUILDFLAG(IS_CHROMEOS_ASH) + +class DeviceAPIServiceWithKioskUserTest : public DeviceAPIServiceTest { + public: + DeviceAPIServiceWithKioskUserTest() + : fake_user_manager_(new ash::FakeChromeUserManager()), + scoped_user_manager_(base::WrapUnique(fake_user_manager_)) {} + + void SetUp() override { + DeviceAPIServiceTest::SetUp(); + command_line_.GetProcessCommandLine()->AppendSwitch( + switches::kForceAppMode); + account_id_ = AccountId::FromUserEmail(kAppEmail); + app_manager_ = std::make_unique<ash::WebKioskAppManager>(); + } + + void TearDown() override { + app_manager_.reset(); + DeviceAPIServiceTest::TearDown(); + } + + void LoginKioskUser() { + app_manager()->AddAppForTesting(account_id(), GURL(kKioskAppInstallUrl)); + fake_user_manager()->AddWebKioskAppUser(account_id()); + fake_user_manager()->LoginUser(account_id()); + } + + ash::FakeChromeUserManager* fake_user_manager() const { + return fake_user_manager_; + } + + const AccountId& account_id() const { return account_id_; } + + ash::WebKioskAppManager* app_manager() const { return app_manager_.get(); } + + private: + ash::FakeChromeUserManager* fake_user_manager_; + user_manager::ScopedUserManager scoped_user_manager_; + base::test::ScopedCommandLine command_line_; + AccountId account_id_; + std::unique_ptr<ash::WebKioskAppManager> app_manager_; +}; + +// The service should be enabled if the current origin is same as the origin of +// Kiosk app. +TEST_F(DeviceAPIServiceWithKioskUserTest, EnableServiceForKioskOrigin) { + LoginKioskUser(); + TryCreatingService(GURL(kKioskAppUrl)); + remote()->FlushForTesting(); + ASSERT_TRUE(remote()->is_connected()); +} + +// The service should be disabled if the current origin is different from the +// origin of Kiosk app. +TEST_F(DeviceAPIServiceWithKioskUserTest, DisableServiceForInvalidOrigin) { + LoginKioskUser(); + TryCreatingService(GURL(kInvalidKioskAppUrl)); + remote()->FlushForTesting(); + ASSERT_FALSE(remote()->is_connected()); +} + +// The service should be disabled if the current origin is different from the +// origin of Kiosk app, even if it is trusted (force-installed). +TEST_F(DeviceAPIServiceWithKioskUserTest, + DisableServiceForNonKioskTrustedOrigin) { + LoginKioskUser(); TryCreatingService(GURL(kTrustedUrl)); remote()->FlushForTesting(); ASSERT_FALSE(remote()->is_connected()); } +#endif + class DeviceAPIServiceWithFeatureFlagTest : public DeviceAPIServiceTest { public: DeviceAPIServiceWithFeatureFlagTest() {
diff --git a/chrome/browser/devtools/devtools_window.cc b/chrome/browser/devtools/devtools_window.cc index 0dfdbb15..eccb36f 100644 --- a/chrome/browser/devtools/devtools_window.cc +++ b/chrome/browser/devtools/devtools_window.cc
@@ -1281,7 +1281,10 @@ const GURL& target_url, WebContents* new_contents) { if (target_url.SchemeIs(content::kChromeDevToolsScheme) && - target_url.path().rfind("toolbox.html") != std::string::npos) { + (target_url.path().rfind("device_mode_emulation_frame.html") != + std::string::npos + // TODO(crbug.com/1228264): Remove toolbox.html allowance + || target_url.path().rfind("toolbox.html") != std::string::npos)) { CHECK(can_dock_); // Ownership will be passed in DevToolsWindow::AddNewContents.
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index e36d5d3..baa10ae 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -4987,6 +4987,11 @@ "expiry_milestone": 94 }, { + "name": "sharing-hub-link-toggle", + "owners": [ "sophey", "chrome-sharing-eng@google.com" ], + "expiry_milestone": 98 + }, + { "name": "sharing-prefer-vapid", "owners": [ "//chrome/browser/sharing/OWNERS" ], "expiry_milestone": 87
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 63e35fd..7495b4a4 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -3500,6 +3500,10 @@ "Enable showing the start surface when launching Chrome via the " "launcher."; +const char kSharingHubLinkToggleName[] = "Sharing Hub Link Toggle"; +const char kSharingHubLinkToggleDescription[] = + "Enable the link toggle in the Sharing Hub."; + const char kStrictSiteIsolationName[] = "Strict site isolation"; const char kStrictSiteIsolationDescription[] = "Security mode that enables site isolation for all sites (SitePerProcess). "
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 581b8862..359a13d 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -1996,6 +1996,9 @@ extern const char kStartSurfaceAndroidName[]; extern const char kStartSurfaceAndroidDescription[]; +extern const char kSharingHubLinkToggleName[]; +extern const char kSharingHubLinkToggleDescription[]; + extern const char kStrictSiteIsolationName[]; extern const char kStrictSiteIsolationDescription[];
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc index 68f1ef1b..b311c038 100644 --- a/chrome/browser/flags/android/chrome_feature_list.cc +++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -236,6 +236,7 @@ &kServiceManagerForDownload, &kShareButtonInTopToolbar, &kSharedClipboardUI, + &kSharingHubLinkToggle, &kSingleTouchSelect, &kSpannableInlineAutocomplete, &kSpecialLocaleWrapper, @@ -648,6 +649,9 @@ const base::Feature kShareButtonInTopToolbar{"ShareButtonInTopToolbar", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kSharingHubLinkToggle{"SharingHubLinkToggle", + base::FEATURE_DISABLED_BY_DEFAULT}; + const base::Feature kSingleTouchSelect{"SingleTouchSelect", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/chrome/browser/flags/android/chrome_feature_list.h b/chrome/browser/flags/android/chrome_feature_list.h index 186bc00..8186fa79 100644 --- a/chrome/browser/flags/android/chrome_feature_list.h +++ b/chrome/browser/flags/android/chrome_feature_list.h
@@ -116,6 +116,7 @@ extern const base::Feature kServiceManagerForBackgroundPrefetch; extern const base::Feature kServiceManagerForDownload; extern const base::Feature kShareButtonInTopToolbar; +extern const base::Feature kSharingHubLinkToggle; extern const base::Feature kSingleTouchSelect; extern const base::Feature kSpannableInlineAutocomplete; extern const base::Feature kSpecialLocaleWrapper;
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java index 203bfaa..169b0e45 100644 --- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java +++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
@@ -472,6 +472,7 @@ public static final String SHARED_CLIPBOARD_UI = "SharedClipboardUI"; public static final String SHARED_HIGHLIGHTING_V2 = "SharedHighlightingV2"; public static final String SHARED_HIGHLIGHTING_AMP = "SharedHighlightingAmp"; + public static final String SHARING_HUB_LINK_TOGGLE = "SharingHubLinkToggle"; public static final String SINGLE_TOUCH_SELECT = "SingleTouchSelect"; public static final String SHOW_TRUSTED_PUBLISHER_URL = "ShowTrustedPublisherURL"; public static final String SMART_SUGGESTION_FOR_LARGE_DOWNLOADS =
diff --git a/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/settings/LanguageSettings.java b/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/settings/LanguageSettings.java index ab4b0f0..4fcf6954 100644 --- a/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/settings/LanguageSettings.java +++ b/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/settings/LanguageSettings.java
@@ -69,8 +69,8 @@ getActivity().setTitle(R.string.language_settings); mPrefChangeRegistrar = new PrefChangeRegistrar(); - // Show the detailed language settings if DETAILED_LANGUAGE_SETTINGS feature is enabled. - if (ChromeFeatureList.isEnabled(ChromeFeatureList.DETAILED_LANGUAGE_SETTINGS)) { + // Create the correct version of language settings. + if (shouldShowDetailedPreferences()) { createDetailedPreferences(savedInstanceState, rootKey); } else { createBasicPreferences(savedInstanceState, rootKey); @@ -80,6 +80,18 @@ } /** + * The detailed language preferences should be shown if the flag to enable them or the app + * language prompt is enabled. If neither flag is enabled, but an override language is set the + * detailed language preferences should still be shown. + * @return Whether or not to show the detailed language preferences. + */ + private boolean shouldShowDetailedPreferences() { + return ChromeFeatureList.isEnabled(ChromeFeatureList.DETAILED_LANGUAGE_SETTINGS) + || ChromeFeatureList.isEnabled(ChromeFeatureList.APP_LANGUAGE_PROMPT) + || GlobalAppLocaleController.getInstance().isOverridden(); + } + + /** * Create the old language and translate settings page. Delete once no longer used. */ private void createBasicPreferences(Bundle savedInstanceState, String rootKey) {
diff --git a/chrome/browser/password_manager/android/password_store_bridge.cc b/chrome/browser/password_manager/android/password_store_bridge.cc index 48c9928..d4914d8b 100644 --- a/chrome/browser/password_manager/android/password_store_bridge.cc +++ b/chrome/browser/password_manager/android/password_store_bridge.cc
@@ -89,7 +89,8 @@ } void PasswordStoreBridge::ClearAllPasswords(JNIEnv* env) { - password_store_->ClearStore( + password_store_->RemoveLoginsCreatedBetween( + base::Time(), base::Time::Max(), base::BindOnce(&PasswordStoreBridge::OnPasswordStoreCleared, weak_factory_.GetWeakPtr())); }
diff --git a/chrome/browser/pdf/pdf_extension_test.cc b/chrome/browser/pdf/pdf_extension_test.cc index 9d984faa..327a2dd 100644 --- a/chrome/browser/pdf/pdf_extension_test.cc +++ b/chrome/browser/pdf/pdf_extension_test.cc
@@ -1474,7 +1474,14 @@ return true; } -IN_PROC_BROWSER_TEST_F(PDFExtensionTest, PdfAccessibilityInIframe) { +// Flaky, see crbug.com/1228762 +#if defined(OS_CHROMEOS) +#define MAYBE_PdfAccessibilityInIframe DISABLED_PdfAccessibilityInIframe +#else +#define MAYBE_PdfAccessibilityInIframe PdfAccessibilityInIframe +#endif + +IN_PROC_BROWSER_TEST_F(PDFExtensionTest, MAYBE_PdfAccessibilityInIframe) { content::BrowserAccessibilityState::GetInstance()->EnableAccessibility(); GURL test_iframe_url(embedded_test_server()->GetURL("/pdf/test-iframe.html")); ui_test_utils::NavigateToURL(browser(), test_iframe_url);
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc index ed53c564..51ac33d 100644 --- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc +++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -1409,9 +1409,9 @@ { key::kFetchKeepaliveDurationSecondsOnShutdown, prefs::kFetchKeepaliveDurationOnShutdown, base::Value::Type::INTEGER }, - { key::kManagedWebAppsAccessToDeviceAttributesAllowed, - prefs::kManagedWebAppsAccessToDeviceAttributesAllowed, - base::Value::Type::BOOLEAN }, + { key::kDeviceAttributesAllowedForOrigins, + prefs::kDeviceAttributesAllowedForOrigins, + base::Value::Type::LIST }, #endif // !defined(OS_ANDROID) { key::kSuppressDifferentOriginSubframeDialogs,
diff --git a/chrome/browser/profiles/gaia_info_update_service_unittest.cc b/chrome/browser/profiles/gaia_info_update_service_unittest.cc index 2bbb2661..5d7c931c 100644 --- a/chrome/browser/profiles/gaia_info_update_service_unittest.cc +++ b/chrome/browser/profiles/gaia_info_update_service_unittest.cc
@@ -18,7 +18,6 @@ #include "chrome/browser/profiles/profile_attributes_entry.h" #include "chrome/browser/profiles/profile_attributes_storage.h" #include "chrome/browser/profiles/profile_downloader.h" -#include "chrome/browser/profiles/profile_info_cache_unittest.h" #include "chrome/browser/profiles/profiles_state.h" #include "chrome/browser/signin/chrome_signin_client_factory.h" #include "chrome/browser/signin/identity_test_environment_profile_adaptor.h" @@ -32,7 +31,9 @@ #include "components/signin/public/base/signin_pref_names.h" #include "components/signin/public/identity_manager/account_info.h" #include "components/sync_preferences/pref_service_syncable.h" +#include "content/public/test/browser_task_environment.h" #include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" #include "ui/gfx/image/image.h" #include "ui/gfx/image/image_unittest_util.h"
diff --git a/chrome/browser/profiles/profile.cc b/chrome/browser/profiles/profile.cc index 88309c7..01f7289 100644 --- a/chrome/browser/profiles/profile.cc +++ b/chrome/browser/profiles/profile.cc
@@ -62,6 +62,7 @@ #endif #if BUILDFLAG(IS_CHROMEOS_LACROS) +#include "chrome/common/chrome_constants.h" #include "chromeos/lacros/lacros_chrome_service_impl.h" #endif @@ -409,6 +410,14 @@ profile_metrics::BrowserProfileType::kSystem; } +#if BUILDFLAG(IS_CHROMEOS_LACROS) +// static +bool Profile::IsMainProfilePath(base::FilePath profile_path) { + // The main profile is the one with the "Default" path. + return profile_path.BaseName().value() == chrome::kInitialProfile; +} +#endif // BUILDFLAG(IS_CHROMEOS_LACROS) + bool Profile::IsPrimaryOTRProfile() const { return IsOffTheRecord() && GetOTRProfileID() == OTRProfileID::PrimaryID(); }
diff --git a/chrome/browser/profiles/profile.h b/chrome/browser/profiles/profile.h index b28d8706..e3e819d 100644 --- a/chrome/browser/profiles/profile.h +++ b/chrome/browser/profiles/profile.h
@@ -445,11 +445,14 @@ bool IsSystemProfile() const; #if BUILDFLAG(IS_CHROMEOS_LACROS) - // Returns `true` if this is the first/initial Profile in Lacros, and - for - // regular sessions, if this Profile has the Device Account logged in. + // Returns `true` if this is the first/initial Profile path in Lacros, and - + // for regular sessions, if this Profile has the Device Account logged in. // For non-regular sessions (Guest Sessions, Managed Guest Sessions) which do // not have the concept of a Device Account, the latter condition is not // checked. + static bool IsMainProfilePath(base::FilePath profile_path); + + // Returns true if this is the main profile as defined above. virtual bool IsMainProfile() const = 0; #endif // BUILDFLAG(IS_CHROMEOS_LACROS)
diff --git a/chrome/browser/profiles/profile_attributes_storage.h b/chrome/browser/profiles/profile_attributes_storage.h index 9c4233e..b11f9508 100644 --- a/chrome/browser/profiles/profile_attributes_storage.h +++ b/chrome/browser/profiles/profile_attributes_storage.h
@@ -182,12 +182,11 @@ void DisableProfileMetricsForTesting(); private: - FRIEND_TEST_ALL_PREFIXES(ProfileInfoCacheTest, EntriesInAttributesStorage); FRIEND_TEST_ALL_PREFIXES(ProfileAttributesStorageTest, DownloadHighResAvatarTest); FRIEND_TEST_ALL_PREFIXES(ProfileAttributesStorageTest, NothingToDownloadHighResAvatarTest); - FRIEND_TEST_ALL_PREFIXES(ProfileInfoCacheTest, + FRIEND_TEST_ALL_PREFIXES(ProfileAttributesStorageTest, MigrateLegacyProfileNamesAndRecomputeIfNeeded); // Starts downloading the high res avatar at index |icon_index| for profile
diff --git a/chrome/browser/profiles/profile_attributes_storage_unittest.cc b/chrome/browser/profiles/profile_attributes_storage_unittest.cc index 12339d6b..145a3fdb 100644 --- a/chrome/browser/profiles/profile_attributes_storage_unittest.cc +++ b/chrome/browser/profiles/profile_attributes_storage_unittest.cc
@@ -10,6 +10,8 @@ #include "base/bind.h" #include "base/files/file_util.h" #include "base/format_macros.h" +#include "base/scoped_observation.h" +#include "base/strings/strcat.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/test/metrics/histogram_tester.h" @@ -25,10 +27,12 @@ #include "chrome/browser/signin/signin_util.h" #include "chrome/browser/supervised_user/supervised_user_constants.h" #include "chrome/browser/ui/ui_features.h" +#include "chrome/common/pref_names.h" #include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile_manager.h" #include "components/account_id/account_id.h" #include "components/profile_metrics/state.h" +#include "components/sync_preferences/pref_service_syncable.h" #include "content/public/test/browser_task_environment.h" #include "content/public/test/test_utils.h" #include "testing/gmock/include/gmock/gmock.h" @@ -147,6 +151,12 @@ #endif // defined(OS_WIN) } +std::u16string ConcatenateGaiaAndProfileNames( + const std::u16string& gaia_name, + const std::u16string& profile_name) { + return base::StrCat({gaia_name, u" (", profile_name, u")"}); +} + } // namespace class ProfileAttributesStorageTest : public testing::Test { @@ -162,8 +172,6 @@ EnableObserver(); } - void TearDown() override { DisableObserver(); } - base::FilePath GetProfilePath(const std::string& base_name) { return testing_profile_manager_.profile_manager()->user_data_dir(). AppendASCII(base_name); @@ -185,8 +193,8 @@ EXPECT_CALL(observer_, OnProfileHostedDomainChanged(_)).Times(0); } - void EnableObserver() { storage()->AddObserver(&observer_); } - void DisableObserver() { storage()->RemoveObserver(&observer_); } + void EnableObserver() { scoped_observation_.Observe(storage()); } + void DisableObserver() { scoped_observation_.Reset(); } void AddCallExpectationsForRemoveProfile(size_t profile_number) { base::FilePath profile_path = GetProfilePath( @@ -232,16 +240,25 @@ } void ResetProfileAttributesStorage() { + bool was_observing = scoped_observation_.IsObserving(); DisableObserver(); testing_profile_manager_.DeleteProfileAttributesStorage(); - EnableObserver(); + // Restore observation if there was any. + if (was_observing) + EnableObserver(); } - TestingProfileManager testing_profile_manager_; + TestingProfileManager& testing_profile_manager() { + return testing_profile_manager_; + } private: content::BrowserTaskEnvironment task_environment_; + TestingProfileManager testing_profile_manager_; ProfileAttributesTestObserver observer_; + base::ScopedObservation<ProfileAttributesStorage, + ProfileAttributesStorage::Observer> + scoped_observation_{&observer_}; }; TEST_F(ProfileAttributesStorageTest, ProfileNotFound) { @@ -286,6 +303,91 @@ EXPECT_EQ(u"new_profile_name_1", entry->GetName()); } +TEST_F(ProfileAttributesStorageTest, AddProfiles) { + DisableObserver(); // This test doesn't test observers. + + EXPECT_EQ(0u, storage()->GetNumberOfProfiles()); + // Avatar icons not used on Android. +#if !defined(OS_ANDROID) + ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); +#endif + + for (size_t i = 0; i < 4u; ++i) { + base::FilePath profile_path = + GetProfilePath(base::StringPrintf("path_%zu", i)); + std::u16string profile_name = + base::ASCIIToUTF16(base::StringPrintf("name_%zu", i)); +#if !defined(OS_ANDROID) + + size_t icon_id = GetDefaultAvatarIconResourceIDAtIndex(i); + const SkBitmap* icon = rb.GetImageNamed(icon_id).ToSkBitmap(); + +#endif // !defined(OS_ANDROID) + std::string supervised_user_id; +#if BUILDFLAG(ENABLE_SUPERVISED_USERS) + if (i == 3u) + supervised_user_id = supervised_users::kChildAccountSUID; +#endif + + ProfileAttributesInitParams params; + params.profile_path = profile_path; + params.profile_name = profile_name; + params.icon_index = i; + params.supervised_user_id = supervised_user_id; + storage()->AddProfile(std::move(params)); + + ProfileAttributesEntry* entry = + storage()->GetProfileAttributesWithPath(profile_path); + entry->SetBackgroundStatus(true); + std::u16string gaia_name = + base::ASCIIToUTF16(base::StringPrintf("gaia_%zu", i)); + entry->SetGAIAName(gaia_name); + + EXPECT_EQ(i + 1, storage()->GetNumberOfProfiles()); + std::u16string expected_profile_name = + ConcatenateGaiaAndProfileNames(gaia_name, profile_name); + + EXPECT_EQ(expected_profile_name, entry->GetName()); + + EXPECT_EQ(profile_path, entry->GetPath()); +#if !defined(OS_ANDROID) + const SkBitmap* actual_icon = entry->GetAvatarIcon().ToSkBitmap(); + EXPECT_EQ(icon->width(), actual_icon->width()); + EXPECT_EQ(icon->height(), actual_icon->height()); +#endif +#if BUILDFLAG(ENABLE_SUPERVISED_USERS) + EXPECT_EQ(i == 3u, entry->IsSupervised()); +#else + EXPECT_FALSE(entry->IsSupervised()); + EXPECT_FALSE(entry->IsOmitted()); +#endif // BUILDFLAG(ENABLE_SUPERVISED_USERS) + EXPECT_EQ(supervised_user_id, entry->GetSupervisedUserId()); + } + + // Reset the storage and test the it reloads correctly. + ResetProfileAttributesStorage(); + + EXPECT_EQ(4u, storage()->GetNumberOfProfiles()); + for (size_t i = 0; i < 4u; ++i) { + base::FilePath profile_path = + GetProfilePath(base::StringPrintf("path_%zu", i)); + ProfileAttributesEntry* entry = + storage()->GetProfileAttributesWithPath(profile_path); + std::u16string profile_name = + base::ASCIIToUTF16(base::StringPrintf("name_%zu", i)); + std::u16string gaia_name = + base::ASCIIToUTF16(base::StringPrintf("gaia_%zu", i)); + std::u16string expected_profile_name = + ConcatenateGaiaAndProfileNames(gaia_name, profile_name); + EXPECT_EQ(expected_profile_name, entry->GetName()); +#if !defined(OS_ANDROID) + EXPECT_EQ(i, entry->GetAvatarIconIndex()); +#endif + EXPECT_EQ(true, entry->GetBackgroundStatus()); + EXPECT_EQ(gaia_name, entry->GetGAIAName()); + } +} + TEST_F(ProfileAttributesStorageTest, RemoveProfile) { EXPECT_EQ(0U, storage()->GetNumberOfProfiles()); @@ -311,6 +413,57 @@ EXPECT_EQ(entry, nullptr); } +TEST_F(ProfileAttributesStorageTest, RemoveProfileByAccountId) { + DisableObserver(); // This test doesn't test observers. + EXPECT_EQ(0u, storage()->GetNumberOfProfiles()); + const struct { + const char* profile_path; + const char* profile_name; + AccountId account_id; + bool is_consented_primary_account; + } kTestCases[] = { + {"path_1", "name_1", AccountId::FromUserEmailGaiaId("email1", "111111"), + true}, + {"path_2", "name_3", AccountId::FromUserEmailGaiaId("email2", "222222"), + true}, + {"path_3", "name_3", AccountId::FromUserEmailGaiaId("email3", "333333"), + false}, + {"path_4", "name_4", AccountId::FromUserEmailGaiaId("email4", "444444"), + false}}; + + for (size_t i = 0; i < base::size(kTestCases); ++i) { + ProfileAttributesInitParams params; + params.profile_path = GetProfilePath(kTestCases[i].profile_path); + params.profile_name = base::ASCIIToUTF16(kTestCases[i].profile_name); + params.gaia_id = kTestCases[i].account_id.GetGaiaId(); + params.user_name = + base::UTF8ToUTF16(kTestCases[i].account_id.GetUserEmail()); + params.is_consented_primary_account = + kTestCases[i].is_consented_primary_account; + storage()->AddProfile(std::move(params)); + EXPECT_EQ(i + 1, storage()->GetNumberOfProfiles()); + } + + storage()->RemoveProfileByAccountId(kTestCases[2].account_id); + EXPECT_EQ(3u, storage()->GetNumberOfProfiles()); + + storage()->RemoveProfileByAccountId(kTestCases[0].account_id); + EXPECT_EQ(2u, storage()->GetNumberOfProfiles()); + + // This profile is already deleted. + storage()->RemoveProfileByAccountId(kTestCases[2].account_id); + EXPECT_EQ(2u, storage()->GetNumberOfProfiles()); + + // Remove profile by partial match. + storage()->RemoveProfileByAccountId( + AccountId::FromUserEmail(kTestCases[1].account_id.GetUserEmail())); + EXPECT_EQ(1u, storage()->GetNumberOfProfiles()); + + // Remove last profile. + storage()->RemoveProfileByAccountId(kTestCases[3].account_id); + EXPECT_EQ(0u, storage()->GetNumberOfProfiles()); +} + TEST_F(ProfileAttributesStorageTest, MultipleProfiles) { EXPECT_EQ(0U, storage()->GetNumberOfProfiles()); @@ -343,6 +496,53 @@ } } +TEST_F(ProfileAttributesStorageTest, AddStubProfile) { + DisableObserver(); // This test doesn't test observers. + EXPECT_EQ(0u, storage()->GetNumberOfProfiles()); + + // Add some profiles with and without a '.' in their paths. + const struct { + const char* profile_path; + const char* profile_name; + } kTestCases[] = { + {"path.test0", "name_0"}, + {"path_test1", "name_1"}, + {"path.test2", "name_2"}, + {"path_test3", "name_3"}, + }; + const size_t kNumProfiles = base::size(kTestCases); + + for (auto test_case : kTestCases) { + base::FilePath profile_path = GetProfilePath(test_case.profile_path); + std::u16string profile_name = base::ASCIIToUTF16(test_case.profile_name); + + ProfileAttributesInitParams params; + params.profile_path = profile_path; + params.profile_name = profile_name; + storage()->AddProfile(std::move(params)); + ProfileAttributesEntry* entry = + storage()->GetProfileAttributesWithPath(profile_path); + EXPECT_TRUE(entry); + EXPECT_EQ(profile_name, entry->GetName()); + } + + ASSERT_EQ(kNumProfiles, storage()->GetNumberOfProfiles()); + + // Check that the profiles can be extracted from the local state. + std::vector<std::string> names; + PrefService* local_state = g_browser_process->local_state(); + const base::DictionaryValue* attributes = + local_state->GetDictionary(prefs::kProfileAttributes); + for (const auto kv : attributes->DictItems()) { + const base::Value& info = kv.second; + const std::string* name = info.FindStringKey("name"); + names.push_back(*name); + } + + for (size_t i = 0; i < kNumProfiles; i++) + ASSERT_FALSE(names[i].empty()); +} + TEST_F(ProfileAttributesStorageTest, InitialValues) { #if defined(OS_ANDROID) // Android has only one default avatar. @@ -415,6 +615,84 @@ /*is_signed_in_with_credential_provider=*/false); } +// Checks that ProfileAttributesStorage doesn't crash when +// ProfileAttributesEntry initialization modifies an attributes entry. +// This is a regression test for https://crbug.com/1180497. +TEST_F(ProfileAttributesStorageTest, ModifyEntryWhileInitializing) { + DisableObserver(); // This test doesn't test observers. + base::FilePath profile_path = GetProfilePath("test"); + { + signin_util::ScopedForceSigninSetterForTesting force_signin_setter(true); + AccountId account_id = AccountId::FromUserEmailGaiaId("email", "111111"); + ProfileAttributesInitParams params; + params.profile_path = profile_path; + params.profile_name = u"Test"; + params.gaia_id = account_id.GetGaiaId(); + params.user_name = base::UTF8ToUTF16(account_id.GetUserEmail()); + storage()->AddProfile(std::move(params)); + ProfileAttributesEntry* entry = + storage()->GetProfileAttributesWithPath(profile_path); + // Set up the state so that ProfileAttributesEntry::Initialize() will modify + // the entry. + entry->LockForceSigninProfile(true); + } + // Reinitialize ProfileAttributesStorage. + ResetProfileAttributesStorage(); + storage(); // Should not crash. + + // The IsSigninRequired attribute should be cleaned up. + ProfileAttributesEntry* entry = + storage()->GetProfileAttributesWithPath(profile_path); + EXPECT_FALSE(entry->IsSigninRequired()); +} + +TEST_F(ProfileAttributesStorageTest, ProfileNamesOnInit) { + DisableObserver(); // This test doesn't test observers. + // Set up the storage with two profiles having the same GAIA given name. + // The second profile also has a profile name matching the GAIA given name. + std::u16string kDefaultProfileName = u"Person 1"; + std::u16string kCommonName = u"Joe"; + + // Create and initialize the first profile. + base::FilePath path_1 = GetProfilePath("path_1"); + ProfileAttributesInitParams params_1; + params_1.profile_path = path_1; + params_1.profile_name = kDefaultProfileName; + storage()->AddProfile(std::move(params_1)); + ProfileAttributesEntry* entry_1 = + storage()->GetProfileAttributesWithPath(path_1); + entry_1->SetGAIAGivenName(kCommonName); + EXPECT_EQ(entry_1->GetName(), kCommonName); + + // Create and initialize the second profile. + base::FilePath path_2 = GetProfilePath("path_2"); + ProfileAttributesInitParams params_2; + params_2.profile_path = path_2; + params_2.profile_name = kCommonName; + storage()->AddProfile(std::move(params_2)); + ProfileAttributesEntry* entry_2 = + storage()->GetProfileAttributesWithPath(path_2); + entry_2->SetGAIAGivenName(kCommonName); + EXPECT_EQ(entry_2->GetName(), kCommonName); + + // The first profile name should be modified. + EXPECT_EQ(entry_1->GetName(), + ConcatenateGaiaAndProfileNames(kCommonName, kDefaultProfileName)); + + // Reset the storage to test profile names set on initialization. + ResetProfileAttributesStorage(); + entry_1 = storage()->GetProfileAttributesWithPath(path_1); + entry_2 = storage()->GetProfileAttributesWithPath(path_2); + + // Freshly initialized entries should not report name changes. + EXPECT_FALSE(entry_1->HasProfileNameChanged()); + EXPECT_FALSE(entry_2->HasProfileNameChanged()); + + EXPECT_EQ(entry_1->GetName(), + ConcatenateGaiaAndProfileNames(kCommonName, kDefaultProfileName)); + EXPECT_EQ(entry_2->GetName(), kCommonName); +} + TEST_F(ProfileAttributesStorageTest, EntryAccessors) { AddTestingProfile(); @@ -611,6 +889,144 @@ EXPECT_EQ("foo", entry->GetGAIAId()); } +TEST_F(ProfileAttributesStorageTest, GAIAName) { + DisableObserver(); // This test doesn't test observers. + + base::FilePath profile_path_1 = GetProfilePath("path_1"); + ProfileAttributesInitParams params_1; + params_1.profile_path = profile_path_1; + params_1.profile_name = u"Person 1"; + storage()->AddProfile(std::move(params_1)); + ProfileAttributesEntry* entry_1 = + storage()->GetProfileAttributesWithPath(profile_path_1); + base::FilePath profile_path_2 = GetProfilePath("path_2"); + ProfileAttributesInitParams params_2; + params_2.profile_path = profile_path_2; + params_2.profile_name = u"Person 2"; + storage()->AddProfile(std::move(params_2)); + ProfileAttributesEntry* entry_2 = + storage()->GetProfileAttributesWithPath(profile_path_2); + + // Sanity check. + EXPECT_TRUE(entry_1->GetGAIAName().empty()); + EXPECT_TRUE(entry_2->GetGAIAName().empty()); + + // Set GAIA name. + std::u16string gaia_name(u"Pat Smith"); + entry_2->SetGAIAName(gaia_name); + // Since there is a GAIA name, we use that as a display name. + EXPECT_TRUE(entry_1->GetGAIAName().empty()); + EXPECT_EQ(gaia_name, entry_2->GetGAIAName()); + EXPECT_EQ(gaia_name, entry_2->GetName()); + + std::u16string custom_name(u"Custom name"); + entry_2->SetLocalProfileName(custom_name, false); + + std::u16string expected_profile_name = + ConcatenateGaiaAndProfileNames(gaia_name, custom_name); + EXPECT_EQ(expected_profile_name, entry_2->GetName()); + EXPECT_EQ(gaia_name, entry_2->GetGAIAName()); +} + +TEST_F(ProfileAttributesStorageTest, ConcatenateGaiaNameAndProfileName) { + DisableObserver(); // This test doesn't test observers. + + // We should only append the profile name to the GAIA name if: + // - The user has chosen a profile name on purpose. + // - Two profiles has the sama GAIA name and we need to show it to + // clear ambiguity. + // If one of the two conditions hold, we will show the profile name in this + // format |GAIA name (Profile local name)| + // Single profile. + base::FilePath profile_path_1 = GetProfilePath("path_1"); + ProfileAttributesInitParams params_1; + params_1.profile_path = profile_path_1; + params_1.profile_name = u"Person 1"; + storage()->AddProfile(std::move(params_1)); + ProfileAttributesEntry* entry_1 = + storage()->GetProfileAttributesWithPath(profile_path_1); + EXPECT_EQ(u"Person 1", entry_1->GetName()); + entry_1->SetGAIAName(u"Patt Smith"); + EXPECT_EQ(u"Patt Smith", entry_1->GetName()); + entry_1->SetGAIAGivenName(u"Patt"); + EXPECT_EQ(u"Patt", entry_1->GetName()); + + // Set a custom profile name. + entry_1->SetLocalProfileName(u"Work", false); + EXPECT_EQ(u"Patt (Work)", entry_1->GetName()); + + // Set the profile name to be equal to GAIA name. + entry_1->SetLocalProfileName(u"patt", false); + EXPECT_EQ(u"Patt", entry_1->GetName()); + + // Multiple profiles. + // Add another profile with the same GAIA name and a default profile name. + base::FilePath profile_path_2 = GetProfilePath("path_2"); + ProfileAttributesInitParams params_2; + params_2.profile_path = profile_path_2; + params_2.profile_name = u"Person 2"; + storage()->AddProfile(std::move(params_2)); + ProfileAttributesEntry* entry_2 = + storage()->GetProfileAttributesWithPath(profile_path_2); + EXPECT_EQ(u"Patt", entry_1->GetName()); + EXPECT_EQ(u"Person 2", entry_2->GetName()); + + entry_1->SetLocalProfileName(u"Work", false); + EXPECT_EQ(u"Patt (Work)", entry_1->GetName()); + EXPECT_EQ(u"Person 2", entry_2->GetName()); + + // A second profile with a different GAIA name should not affect the first + // profile. + entry_2->SetGAIAGivenName(u"Olly"); + EXPECT_EQ(u"Patt (Work)", entry_1->GetName()); + EXPECT_EQ(u"Olly", entry_2->GetName()); + + // Mark profile name as default. + entry_1->SetLocalProfileName(u"Person 1", true); + EXPECT_EQ(u"Patt", entry_1->GetName()); + EXPECT_EQ(u"Olly", entry_2->GetName()); + + // Add a third profile with the same GAIA name as the first. + // The two profiles are marked as using default profile names. + base::FilePath profile_path_3 = GetProfilePath("path_3"); + ProfileAttributesInitParams params_3; + params_3.profile_path = profile_path_3; + params_3.profile_name = u"Person 3"; + storage()->AddProfile(std::move(params_3)); + ProfileAttributesEntry* entry_3 = + storage()->GetProfileAttributesWithPath(profile_path_3); + entry_3->SetGAIAName(u"Patt Smith"); + EXPECT_EQ(u"Patt", entry_1->GetName()); + EXPECT_EQ(u"Patt Smith", entry_3->GetName()); + + // Two profiles with same GAIA name and default profile name. + // Empty GAIA given name. + entry_3->SetGAIAName(u"Patt"); + EXPECT_EQ(u"Patt (Person 1)", entry_1->GetName()); + EXPECT_EQ(u"Patt (Person 3)", entry_3->GetName()); + // Set GAIA given name. + entry_3->SetGAIAGivenName(u"Patt"); + EXPECT_EQ(u"Patt (Person 1)", entry_1->GetName()); + EXPECT_EQ(u"Patt (Person 3)", entry_3->GetName()); + + // Customize the profile name for one of the two profiles. + entry_3->SetLocalProfileName(u"Personal", false); + EXPECT_EQ(u"Patt", entry_1->GetName()); + EXPECT_EQ(u"Patt (Personal)", entry_3->GetName()); + + // Set one of the profile names to be equal to GAIA name, we should show + // the profile name even if it is Person n to clear ambiguity. + entry_3->SetLocalProfileName(u"patt", false); + EXPECT_EQ(u"Patt (Person 1)", entry_1->GetName()); + EXPECT_EQ(u"Patt", entry_3->GetName()); + + // Never show the profile name if it is equal GAIA name. + entry_1->SetLocalProfileName(u"Patt", false); + EXPECT_EQ(u"Patt", entry_1->GetName()); + EXPECT_EQ(u"Patt", entry_3->GetName()); + EXPECT_EQ(u"Olly", entry_2->GetName()); +} + TEST_F(ProfileAttributesStorageTest, SupervisedUsersAccessors) { AddTestingProfile(); @@ -639,6 +1055,33 @@ #endif // BUILDFLAG(ENABLE_SUPERVISED_USERS) } +#if BUILDFLAG(ENABLE_SUPERVISED_USERS) +TEST_F(ProfileAttributesStorageTest, CreateSupervisedTestingProfile) { + DisableObserver(); // This test doesn't test observers. + + base::FilePath path_1 = + testing_profile_manager().CreateTestingProfile("default")->GetPath(); + std::u16string supervised_user_name = u"Supervised User"; + base::FilePath path_2 = + testing_profile_manager() + .CreateTestingProfile( + "test1", std::unique_ptr<sync_preferences::PrefServiceSyncable>(), + supervised_user_name, 0, supervised_users::kChildAccountSUID, + TestingProfile::TestingFactories()) + ->GetPath(); + base::FilePath profile_paths[] = {path_1, path_2}; + for (const base::FilePath& path : profile_paths) { + ProfileAttributesEntry* entry = + storage()->GetProfileAttributesWithPath(path); + bool is_supervised = entry->GetName() == supervised_user_name; + EXPECT_EQ(is_supervised, entry->IsSupervised()); + std::string supervised_user_id = + is_supervised ? supervised_users::kChildAccountSUID : ""; + EXPECT_EQ(supervised_user_id, entry->GetSupervisedUserId()); + } +} +#endif + TEST_F(ProfileAttributesStorageTest, ReSortTriggered) { DisableObserver(); // No need to test observers in this test. @@ -1392,3 +1835,116 @@ EXPECT_TRUE(gfx::test::AreImagesEqual(gaia_image, image_loaded)); } #endif // !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH) + +#if !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH) +TEST_F(ProfileAttributesStorageTest, + MigrateLegacyProfileNamesAndRecomputeIfNeeded) { + DisableObserver(); // This test doesn't test observers. + EXPECT_EQ(0U, storage()->GetNumberOfProfiles()); + // Mimic a pre-existing Directory with profiles that has legacy profile + // names. + const struct { + const char* profile_path; + const char* profile_name; + bool is_using_default_name; + } kTestCases[] = { + {"path_1", "Default Profile", true}, {"path_2", "First user", true}, + {"path_3", "Lemonade", true}, {"path_4", "Batman", true}, + {"path_5", "Batman", false}, {"path_6", "Person 2", true}, + {"path_7", "Person 3", true}, {"path_8", "Person 1", true}, + {"path_9", "Person 2", true}, {"path_10", "Person 1", true}, + {"path_11", "Smith", false}, {"path_12", "Person 2", true}}; + const size_t kNumProfiles = base::size(kTestCases); + + ProfileAttributesEntry* entry = nullptr; + for (size_t i = 0; i < kNumProfiles; ++i) { + base::FilePath profile_path = GetProfilePath(kTestCases[i].profile_path); + ProfileAttributesInitParams params; + params.profile_path = profile_path; + params.profile_name = base::ASCIIToUTF16(kTestCases[i].profile_name); + params.icon_index = i; + storage()->AddProfile(std::move(params)); + entry = storage()->GetProfileAttributesWithPath(profile_path); + EXPECT_TRUE(entry); + entry->SetIsUsingDefaultName(kTestCases[i].is_using_default_name); + } + + EXPECT_EQ(kNumProfiles, storage()->GetNumberOfProfiles()); + + ResetProfileAttributesStorage(); + ProfileAttributesStorage::SetLegacyProfileMigrationForTesting(true); + storage(); + ProfileAttributesStorage::SetLegacyProfileMigrationForTesting(false); + + entry = storage()->GetProfileAttributesWithPath( + GetProfilePath(kTestCases[4].profile_path)); + EXPECT_EQ(base::ASCIIToUTF16(kTestCases[4].profile_name), entry->GetName()); + entry = storage()->GetProfileAttributesWithPath( + GetProfilePath(kTestCases[10].profile_path)); + EXPECT_EQ(base::ASCIIToUTF16(kTestCases[10].profile_name), entry->GetName()); + + // Legacy profile names like "Default Profile" and "First user" should be + // migrated to "Person %n" type names, i.e. any permutation of "Person %n". + std::set<std::u16string> expected_profile_names{ + u"Person 1", u"Person 2", u"Person 3", u"Person 4", u"Person 5", + u"Person 6", u"Person 7", u"Person 8", u"Person 9", u"Person 10"}; + + const char* profile_paths[] = { + kTestCases[0].profile_path, kTestCases[1].profile_path, + kTestCases[2].profile_path, kTestCases[3].profile_path, + kTestCases[5].profile_path, kTestCases[6].profile_path, + kTestCases[7].profile_path, kTestCases[8].profile_path, + kTestCases[9].profile_path, kTestCases[11].profile_path}; + + std::set<std::u16string> actual_profile_names; + for (auto* path : profile_paths) { + entry = storage()->GetProfileAttributesWithPath(GetProfilePath(path)); + actual_profile_names.insert(entry->GetName()); + } + EXPECT_EQ(actual_profile_names, expected_profile_names); +} +#endif // !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH) + +#if BUILDFLAG(IS_CHROMEOS_ASH) || defined(OS_ANDROID) +TEST_F(ProfileAttributesStorageTest, + DontMigrateLegacyProfileNamesWithoutNewAvatarMenu) { + DisableObserver(); // This test doesn't test observers. + EXPECT_EQ(0U, storage()->GetNumberOfProfiles()); + + const struct { + const char* profile_path; + const char* profile_name; + } kTestCases[] = {{"path_1", "Default Profile"}, + {"path_2", "First user"}, + {"path_3", "Lemonade"}, + {"path_4", "Batman"}}; + const size_t kNumProfiles = base::size(kTestCases); + + for (size_t i = 0; i < kNumProfiles; ++i) { + base::FilePath profile_path = GetProfilePath(kTestCases[i].profile_path); + ProfileAttributesInitParams params; + params.profile_path = profile_path; + params.profile_name = base::ASCIIToUTF16(kTestCases[i].profile_name); + params.icon_index = i; + storage()->AddProfile(std::move(params)); + ProfileAttributesEntry* entry = + storage()->GetProfileAttributesWithPath(profile_path); + EXPECT_TRUE(entry); + entry->SetIsUsingDefaultName(true); + } + EXPECT_EQ(kNumProfiles, storage()->GetNumberOfProfiles()); + + ResetProfileAttributesStorage(); + + // Profile names should have been preserved. + for (size_t i = 0; i < kNumProfiles; ++i) { + base::FilePath profile_path = GetProfilePath(kTestCases[i].profile_path); + std::u16string profile_name = + base::ASCIIToUTF16(kTestCases[i].profile_name); + ProfileAttributesEntry* entry = + storage()->GetProfileAttributesWithPath(profile_path); + EXPECT_TRUE(entry); + EXPECT_EQ(profile_name, entry->GetName()); + } +} +#endif // BUILDFLAG(IS_CHROMEOS_ASH) || defined(OS_ANDROID)
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc index 48028878..5d87d4fff 100644 --- a/chrome/browser/profiles/profile_impl.cc +++ b/chrome/browser/profiles/profile_impl.cc
@@ -903,7 +903,7 @@ // Profile must be at "Default" path. // `IdentityManager' will guarantee that the Chrome OS Device Account is // signed into `this' Profile, if it's the Main Profile. - return GetBaseName().value() == chrome::kInitialProfile; + return Profile::IsMainProfilePath(GetPath()); } #endif // BUILDFLAG(IS_CHROMEOS_LACROS)
diff --git a/chrome/browser/profiles/profile_info_cache_unittest.cc b/chrome/browser/profiles/profile_info_cache_unittest.cc deleted file mode 100644 index 27c7245b..0000000 --- a/chrome/browser/profiles/profile_info_cache_unittest.cc +++ /dev/null
@@ -1,883 +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/profiles/profile_info_cache_unittest.h" - -#include <stddef.h> -#include <stdint.h> - -#include <algorithm> -#include <set> -#include <string> -#include <vector> - -#include "base/bind.h" -#include "base/command_line.h" -#include "base/cxx17_backports.h" -#include "base/files/file_util.h" -#include "base/strings/stringprintf.h" -#include "base/strings/utf_string_conversions.h" -#include "base/time/time.h" -#include "build/build_config.h" -#include "build/chromeos_buildflags.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/profiles/avatar_menu.h" -#include "chrome/browser/profiles/profile_attributes_init_params.h" -#include "chrome/browser/profiles/profile_attributes_storage.h" -#include "chrome/browser/profiles/profile_avatar_icon_util.h" -#include "chrome/browser/profiles/profile_manager.h" -#include "chrome/browser/signin/signin_util.h" -#include "chrome/common/chrome_switches.h" -#include "chrome/common/pref_names.h" -#include "chrome/test/base/testing_browser_process.h" -#include "components/account_id/account_id.h" -#include "components/prefs/testing_pref_service.h" -#include "components/sync_preferences/pref_service_syncable.h" -#include "content/public/test/browser_task_environment.h" -#include "content/public/test/test_utils.h" -#include "third_party/skia/include/core/SkBitmap.h" -#include "ui/base/resource/resource_bundle.h" -#include "ui/gfx/image/image.h" -#include "ui/gfx/image/image_unittest_util.h" - -#if BUILDFLAG(ENABLE_SUPERVISED_USERS) -#include "chrome/browser/supervised_user/supervised_user_constants.h" -#endif - -using base::ASCIIToUTF16; -using base::UTF8ToUTF16; -using content::BrowserThread; - -namespace { - -#if !defined(OS_ANDROID) -size_t GetDefaultAvatarIconResourceIDAtIndex(int index) { -#if defined(OS_WIN) - return profiles::GetOldDefaultAvatar2xIconResourceIDAtIndex(index); -#else - return profiles::GetDefaultAvatarIconResourceIDAtIndex(index); -#endif // defined(OS_WIN) -} -#endif // !defined(OS_ANDROID) - -} // namespace - -ProfileNameVerifierObserver::ProfileNameVerifierObserver( - TestingProfileManager* testing_profile_manager) - : testing_profile_manager_(testing_profile_manager) { - DCHECK(testing_profile_manager_); -} - -ProfileNameVerifierObserver::~ProfileNameVerifierObserver() { -} - -void ProfileNameVerifierObserver::OnProfileAdded( - const base::FilePath& profile_path) { - ProfileAttributesEntry* entry = - GetCache()->GetProfileAttributesWithPath(profile_path); - std::u16string profile_name = entry->GetName(); - EXPECT_TRUE(profile_names_.find(profile_path) == profile_names_.end()); - profile_names_.insert({profile_path, profile_name}); -} - -void ProfileNameVerifierObserver::OnProfileWillBeRemoved( - const base::FilePath& profile_path) { - auto it = profile_names_.find(profile_path); - EXPECT_TRUE(it != profile_names_.end()); - profile_names_.erase(it); -} - -void ProfileNameVerifierObserver::OnProfileWasRemoved( - const base::FilePath& profile_path, - const std::u16string& profile_name) { - EXPECT_TRUE(profile_names_.find(profile_path) == profile_names_.end()); -} - -void ProfileNameVerifierObserver::OnProfileNameChanged( - const base::FilePath& profile_path, - const std::u16string& old_profile_name) { - ProfileAttributesEntry* entry = - GetCache()->GetProfileAttributesWithPath(profile_path); - std::u16string new_profile_name = entry->GetName(); - EXPECT_TRUE(profile_names_[profile_path] == old_profile_name); - profile_names_[profile_path] = new_profile_name; -} - -void ProfileNameVerifierObserver::OnProfileAvatarChanged( - const base::FilePath& profile_path) { - EXPECT_TRUE(profile_names_.find(profile_path) != profile_names_.end()); -} - -ProfileAttributesStorage* ProfileNameVerifierObserver::GetCache() { - return testing_profile_manager_->profile_attributes_storage(); -} - -ProfileInfoCacheTest::ProfileInfoCacheTest() - : testing_profile_manager_(TestingBrowserProcess::GetGlobal()), - name_observer_(&testing_profile_manager_) {} - -ProfileInfoCacheTest::~ProfileInfoCacheTest() { -} - -void ProfileInfoCacheTest::SetUp() { - ASSERT_TRUE(testing_profile_manager_.SetUp()); - testing_profile_manager_.profile_attributes_storage()->AddObserver( - &name_observer_); -} - -void ProfileInfoCacheTest::TearDown() { - // Drain remaining tasks to make sure all tasks are completed. This prevents - // memory leaks. - content::RunAllTasksUntilIdle(); -} - -ProfileAttributesStorage* ProfileInfoCacheTest::GetCache() { - return testing_profile_manager_.profile_attributes_storage(); -} - -base::FilePath ProfileInfoCacheTest::GetProfilePath( - const std::string& base_name) { - return testing_profile_manager_.profile_manager()->user_data_dir(). - AppendASCII(base_name); -} - -void ProfileInfoCacheTest::ResetCache() { - testing_profile_manager_.DeleteProfileAttributesStorage(); -} - -std::u16string ProfileInfoCacheTest::GetConcatenation( - const std::u16string& gaia_name, - const std::u16string profile_name) { - std::u16string name_to_display(gaia_name); - name_to_display.append(u" ("); - name_to_display.append(profile_name); - name_to_display.append(u")"); - return name_to_display; -} - -TEST_F(ProfileInfoCacheTest, AddProfiles) { - EXPECT_EQ(0u, GetCache()->GetNumberOfProfiles()); - // Avatar icons not used on Android. -#if !defined(OS_ANDROID) - ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); -#endif - - for (uint32_t i = 0; i < 4; ++i) { - base::FilePath profile_path = - GetProfilePath(base::StringPrintf("path_%ud", i)); - std::u16string profile_name = - ASCIIToUTF16(base::StringPrintf("name_%ud", i)); -#if !defined(OS_ANDROID) - - size_t icon_id = GetDefaultAvatarIconResourceIDAtIndex(i); - const SkBitmap* icon = rb.GetImageNamed(icon_id).ToSkBitmap(); - -#endif // !defined(OS_ANDROID) - std::string supervised_user_id; -#if BUILDFLAG(ENABLE_SUPERVISED_USERS) - if (i == 3) - supervised_user_id = supervised_users::kChildAccountSUID; -#endif - - ProfileAttributesInitParams params; - params.profile_path = profile_path; - params.profile_name = profile_name; - params.icon_index = i; - params.supervised_user_id = supervised_user_id; - GetCache()->AddProfile(std::move(params)); - - ProfileAttributesEntry* entry = - GetCache()->GetProfileAttributesWithPath(profile_path); - entry->SetBackgroundStatus(true); - std::u16string gaia_name = ASCIIToUTF16(base::StringPrintf("gaia_%ud", i)); - entry->SetGAIAName(gaia_name); - - EXPECT_EQ(i + 1, GetCache()->GetNumberOfProfiles()); - std::u16string expected_profile_name = - GetConcatenation(gaia_name, profile_name); - - EXPECT_EQ(expected_profile_name, entry->GetName()); - - EXPECT_EQ(profile_path, entry->GetPath()); -#if !defined(OS_ANDROID) - const SkBitmap* actual_icon = entry->GetAvatarIcon().ToSkBitmap(); - EXPECT_EQ(icon->width(), actual_icon->width()); - EXPECT_EQ(icon->height(), actual_icon->height()); -#endif -#if BUILDFLAG(ENABLE_SUPERVISED_USERS) - EXPECT_EQ(i == 3, entry->IsSupervised()); -#else - EXPECT_FALSE(entry->IsSupervised()); - EXPECT_FALSE(entry->IsOmitted()); -#endif // BUILDFLAG(ENABLE_SUPERVISED_USERS) - EXPECT_EQ(supervised_user_id, entry->GetSupervisedUserId()); - } - - // Reset the cache and test the it reloads correctly. - ResetCache(); - - EXPECT_EQ(4u, GetCache()->GetNumberOfProfiles()); - for (uint32_t i = 0; i < 4; ++i) { - base::FilePath profile_path = - GetProfilePath(base::StringPrintf("path_%ud", i)); - ProfileAttributesEntry* entry = - GetCache()->GetProfileAttributesWithPath(profile_path); - std::u16string profile_name = - ASCIIToUTF16(base::StringPrintf("name_%ud", i)); - std::u16string gaia_name = ASCIIToUTF16(base::StringPrintf("gaia_%ud", i)); - std::u16string expected_profile_name = - GetConcatenation(gaia_name, profile_name); - EXPECT_EQ(expected_profile_name, entry->GetName()); -#if !defined(OS_ANDROID) - EXPECT_EQ(i, entry->GetAvatarIconIndex()); -#endif - EXPECT_EQ(true, entry->GetBackgroundStatus()); - EXPECT_EQ(gaia_name, entry->GetGAIAName()); - } -} - -TEST_F(ProfileInfoCacheTest, GAIAName) { - base::FilePath profile_path_1 = GetProfilePath("path_1"); - ProfileAttributesInitParams params_1; - params_1.profile_path = profile_path_1; - params_1.profile_name = u"Person 1"; - GetCache()->AddProfile(std::move(params_1)); - ProfileAttributesEntry* entry_1 = - GetCache()->GetProfileAttributesWithPath(profile_path_1); - base::FilePath profile_path_2 = GetProfilePath("path_2"); - ProfileAttributesInitParams params_2; - params_2.profile_path = profile_path_2; - params_2.profile_name = u"Person 2"; - GetCache()->AddProfile(std::move(params_2)); - ProfileAttributesEntry* entry_2 = - GetCache()->GetProfileAttributesWithPath(profile_path_2); - - // Sanity check. - EXPECT_TRUE(entry_1->GetGAIAName().empty()); - EXPECT_TRUE(entry_2->GetGAIAName().empty()); - - // Set GAIA name. - std::u16string gaia_name(u"Pat Smith"); - entry_2->SetGAIAName(gaia_name); - // Since there is a GAIA name, we use that as a display name. - EXPECT_TRUE(entry_1->GetGAIAName().empty()); - EXPECT_EQ(gaia_name, entry_2->GetGAIAName()); - EXPECT_EQ(gaia_name, entry_2->GetName()); - - std::u16string custom_name(u"Custom name"); - entry_2->SetLocalProfileName(custom_name, false); - - std::u16string expected_profile_name = - GetConcatenation(gaia_name, custom_name); - EXPECT_EQ(expected_profile_name, entry_2->GetName()); - EXPECT_EQ(gaia_name, entry_2->GetGAIAName()); -} - -TEST_F(ProfileInfoCacheTest, ConcatenateGaiaNameAndProfileName) { - // We should only append the profile name to the GAIA name if: - // - The user has chosen a profile name on purpose. - // - Two profiles has the sama GAIA name and we need to show it to - // clear ambiguity. - // If one of the two conditions hold, we will show the profile name in this - // format |GAIA name (Profile local name)| - // Single profile. - base::FilePath profile_path_1 = GetProfilePath("path_1"); - ProfileAttributesInitParams params_1; - params_1.profile_path = profile_path_1; - params_1.profile_name = u"Person 1"; - GetCache()->AddProfile(std::move(params_1)); - ProfileAttributesEntry* entry_1 = - GetCache()->GetProfileAttributesWithPath(profile_path_1); - EXPECT_EQ(u"Person 1", entry_1->GetName()); - entry_1->SetGAIAName(u"Patt Smith"); - EXPECT_EQ(u"Patt Smith", entry_1->GetName()); - entry_1->SetGAIAGivenName(u"Patt"); - EXPECT_EQ(u"Patt", entry_1->GetName()); - - // Set a custom profile name. - entry_1->SetLocalProfileName(u"Work", false); - EXPECT_EQ(u"Patt (Work)", entry_1->GetName()); - - // Set the profile name to be equal to GAIA name. - entry_1->SetLocalProfileName(u"patt", false); - EXPECT_EQ(u"Patt", entry_1->GetName()); - - // Multiple profiles. - // Add another profile with the same GAIA name and a default profile name. - base::FilePath profile_path_2 = GetProfilePath("path_2"); - ProfileAttributesInitParams params_2; - params_2.profile_path = profile_path_2; - params_2.profile_name = u"Person 2"; - GetCache()->AddProfile(std::move(params_2)); - ProfileAttributesEntry* entry_2 = - GetCache()->GetProfileAttributesWithPath(profile_path_2); - EXPECT_EQ(u"Patt", entry_1->GetName()); - EXPECT_EQ(u"Person 2", entry_2->GetName()); - - entry_1->SetLocalProfileName(u"Work", false); - EXPECT_EQ(u"Patt (Work)", entry_1->GetName()); - EXPECT_EQ(u"Person 2", entry_2->GetName()); - - // A second profile with a different GAIA name should not affect the first - // profile. - entry_2->SetGAIAGivenName(u"Olly"); - EXPECT_EQ(u"Patt (Work)", entry_1->GetName()); - EXPECT_EQ(u"Olly", entry_2->GetName()); - - // Mark profile name as default. - entry_1->SetLocalProfileName(u"Person 1", true); - EXPECT_EQ(u"Patt", entry_1->GetName()); - EXPECT_EQ(u"Olly", entry_2->GetName()); - - // Add a third profile with the same GAIA name as the first. - // The two profiles are marked as using default profile names. - base::FilePath profile_path_3 = GetProfilePath("path_3"); - ProfileAttributesInitParams params_3; - params_3.profile_path = profile_path_3; - params_3.profile_name = u"Person 3"; - GetCache()->AddProfile(std::move(params_3)); - ProfileAttributesEntry* entry_3 = - GetCache()->GetProfileAttributesWithPath(profile_path_3); - entry_3->SetGAIAName(u"Patt Smith"); - EXPECT_EQ(u"Patt", entry_1->GetName()); - EXPECT_EQ(u"Patt Smith", entry_3->GetName()); - - // Two profiles with same GAIA name and default profile name. - // Empty GAIA given name. - entry_3->SetGAIAName(u"Patt"); - EXPECT_EQ(u"Patt (Person 1)", entry_1->GetName()); - EXPECT_EQ(u"Patt (Person 3)", entry_3->GetName()); - // Set GAIA given name. - entry_3->SetGAIAGivenName(u"Patt"); - EXPECT_EQ(u"Patt (Person 1)", entry_1->GetName()); - EXPECT_EQ(u"Patt (Person 3)", entry_3->GetName()); - - // Customize the profile name for one of the two profiles. - entry_3->SetLocalProfileName(u"Personal", false); - EXPECT_EQ(u"Patt", entry_1->GetName()); - EXPECT_EQ(u"Patt (Personal)", entry_3->GetName()); - - // Set one of the profile names to be equal to GAIA name, we should show - // the profile name even if it is Person n to clear ambiguity. - entry_3->SetLocalProfileName(u"patt", false); - EXPECT_EQ(u"Patt (Person 1)", entry_1->GetName()); - EXPECT_EQ(u"Patt", entry_3->GetName()); - - // Never show the profile name if it is equal GAIA name. - entry_1->SetLocalProfileName(u"Patt", false); - EXPECT_EQ(u"Patt", entry_1->GetName()); - EXPECT_EQ(u"Patt", entry_3->GetName()); - EXPECT_EQ(u"Olly", entry_2->GetName()); -} - -TEST_F(ProfileInfoCacheTest, DeleteProfile) { - EXPECT_EQ(0u, GetCache()->GetNumberOfProfiles()); - - base::FilePath path_1 = GetProfilePath("path_1"); - ProfileAttributesInitParams params_1; - params_1.profile_path = path_1; - params_1.profile_name = u"name_1"; - GetCache()->AddProfile(std::move(params_1)); - EXPECT_EQ(1u, GetCache()->GetNumberOfProfiles()); - - base::FilePath path_2 = GetProfilePath("path_2"); - std::u16string name_2 = u"name_2"; - ProfileAttributesInitParams params_2; - params_2.profile_path = path_2; - params_2.profile_name = name_2; - GetCache()->AddProfile(std::move(params_2)); - ProfileAttributesEntry* entry = - GetCache()->GetProfileAttributesWithPath(path_2); - EXPECT_EQ(2u, GetCache()->GetNumberOfProfiles()); - - GetCache()->RemoveProfile(path_1); - EXPECT_EQ(1u, GetCache()->GetNumberOfProfiles()); - EXPECT_EQ(name_2, entry->GetName()); - - GetCache()->RemoveProfile(path_2); - EXPECT_EQ(0u, GetCache()->GetNumberOfProfiles()); -} - -TEST_F(ProfileInfoCacheTest, MutateProfile) { - base::FilePath profile_path_1 = GetProfilePath("path_1"); - ProfileAttributesInitParams params_1; - params_1.profile_path = profile_path_1; - params_1.profile_name = u"name_1"; - GetCache()->AddProfile(std::move(params_1)); - - base::FilePath profile_path_2 = GetProfilePath("path_2"); - ProfileAttributesInitParams params_2; - params_2.profile_path = profile_path_2; - params_2.profile_name = u"name_2"; - GetCache()->AddProfile(std::move(params_2)); - ProfileAttributesEntry* entry_1 = - GetCache()->GetProfileAttributesWithPath(profile_path_1); - ProfileAttributesEntry* entry_2 = - GetCache()->GetProfileAttributesWithPath(profile_path_2); - - std::u16string new_name = u"new_name"; - entry_2->SetLocalProfileName(new_name, false); - EXPECT_EQ(new_name, entry_2->GetName()); - EXPECT_NE(new_name, entry_1->GetName()); - - std::u16string new_user_name = u"user_name"; - std::string new_gaia_id = "12345"; - entry_2->SetAuthInfo(new_gaia_id, new_user_name, true); - EXPECT_EQ(new_user_name, entry_2->GetUserName()); - EXPECT_EQ(new_gaia_id, entry_2->GetGAIAId()); - EXPECT_NE(new_user_name, entry_1->GetUserName()); - - // Avatar icons not used on Android. -#if !defined(OS_ANDROID) - const size_t new_icon_index = 3; - entry_2->SetAvatarIconIndex(new_icon_index); - EXPECT_EQ(new_icon_index, entry_2->GetAvatarIconIndex()); -#endif -} - -// Will be removed SOON with ProfileInfoCache tests. -TEST_F(ProfileInfoCacheTest, BackgroundModeStatus) { - base::FilePath path_1 = GetProfilePath("path_1"); - ProfileAttributesInitParams params_1; - params_1.profile_path = path_1; - params_1.profile_name = u"name_1"; - GetCache()->AddProfile(std::move(params_1)); - - base::FilePath path_2 = GetProfilePath("path_2"); - ProfileAttributesInitParams params_2; - params_2.profile_path = path_2; - params_2.profile_name = u"name_2"; - GetCache()->AddProfile(std::move(params_2)); - - ProfileAttributesEntry* entry_1 = - GetCache()->GetProfileAttributesWithPath(path_1); - ProfileAttributesEntry* entry_2 = - GetCache()->GetProfileAttributesWithPath(path_2); - EXPECT_FALSE(entry_1->GetBackgroundStatus()); - EXPECT_FALSE(entry_2->GetBackgroundStatus()); - - entry_2->SetBackgroundStatus(true); - - EXPECT_FALSE(entry_1->GetBackgroundStatus()); - EXPECT_TRUE(entry_2->GetBackgroundStatus()); - - entry_1->SetBackgroundStatus(true); - - EXPECT_TRUE(entry_1->GetBackgroundStatus()); - EXPECT_TRUE(entry_2->GetBackgroundStatus()); - - entry_2->SetBackgroundStatus(false); - - EXPECT_TRUE(entry_1->GetBackgroundStatus()); - EXPECT_FALSE(entry_2->GetBackgroundStatus()); -} - -#if BUILDFLAG(ENABLE_SUPERVISED_USERS) -TEST_F(ProfileInfoCacheTest, SetSupervisedUserId) { - base::FilePath profile_path = GetProfilePath("test"); - ProfileAttributesInitParams params; - params.profile_path = profile_path; - params.profile_name = u"Test"; - GetCache()->AddProfile(std::move(params)); - ProfileAttributesEntry* entry = - GetCache()->GetProfileAttributesWithPath(profile_path); - EXPECT_FALSE(entry->IsSupervised()); - - entry->SetSupervisedUserId(supervised_users::kChildAccountSUID); - EXPECT_TRUE(entry->IsSupervised()); - EXPECT_EQ(supervised_users::kChildAccountSUID, entry->GetSupervisedUserId()); - - ResetCache(); - entry = GetCache()->GetProfileAttributesWithPath(profile_path); - EXPECT_TRUE(entry->IsSupervised()); - - entry->SetSupervisedUserId(std::string()); - EXPECT_FALSE(entry->IsSupervised()); - EXPECT_EQ("", entry->GetSupervisedUserId()); -} -#endif // BUILDFLAG(ENABLE_SUPERVISED_USERS) - -#if BUILDFLAG(ENABLE_SUPERVISED_USERS) -TEST_F(ProfileInfoCacheTest, CreateSupervisedTestingProfile) { - base::FilePath path_1 = - testing_profile_manager_.CreateTestingProfile("default")->GetPath(); - std::u16string supervised_user_name = u"Supervised User"; - base::FilePath path_2 = - testing_profile_manager_ - .CreateTestingProfile( - "test1", std::unique_ptr<sync_preferences::PrefServiceSyncable>(), - supervised_user_name, 0, supervised_users::kChildAccountSUID, - TestingProfile::TestingFactories()) - ->GetPath(); - base::FilePath profile_path[] = {path_1, path_2}; - for (const base::FilePath& path : profile_path) { - ProfileAttributesEntry* entry = - GetCache()->GetProfileAttributesWithPath(path); - bool is_supervised = entry->GetName() == supervised_user_name; - EXPECT_EQ(is_supervised, entry->IsSupervised()); - std::string supervised_user_id = - is_supervised ? supervised_users::kChildAccountSUID : ""; - EXPECT_EQ(supervised_user_id, entry->GetSupervisedUserId()); - } - - // Supervised profiles have a custom theme, which needs to be deleted on the - // FILE thread. Reset the profile manager now so everything is deleted while - // we still have a FILE thread. - TestingBrowserProcess::GetGlobal()->SetProfileManager(nullptr); -} -#endif - -TEST_F(ProfileInfoCacheTest, AddStubProfile) { - EXPECT_EQ(0u, GetCache()->GetNumberOfProfiles()); - - // Add some profiles with and without a '.' in their paths. - const struct { - const char* profile_path; - const char* profile_name; - } kTestCases[] = { - { "path.test0", "name_0" }, - { "path_test1", "name_1" }, - { "path.test2", "name_2" }, - { "path_test3", "name_3" }, - }; - - for (size_t i = 0; i < base::size(kTestCases); ++i) { - base::FilePath profile_path = GetProfilePath(kTestCases[i].profile_path); - std::u16string profile_name = ASCIIToUTF16(kTestCases[i].profile_name); - - ProfileAttributesInitParams params; - params.profile_path = profile_path; - params.profile_name = profile_name; - GetCache()->AddProfile(std::move(params)); - ProfileAttributesEntry* entry = - GetCache()->GetProfileAttributesWithPath(profile_path); - EXPECT_TRUE(entry); - EXPECT_EQ(profile_name, entry->GetName()); - } - - ASSERT_EQ(4U, GetCache()->GetNumberOfProfiles()); - - // Check that the profiles can be extracted from the local state. - std::vector<std::u16string> names; - PrefService* local_state = g_browser_process->local_state(); - const base::DictionaryValue* cache = - local_state->GetDictionary(prefs::kProfileAttributes); - std::u16string name; - for (base::DictionaryValue::Iterator it(*cache); !it.IsAtEnd(); - it.Advance()) { - const base::DictionaryValue* info = NULL; - it.value().GetAsDictionary(&info); - info->GetString("name", &name); - names.push_back(name); - } - - for (size_t i = 0; i < 4; i++) - ASSERT_FALSE(names[i].empty()); -} - -TEST_F(ProfileInfoCacheTest, EntriesInAttributesStorage) { - EXPECT_EQ(0u, GetCache()->GetNumberOfProfiles()); - - // Add some profiles with and without a '.' in their paths. - const struct { - const char* profile_path; - const char* profile_name; - } kTestCases[] = { - { "path.test0", "name_0" }, - { "path_test1", "name_1" }, - { "path.test2", "name_2" }, - { "path_test3", "name_3" }, - }; - - // Profiles are added and removed using all combinations of the old and the - // new interfaces. The content of |profile_attributes_entries_| in - // ProfileAttributesStorage is checked after each insert and delete operation. - - // Add profiles. - for (size_t i = 0; i < base::size(kTestCases); ++i) { - base::FilePath profile_path = GetProfilePath(kTestCases[i].profile_path); - std::u16string profile_name = ASCIIToUTF16(kTestCases[i].profile_name); - - ASSERT_EQ(0u, GetCache()->profile_attributes_entries_.count( - profile_path.value())); - - // Use ProfileInfoCache in profiles 0 and 2, and ProfileAttributesStorage in - // profiles 1 and 3. - ProfileAttributesInitParams params; - params.profile_path = profile_path; - params.profile_name = profile_name; - params.icon_index = i; - if (i == 0 || i == 2) { - GetCache()->AddProfile(std::move(params)); - } else { - GetCache()->AddProfile(std::move(params)); - } - - ASSERT_EQ(i + 1, GetCache()->GetNumberOfProfiles()); - ASSERT_EQ(i + 1, GetCache()->profile_attributes_entries_.size()); - - ASSERT_EQ(1u, GetCache()->profile_attributes_entries_.count( - profile_path.value())); - - ProfileAttributesEntry* entry = - GetCache()->GetProfileAttributesWithPath(profile_path); - EXPECT_EQ(entry, - &GetCache()->profile_attributes_entries_[profile_path.value()]); - } - - // Remove profiles. - for (size_t i = 0; i < base::size(kTestCases); ++i) { - base::FilePath profile_path = GetProfilePath(kTestCases[i].profile_path); - ASSERT_EQ(1u, GetCache()->profile_attributes_entries_.count( - profile_path.value())); - - // Use ProfileInfoCache in profiles 0 and 1, and ProfileAttributesStorage in - // profiles 2 and 3. - if (i == 0 || i == 1) - GetCache()->RemoveProfile(profile_path); - else - GetCache()->RemoveProfile(profile_path); - - ASSERT_EQ(0u, GetCache()->profile_attributes_entries_.count( - profile_path.value())); - - ProfileAttributesEntry* entry = - GetCache()->GetProfileAttributesWithPath(profile_path); - EXPECT_EQ(entry, nullptr); - ASSERT_EQ(0u, GetCache()->profile_attributes_entries_.count( - profile_path.value())); - } -} - -#if !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH) -TEST_F(ProfileInfoCacheTest, MigrateLegacyProfileNamesAndRecomputeIfNeeded) { - EXPECT_EQ(0U, GetCache()->GetNumberOfProfiles()); - // Mimick a pre-existing Directory with profiles that has legacy profile - // names. - const struct { - const char* profile_path; - const char* profile_name; - bool is_using_default_name; - } kTestCases[] = { - {"path_1", "Default Profile", true}, {"path_2", "First user", true}, - {"path_3", "Lemonade", true}, {"path_4", "Batman", true}, - {"path_5", "Batman", false}, {"path_6", "Person 2", true}, - {"path_7", "Person 3", true}, {"path_8", "Person 1", true}, - {"path_9", "Person 2", true}, {"path_10", "Person 1", true}, - {"path_11", "Smith", false}, {"path_12", "Person 2", true}}; - - ProfileAttributesEntry* entry = nullptr; - for (size_t i = 0; i < base::size(kTestCases); ++i) { - base::FilePath profile_path = GetProfilePath(kTestCases[i].profile_path); - ProfileAttributesInitParams params; - params.profile_path = profile_path; - params.profile_name = ASCIIToUTF16(kTestCases[i].profile_name); - params.icon_index = i; - GetCache()->AddProfile(std::move(params)); - entry = GetCache()->GetProfileAttributesWithPath(profile_path); - EXPECT_TRUE(entry); - entry->SetIsUsingDefaultName(kTestCases[i].is_using_default_name); - } - - EXPECT_EQ(12U, GetCache()->GetNumberOfProfiles()); - - ResetCache(); - ProfileAttributesStorage::SetLegacyProfileMigrationForTesting(true); - GetCache(); - ProfileAttributesStorage::SetLegacyProfileMigrationForTesting(false); - - entry = GetCache()->GetProfileAttributesWithPath( - GetProfilePath(kTestCases[4].profile_path)); - EXPECT_EQ(ASCIIToUTF16(kTestCases[4].profile_name), entry->GetName()); - entry = GetCache()->GetProfileAttributesWithPath( - GetProfilePath(kTestCases[10].profile_path)); - EXPECT_EQ(ASCIIToUTF16(kTestCases[10].profile_name), entry->GetName()); - - // Legacy profile names like "Default Profile" and "First user" should be - // migrated to "Person %n" type names, i.e. any permutation of "Person %n". - std::set<std::u16string> expected_profile_names{ - u"Person 1", u"Person 2", u"Person 3", u"Person 4", u"Person 5", - u"Person 6", u"Person 7", u"Person 8", u"Person 9", u"Person 10"}; - - const char* profile_path[] = { - kTestCases[0].profile_path, kTestCases[1].profile_path, - kTestCases[2].profile_path, kTestCases[3].profile_path, - kTestCases[5].profile_path, kTestCases[6].profile_path, - kTestCases[7].profile_path, kTestCases[8].profile_path, - kTestCases[9].profile_path, kTestCases[11].profile_path}; - - std::set<std::u16string> actual_profile_names; - for (auto* path : profile_path) { - entry = GetCache()->GetProfileAttributesWithPath(GetProfilePath(path)); - actual_profile_names.insert(entry->GetName()); - } - EXPECT_EQ(actual_profile_names, expected_profile_names); -} -#endif - -#if BUILDFLAG(IS_CHROMEOS_ASH) || defined(OS_ANDROID) -TEST_F(ProfileInfoCacheTest, - DontMigrateLegacyProfileNamesWithoutNewAvatarMenu) { - EXPECT_EQ(0U, GetCache()->GetNumberOfProfiles()); - - const struct { - const char* profile_path; - const char* profile_name; - } kTestCases[] = {{"path_1", "Default Profile"}, - {"path_2", "First user"}, - {"path_3", "Lemonade"}, - {"path_4", "Batman"}}; - - for (size_t i = 0; i < base::size(kTestCases); ++i) { - base::FilePath profile_path = GetProfilePath(kTestCases[i].profile_path); - ProfileAttributesInitParams params; - params.profile_path = profile_path; - params.profile_name = ASCIIToUTF16(kTestCases[i].profile_name); - params.icon_index = i; - GetCache()->AddProfile(std::move(params)); - ProfileAttributesEntry* entry = - GetCache()->GetProfileAttributesWithPath(profile_path); - EXPECT_TRUE(entry); - entry->SetIsUsingDefaultName(true); - } - EXPECT_EQ(4U, GetCache()->GetNumberOfProfiles()); - - ResetCache(); - - // Profile names should have been preserved. - for (size_t i = 0; i < base::size(kTestCases); ++i) { - base::FilePath profile_path = GetProfilePath(kTestCases[i].profile_path); - std::u16string profile_name = ASCIIToUTF16(kTestCases[i].profile_name); - ProfileAttributesEntry* entry = - GetCache()->GetProfileAttributesWithPath(profile_path); - EXPECT_TRUE(entry); - EXPECT_EQ(profile_name, entry->GetName()); - } -} -#endif - -TEST_F(ProfileInfoCacheTest, RemoveProfileByAccountId) { - EXPECT_EQ(0u, GetCache()->GetNumberOfProfiles()); - const struct { - const char* profile_path; - const char* profile_name; - AccountId account_id; - bool is_consented_primary_account; - } kTestCases[] = { - {"path_1", "name_1", AccountId::FromUserEmailGaiaId("email1", "111111"), - true}, - {"path_2", "name_3", AccountId::FromUserEmailGaiaId("email2", "222222"), - true}, - {"path_3", "name_3", AccountId::FromUserEmailGaiaId("email3", "333333"), - false}, - {"path_4", "name_4", AccountId::FromUserEmailGaiaId("email4", "444444"), - false}}; - - for (size_t i = 0; i < base::size(kTestCases); ++i) { - ProfileAttributesInitParams params; - params.profile_path = GetProfilePath(kTestCases[i].profile_path); - params.profile_name = ASCIIToUTF16(kTestCases[i].profile_name); - params.gaia_id = kTestCases[i].account_id.GetGaiaId(); - params.user_name = UTF8ToUTF16(kTestCases[i].account_id.GetUserEmail()); - params.is_consented_primary_account = - kTestCases[i].is_consented_primary_account; - GetCache()->AddProfile(std::move(params)); - EXPECT_EQ(i + 1, GetCache()->GetNumberOfProfiles()); - } - - GetCache()->RemoveProfileByAccountId(kTestCases[2].account_id); - EXPECT_EQ(3u, GetCache()->GetNumberOfProfiles()); - - GetCache()->RemoveProfileByAccountId(kTestCases[0].account_id); - EXPECT_EQ(2u, GetCache()->GetNumberOfProfiles()); - - // this profile is already deleted. - GetCache()->RemoveProfileByAccountId(kTestCases[2].account_id); - EXPECT_EQ(2u, GetCache()->GetNumberOfProfiles()); - - // Remove profile by partial match - GetCache()->RemoveProfileByAccountId( - AccountId::FromUserEmail(kTestCases[1].account_id.GetUserEmail())); - EXPECT_EQ(1u, GetCache()->GetNumberOfProfiles()); - - // Remove last profile - GetCache()->RemoveProfileByAccountId(kTestCases[3].account_id); - EXPECT_EQ(0u, GetCache()->GetNumberOfProfiles()); -} - -// Checks that ProfileInfoCache doesn't crash when ProfileAttributesEntry -// initialization modifies the cache entry. -// This is a regression test for https://crbug.com/1180497. -TEST_F(ProfileInfoCacheTest, ModifiyEntryWhileInitializing) { - base::FilePath profile_path = GetProfilePath("test"); - { - signin_util::ScopedForceSigninSetterForTesting force_signin_setter(true); - AccountId account_id = AccountId::FromUserEmailGaiaId("email", "111111"); - ProfileAttributesInitParams params; - params.profile_path = profile_path; - params.profile_name = u"Test"; - params.gaia_id = account_id.GetGaiaId(); - params.user_name = UTF8ToUTF16(account_id.GetUserEmail()); - GetCache()->AddProfile(std::move(params)); - ProfileAttributesEntry* entry = - GetCache()->GetProfileAttributesWithPath(profile_path); - // Set up the state so that ProfileAttributesEntry::Initialize() will modify - // the cache entry. - entry->LockForceSigninProfile(true); - } - // Reinitialize ProfileInfoCache. - ResetCache(); - GetCache(); // Should not crash. - - // The IsSigninRequired attribute should be cleaned up. - ProfileAttributesEntry* entry = - GetCache()->GetProfileAttributesWithPath(profile_path); - EXPECT_FALSE(entry->IsSigninRequired()); -} - -TEST_F(ProfileInfoCacheTest, ProfileNamesOnInit) { - // Set up the cache with two profiles having the same GAIA given name. - // The second profile also has a profile name matching the GAIA given name. - std::u16string kDefaultProfileName = u"Person 1"; - std::u16string kCommonName = u"Joe"; - - // Create and initialize the first profile. - base::FilePath path_1 = GetProfilePath("path_1"); - ProfileAttributesInitParams params_1; - params_1.profile_path = path_1; - params_1.profile_name = kDefaultProfileName; - GetCache()->AddProfile(std::move(params_1)); - ProfileAttributesEntry* entry_1 = - GetCache()->GetProfileAttributesWithPath(path_1); - entry_1->SetGAIAGivenName(kCommonName); - EXPECT_EQ(entry_1->GetName(), kCommonName); - - // Create and initialize the second profile. - base::FilePath path_2 = GetProfilePath("path_2"); - ProfileAttributesInitParams params_2; - params_2.profile_path = path_2; - params_2.profile_name = kCommonName; - GetCache()->AddProfile(std::move(params_2)); - ProfileAttributesEntry* entry_2 = - GetCache()->GetProfileAttributesWithPath(path_2); - entry_2->SetGAIAGivenName(kCommonName); - EXPECT_EQ(entry_2->GetName(), kCommonName); - - // The first profile name should be modified. - EXPECT_EQ(entry_1->GetName(), - GetConcatenation(kCommonName, kDefaultProfileName)); - - // Reset cache to test profile names set on initialization. - ResetCache(); - entry_1 = GetCache()->GetProfileAttributesWithPath(path_1); - entry_2 = GetCache()->GetProfileAttributesWithPath(path_2); - - // Freshly initialized entries should not report name changes. - EXPECT_FALSE(entry_1->HasProfileNameChanged()); - EXPECT_FALSE(entry_2->HasProfileNameChanged()); - - EXPECT_EQ(entry_1->GetName(), - GetConcatenation(kCommonName, kDefaultProfileName)); - EXPECT_EQ(entry_2->GetName(), kCommonName); -}
diff --git a/chrome/browser/profiles/profile_info_cache_unittest.h b/chrome/browser/profiles/profile_info_cache_unittest.h deleted file mode 100644 index 275c4832..0000000 --- a/chrome/browser/profiles/profile_info_cache_unittest.h +++ /dev/null
@@ -1,72 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_PROFILES_PROFILE_INFO_CACHE_UNITTEST_H_ -#define CHROME_BROWSER_PROFILES_PROFILE_INFO_CACHE_UNITTEST_H_ - -#include <set> - -#include "chrome/browser/profiles/profile_attributes_storage.h" -#include "chrome/test/base/testing_profile_manager.h" -#include "content/public/test/browser_task_environment.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace base { -class FilePath; -} - -// Class used to test that ProfileInfoCache does not try to access any -// unexpected profile names. -class ProfileNameVerifierObserver : public ProfileAttributesStorage::Observer { - public: - explicit ProfileNameVerifierObserver( - TestingProfileManager* testing_profile_manager); - ProfileNameVerifierObserver(const ProfileNameVerifierObserver&) = delete; - ProfileNameVerifierObserver& operator=(const ProfileNameVerifierObserver&) = - delete; - ~ProfileNameVerifierObserver() override; - - // ProfileAttributesStorage::Observer overrides: - void OnProfileAdded(const base::FilePath& profile_path) override; - void OnProfileWillBeRemoved(const base::FilePath& profile_path) override; - void OnProfileWasRemoved(const base::FilePath& profile_path, - const std::u16string& profile_name) override; - void OnProfileNameChanged(const base::FilePath& profile_path, - const std::u16string& old_profile_name) override; - void OnProfileAvatarChanged(const base::FilePath& profile_path) override; - - private: - ProfileAttributesStorage* GetCache(); - std::map<base::FilePath, std::u16string> profile_names_; - TestingProfileManager* testing_profile_manager_; -}; - -class ProfileInfoCacheTest : public testing::Test { - protected: - ProfileInfoCacheTest(); - ~ProfileInfoCacheTest() override; - - void SetUp() override; - void TearDown() override; - - ProfileAttributesStorage* GetCache(); - base::FilePath GetProfilePath(const std::string& base_name); - void ResetCache(); - void RemoveObserver(); - std::u16string GetConcatenation(const std::u16string& gaia_name, - const std::u16string profile_name); - - private: - // BrowserTaskEnvironment needs to be up through the destruction of the - // TestingProfileManager below. - content::BrowserTaskEnvironment task_environment_; - - protected: - TestingProfileManager testing_profile_manager_; - - private: - ProfileNameVerifierObserver name_observer_; -}; - -#endif // CHROME_BROWSER_PROFILES_PROFILE_INFO_CACHE_UNITTEST_H_
diff --git a/chrome/browser/profiles/profile_manager.cc b/chrome/browser/profiles/profile_manager.cc index 6231d7f..aef8964 100644 --- a/chrome/browser/profiles/profile_manager.cc +++ b/chrome/browser/profiles/profile_manager.cc
@@ -1924,7 +1924,7 @@ .get(); if (password_store.get()) { password_store->RemoveLoginsCreatedBetween( - base::Time(), base::Time::Max(), base::OnceClosure()); + base::Time(), base::Time::Max(), base::DoNothing()); } // The Profile Data doesn't get wiped until Chrome closes. Since we promised
diff --git a/chrome/browser/resources/accessibility/accessibility.js b/chrome/browser/resources/accessibility/accessibility.js index f60c8d5..8bc655d 100644 --- a/chrome/browser/resources/accessibility/accessibility.js +++ b/chrome/browser/resources/accessibility/accessibility.js
@@ -73,6 +73,11 @@ get kAXModeComplete() { return AXMode.kNativeAPIs | AXMode.kWebContents | AXMode.kInlineTextBoxes | AXMode.kScreenReader | AXMode.kHTML; + }, + + get kAXModeCompleteNoHTML() { + return AXMode.kNativeAPIs | AXMode.kWebContents | AXMode.kInlineTextBoxes | + AXMode.kScreenReader; } };
diff --git a/chrome/browser/resources/chromeos/login/arc_terms_of_service.html b/chrome/browser/resources/chromeos/login/arc_terms_of_service.html index 0c8721b..01eff082 100644 --- a/chrome/browser/resources/chromeos/login/arc_terms_of_service.html +++ b/chrome/browser/resources/chromeos/login/arc_terms_of_service.html
@@ -106,17 +106,19 @@ <!-- As this dialog have pre-loading logic that require access to elements, dialog is marked as no-lazy. --> <oobe-adaptive-dialog id="arcTosDialog" for-step="loaded" - role="dialog" - aria-label$="[[i18nDynamic(locale, 'arcTermsOfServiceScreenHeading')]]" + role="dialog" aria-label$="[[getDialogTitle_(locale, isChild)]]" no-lazy> <iron-icon src="chrome://oobe/playstore.svg" slot="icon"> </iron-icon> <h1 slot="title"> - [[i18nDynamic(locale, 'arcTermsOfServiceScreenHeading')]] + [[getDialogTitle_(locale, isChild)]] </h1> - <p slot="subtitle"> + <p slot="subtitle" hidden="[[isChild]]"> [[i18nDynamic(locale, 'arcTermsOfServiceScreenDescription')]] </p> + <p slot="subtitle" hidden="[[!isChild]]"> + [[i18nDynamic(locale, 'arcTermsOfServiceScreenDescriptionForChild')]] + </p> <div id="arcTosContainer" slot="content" class="flex layout vertical"> <webview id="arcTosView" allowTransparency role="document" class="flex oobe-tos-webview"
diff --git a/chrome/browser/resources/chromeos/login/arc_terms_of_service.js b/chrome/browser/resources/chromeos/login/arc_terms_of_service.js index d3bc27d..73a3e63 100644 --- a/chrome/browser/resources/chromeos/login/arc_terms_of_service.js +++ b/chrome/browser/resources/chromeos/login/arc_terms_of_service.js
@@ -776,5 +776,13 @@ this.lastFocusedElement_ = null; } }, + + /** + * Returns dialog title based on whether the active user is child. + */ + getDialogTitle_(locale, isChild) { + return isChild ? this.i18n('arcTermsOfServiceScreenHeadingForChild') : + this.i18n('arcTermsOfServiceScreenHeading'); + } }); })();
diff --git a/chrome/browser/resources/settings/chromeos/BUILD.gn b/chrome/browser/resources/settings/chromeos/BUILD.gn index 56fbac3f..b9ea188e 100644 --- a/chrome/browser/resources/settings/chromeos/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/BUILD.gn
@@ -380,6 +380,7 @@ "chromeos/os_apps_page/android_apps_browser_proxy.m.js", "chromeos/os_apps_page/android_apps_subpage.m.js", "chromeos/os_apps_page/app_notifications_page/app_notifications_subpage.js", + "chromeos/os_apps_page/app_notifications_page/app_notification_row.js", "chromeos/os_apps_page/app_management_page/actions.m.js", "chromeos/os_apps_page/app_management_page/api_listener.m.js", "chromeos/os_apps_page/app_management_page/app_detail_view.m.js",
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_notifications_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_apps_page/app_notifications_page/BUILD.gn index cb7fe2c..dd348b9 100644 --- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_notifications_page/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_notifications_page/BUILD.gn
@@ -8,7 +8,10 @@ import("//tools/polymer/html_to_js.gni") import("//ui/webui/resources/tools/generate_grd.gni") -polymer_element_files = [ "app_notifications_subpage.js" ] +polymer_element_files = [ + "app_notifications_subpage.js", + "app_notification_row.js", +] js_type_check("closure_compile") { is_polymer3 = true @@ -18,6 +21,13 @@ js_library("app_notifications_subpage") { deps = [ + ":app_notification_row", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + ] +} + +js_library("app_notification_row") { + deps = [ "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", ] }
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_notifications_page/app_notification_row.html b/chrome/browser/resources/settings/chromeos/os_apps_page/app_notifications_page/app_notification_row.html new file mode 100644 index 0000000..c5f2ecf --- /dev/null +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_notifications_page/app_notification_row.html
@@ -0,0 +1,32 @@ +<style include="cr-icons"> + :host { + align-items: center; + border-bottom: var(--card-separator); + color: var(--cros-text-color-primary); + display: flex; + flex-direction: row; + font-weight: 400; + height: 48px; + } + + #appTitle { + flex: 1; + overflow: hidden; + text-overflow: ellipsis; + } + + #appToggle { + padding: 0 20px 0 0; + } + + #appIcon { + height: 32px; + margin-inline-end: 20px; + margin-inline-start: 24px; + width: 32px; + } +</style> +<img id="appIcon" src="chrome://app-icon/[[app.id]]/64" + alt="[[app.title]] app icon." aria-hidden="true"> +<div id="appTitle" aria-hidden="true">[[app.title]]</div> +<cr-toggle id="appToggle"></cr-toggle> \ No newline at end of file
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_notifications_page/app_notification_row.js b/chrome/browser/resources/settings/chromeos/os_apps_page/app_notifications_page/app_notification_row.js new file mode 100644 index 0000000..e766983 --- /dev/null +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_notifications_page/app_notification_row.js
@@ -0,0 +1,31 @@ +// 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 {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +/** + * @fileoverview + * 'app-notification-row' is a custom row element for the OS Settings + * Notifications Subpage. Each row contains an app icon, app name, and toggle. + */ +export class AppNotificationRowElement extends PolymerElement { + static get is() { + return 'app-notification-row'; + } + + static get template() { + return html`{__html_template__}`; + } + + static get properties() { + return { + /** @type {!Object} */ + app: { + type: Object, + }, + }; + } +} + +customElements.define(AppNotificationRowElement.is, AppNotificationRowElement); \ No newline at end of file
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_notifications_page/app_notifications_subpage.html b/chrome/browser/resources/settings/chromeos/os_apps_page/app_notifications_page/app_notifications_subpage.html index a95c755..508abfd 100644 --- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_notifications_page/app_notifications_subpage.html +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_notifications_page/app_notifications_subpage.html
@@ -1 +1,5 @@ -<div id="testDiv">Notifications</div> \ No newline at end of file +<div id="appNotificationsList"> + <template is="dom-repeat" items="[[appList_]]" as="app"> + <app-notification-row app="[[app]]"></app-notification-row> + </template> +</div> \ No newline at end of file
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_notifications_page/app_notifications_subpage.js b/chrome/browser/resources/settings/chromeos/os_apps_page/app_notifications_page/app_notifications_subpage.js index 4089209..3d2e6f33 100644 --- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_notifications_page/app_notifications_subpage.js +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_notifications_page/app_notifications_subpage.js
@@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import './app_notification_row.js'; import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; /** @@ -18,6 +19,24 @@ static get template() { return html`{__html_template__}`; } + + static get properties() { + return { + /** + * @type {!Array<!Object>} + * @private + */ + appList_: { + type: Array, + // TODO(ethanimooney): Replace placeholders with proper implementation + // for apps + value: [ + {title: 'Chrome', id: 'mgndgikekgjfcpckkfioiadnlibdjbkf'}, + {title: 'Files', id: 'hhaomjibdihmijegdhdafkllkbggdgoj'} + ], + }, + }; + } } customElements.define(AppNotificationsSubpage.is, AppNotificationsSubpage); \ No newline at end of file
diff --git a/chrome/browser/resources/settings/clear_browsing_data_dialog/clear_browsing_data_dialog.html b/chrome/browser/resources/settings/clear_browsing_data_dialog/clear_browsing_data_dialog.html index 9e7f2ed..5a5af6b 100644 --- a/chrome/browser/resources/settings/clear_browsing_data_dialog/clear_browsing_data_dialog.html +++ b/chrome/browser/resources/settings/clear_browsing_data_dialog/clear_browsing_data_dialog.html
@@ -127,6 +127,13 @@ padding-inline-end: var(--cr-icon-button-margin-start); width: var(--cr-link-row-icon-width, var(--cr-icon-size)); } + + @media (prefers-color-scheme: dark) { + .search-history-box-icon { + --iron-icon-fill-color: var(--cr-link-row-start-icon-color, + var(--google-grey-refresh-500)); + } + } </style> <cr-dialog id="clearBrowsingDataDialog" @@ -192,7 +199,7 @@ <div class="search-history-box" hidden="[[!shouldShowGoogleSearchHistoryLabel_(isSignedIn_)]]"> <iron-icon class="search-history-box-icon" aria-hidden="true" - icon="settings20:safety-check"> + icon="settings20:googleg"> </iron-icon> <div id="googleSearchHistoryLabel" inner-h-t-m-l="[[googleSearchHistoryString_]]">
diff --git a/chrome/browser/safe_browsing/chrome_safe_browsing_blocking_page_factory.cc b/chrome/browser/safe_browsing/chrome_safe_browsing_blocking_page_factory.cc index 3f03916e..71bdbaab 100644 --- a/chrome/browser/safe_browsing/chrome_safe_browsing_blocking_page_factory.cc +++ b/chrome/browser/safe_browsing/chrome_safe_browsing_blocking_page_factory.cc
@@ -4,8 +4,13 @@ #include "chrome/browser/safe_browsing/chrome_safe_browsing_blocking_page_factory.h" +#include "chrome/browser/history/history_service_factory.h" +#include "chrome/browser/interstitials/chrome_settings_page_helper.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/safe_browsing/chrome_controller_client.h" #include "components/prefs/pref_service.h" +#include "components/security_interstitials/content/content_metrics_helper.h" +#include "components/security_interstitials/content/security_interstitial_controller_client.h" #include "content/public/browser/web_contents.h" namespace safe_browsing { @@ -49,12 +54,40 @@ true, // is_enhanced_protection_message_enabled IsSafeBrowsingPolicyManaged(*prefs), kHelpCenterLink); - return new SafeBrowsingBlockingPage(ui_manager, web_contents, main_frame_url, - unsafe_resources, display_options, - should_trigger_reporting); + return new SafeBrowsingBlockingPage( + ui_manager, web_contents, main_frame_url, unsafe_resources, + CreateControllerClient(web_contents, unsafe_resources, ui_manager), + display_options, should_trigger_reporting); } ChromeSafeBrowsingBlockingPageFactory::ChromeSafeBrowsingBlockingPageFactory() = default; +// static +std::unique_ptr<security_interstitials::SecurityInterstitialControllerClient> +ChromeSafeBrowsingBlockingPageFactory::CreateControllerClient( + content::WebContents* web_contents, + const SafeBrowsingBlockingPage::UnsafeResourceList& unsafe_resources, + const BaseUIManager* ui_manager) { + Profile* profile = + Profile::FromBrowserContext(web_contents->GetBrowserContext()); + DCHECK(profile); + + std::unique_ptr<ContentMetricsHelper> metrics_helper = + std::make_unique<ContentMetricsHelper>( + HistoryServiceFactory::GetForProfile( + Profile::FromBrowserContext(web_contents->GetBrowserContext()), + ServiceAccessType::EXPLICIT_ACCESS), + unsafe_resources[0].url, + BaseBlockingPage::GetReportingInfo(unsafe_resources)); + + auto chrome_settings_page_helper = + std::make_unique<security_interstitials::ChromeSettingsPageHelper>(); + + return std::make_unique<ChromeControllerClient>( + web_contents, std::move(metrics_helper), profile->GetPrefs(), + ui_manager->app_locale(), ui_manager->default_safe_page(), + std::move(chrome_settings_page_helper)); +} + } // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/chrome_safe_browsing_blocking_page_factory.h b/chrome/browser/safe_browsing/chrome_safe_browsing_blocking_page_factory.h index 8f681a9..bfbf3c04 100644 --- a/chrome/browser/safe_browsing/chrome_safe_browsing_blocking_page_factory.h +++ b/chrome/browser/safe_browsing/chrome_safe_browsing_blocking_page_factory.h
@@ -26,6 +26,15 @@ ChromeSafeBrowsingBlockingPageFactory& operator=( const ChromeSafeBrowsingBlockingPageFactory&) = delete; + // Creates a SecurityInterstitialControllerClient configured for //chrome for + // safe browsing blocking pages. + static std::unique_ptr< + security_interstitials::SecurityInterstitialControllerClient> + CreateControllerClient( + content::WebContents* web_contents, + const SafeBrowsingBlockingPage::UnsafeResourceList& unsafe_resources, + const BaseUIManager* ui_manager); + private: friend struct base::LazyInstanceTraitsBase< ChromeSafeBrowsingBlockingPageFactory>;
diff --git a/chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service.cc b/chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service.cc index 374f246..ce359be 100644 --- a/chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service.cc +++ b/chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service.cc
@@ -49,7 +49,7 @@ // requests. // TODO(crbug.com/1191061): Tweak this number to an "optimal" value. constexpr char kMaxParallelActiveRequests[] = "wp-max-parallel-active-requests"; -constexpr int kDefaultMaxParallelActiveRequests = 50; +constexpr int kDefaultMaxParallelActiveRequests = 5; const int kScanningTimeoutSeconds = 5 * 60; // 5 minutes
diff --git a/chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service_unittest.cc b/chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service_unittest.cc index a147c64..e1f8d42 100644 --- a/chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service_unittest.cc +++ b/chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service_unittest.cc
@@ -781,7 +781,7 @@ } TEST_F(BinaryUploadServiceTest, TestMaxParallelRequestsFlag) { - EXPECT_EQ(50UL, BinaryUploadService::GetParallelActiveRequestsMax()); + EXPECT_EQ(5UL, BinaryUploadService::GetParallelActiveRequestsMax()); { base::test::ScopedCommandLine scoped_command_line; @@ -801,21 +801,21 @@ base::test::ScopedCommandLine scoped_command_line; scoped_command_line.GetProcessCommandLine()->AppendSwitchASCII( "wp-max-parallel-active-requests", "0"); - EXPECT_EQ(50UL, BinaryUploadService::GetParallelActiveRequestsMax()); + EXPECT_EQ(5UL, BinaryUploadService::GetParallelActiveRequestsMax()); } { base::test::ScopedCommandLine scoped_command_line; scoped_command_line.GetProcessCommandLine()->AppendSwitchASCII( "wp-max-parallel-active-requests", "foo"); - EXPECT_EQ(50UL, BinaryUploadService::GetParallelActiveRequestsMax()); + EXPECT_EQ(5UL, BinaryUploadService::GetParallelActiveRequestsMax()); } { base::test::ScopedCommandLine scoped_command_line; scoped_command_line.GetProcessCommandLine()->AppendSwitchASCII( "wp-max-parallel-active-requests", "-1"); - EXPECT_EQ(50UL, BinaryUploadService::GetParallelActiveRequestsMax()); + EXPECT_EQ(5UL, BinaryUploadService::GetParallelActiveRequestsMax()); } }
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc b/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc index 28a2554..d03ff5e 100644 --- a/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc +++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc
@@ -13,9 +13,7 @@ #include "base/metrics/histogram_macros.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/history/history_service_factory.h" -#include "chrome/browser/interstitials/chrome_settings_page_helper.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/safe_browsing/chrome_controller_client.h" #include "chrome/browser/safe_browsing/chrome_safe_browsing_blocking_page_factory.h" #include "chrome/browser/safe_browsing/safe_browsing_metrics_collector_factory.h" #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h" @@ -28,7 +26,6 @@ #include "components/safe_browsing/core/common/features.h" #include "components/safe_browsing/core/common/safe_browsing_prefs.h" #include "components/safe_browsing/core/common/utils.h" -#include "components/security_interstitials/content/content_metrics_helper.h" #include "components/security_interstitials/content/security_interstitial_controller_client.h" #include "components/security_interstitials/content/settings_page_helper.h" #include "components/security_interstitials/content/unsafe_resource_util.h" @@ -86,16 +83,18 @@ WebContents* web_contents, const GURL& main_frame_url, const UnsafeResourceList& unsafe_resources, + std::unique_ptr< + security_interstitials::SecurityInterstitialControllerClient> + controller_client, const BaseSafeBrowsingErrorUI::SBErrorDisplayOptions& display_options, bool should_trigger_reporting, network::SharedURLLoaderFactory* url_loader_for_testing) - : BaseBlockingPage( - ui_manager, - web_contents, - main_frame_url, - unsafe_resources, - CreateControllerClient(web_contents, unsafe_resources, ui_manager), - display_options), + : BaseBlockingPage(ui_manager, + web_contents, + main_frame_url, + unsafe_resources, + std::move(controller_client), + display_options), threat_details_in_progress_(false), threat_source_(unsafe_resources[0].threat_source) { // Make sure the safe browsing service is available - it may not be when @@ -103,6 +102,15 @@ if (!g_browser_process->safe_browsing_service()) return; + if (unsafe_resources.size() == 1) { + UMA_HISTOGRAM_ENUMERATION( + "SafeBrowsing.BlockingPage.ResourceType", + safe_browsing::GetResourceTypeFromRequestDestination( + unsafe_resources[0].request_destination)); + UMA_HISTOGRAM_ENUMERATION("SafeBrowsing.BlockingPage.RequestDestination", + unsafe_resources[0].request_destination); + } + // Start computing threat details. Trigger Manager will decide if it's safe to // begin collecting data at this time. The report will be sent only if the // user opts-in on the blocking page later. @@ -196,46 +204,13 @@ const GURL& main_frame_url, const UnsafeResource& unsafe_resource, bool should_trigger_reporting) { - UMA_HISTOGRAM_ENUMERATION( - "SafeBrowsing.BlockingPage.ResourceType", - safe_browsing::GetResourceTypeFromRequestDestination( - unsafe_resource.request_destination)); - UMA_HISTOGRAM_ENUMERATION("SafeBrowsing.BlockingPage.RequestDestination", - unsafe_resource.request_destination); - const UnsafeResourceList resources{unsafe_resource}; // Set up the factory if this has not been done already (tests do that // before this method is called). if (!factory_) factory_ = g_chrome_safe_browsing_blocking_page_factory.Pointer(); return factory_->CreateSafeBrowsingPage(ui_manager, web_contents, - main_frame_url, resources, + main_frame_url, {unsafe_resource}, should_trigger_reporting); } -// static -std::unique_ptr<SecurityInterstitialControllerClient> -SafeBrowsingBlockingPage::CreateControllerClient( - WebContents* web_contents, - const UnsafeResourceList& unsafe_resources, - const BaseUIManager* ui_manager) { - Profile* profile = Profile::FromBrowserContext( - web_contents->GetBrowserContext()); - DCHECK(profile); - - std::unique_ptr<ContentMetricsHelper> metrics_helper = - std::make_unique<ContentMetricsHelper>( - HistoryServiceFactory::GetForProfile( - Profile::FromBrowserContext(web_contents->GetBrowserContext()), - ServiceAccessType::EXPLICIT_ACCESS), - unsafe_resources[0].url, GetReportingInfo(unsafe_resources)); - - auto chrome_settings_page_helper = - std::make_unique<security_interstitials::ChromeSettingsPageHelper>(); - - return std::make_unique<ChromeControllerClient>( - web_contents, std::move(metrics_helper), profile->GetPrefs(), - ui_manager->app_locale(), ui_manager->default_safe_page(), - std::move(chrome_settings_page_helper)); -} - } // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page.h b/chrome/browser/safe_browsing/safe_browsing_blocking_page.h index 8bb85874..0ccb8c52 100644 --- a/chrome/browser/safe_browsing/safe_browsing_blocking_page.h +++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page.h
@@ -107,6 +107,9 @@ content::WebContents* web_contents, const GURL& main_frame_url, const UnsafeResourceList& unsafe_resources, + std::unique_ptr< + security_interstitials::SecurityInterstitialControllerClient> + controller_client, const BaseSafeBrowsingErrorUI::SBErrorDisplayOptions& display_options, bool should_trigger_reporting, network::SharedURLLoaderFactory* url_loader_for_testing = nullptr); @@ -135,11 +138,6 @@ // SafeBrowsingBlockingPage. static SafeBrowsingBlockingPageFactory* factory_; private: - static std::unique_ptr< - security_interstitials::SecurityInterstitialControllerClient> - CreateControllerClient(content::WebContents* web_contents, - const UnsafeResourceList& unsafe_resources, - const BaseUIManager* ui_manager); DISALLOW_COPY_AND_ASSIGN(SafeBrowsingBlockingPage); };
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc index 722891be..69338e2 100644 --- a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc +++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
@@ -32,6 +32,7 @@ #include "chrome/browser/policy/policy_test_utils.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/renderer_context_menu/render_view_context_menu_test_util.h" +#include "chrome/browser/safe_browsing/chrome_safe_browsing_blocking_page_factory.h" #include "chrome/browser/safe_browsing/safe_browsing_blocking_page.h" #include "chrome/browser/safe_browsing/safe_browsing_blocking_page_factory.h" #include "chrome/browser/safe_browsing/test_safe_browsing_service.h" @@ -351,12 +352,17 @@ const UnsafeResourceList& unsafe_resources, const BaseSafeBrowsingErrorUI::SBErrorDisplayOptions& display_options, bool should_trigger_reporting) - : SafeBrowsingBlockingPage(manager, - web_contents, - main_frame_url, - unsafe_resources, - display_options, - should_trigger_reporting), + : SafeBrowsingBlockingPage( + manager, + web_contents, + main_frame_url, + unsafe_resources, + ChromeSafeBrowsingBlockingPageFactory::CreateControllerClient( + web_contents, + unsafe_resources, + manager), + display_options, + should_trigger_reporting), wait_for_delete_(false) { // Don't wait the whole 3 seconds for the browser test. SetThreatDetailsProceedDelayForTesting(100);
diff --git a/chrome/browser/safe_browsing/ui_manager_unittest.cc b/chrome/browser/safe_browsing/ui_manager_unittest.cc index 6dc674f..a4906fa 100644 --- a/chrome/browser/safe_browsing/ui_manager_unittest.cc +++ b/chrome/browser/safe_browsing/ui_manager_unittest.cc
@@ -10,6 +10,7 @@ #include "base/values.h" #include "chrome/browser/net/system_network_context_manager.h" #include "chrome/browser/password_manager/password_store_factory.h" +#include "chrome/browser/safe_browsing/chrome_safe_browsing_blocking_page_factory.h" #include "chrome/browser/safe_browsing/safe_browsing_blocking_page.h" #include "chrome/browser/safe_browsing/safe_browsing_blocking_page_factory.h" #include "chrome/browser/safe_browsing/test_safe_browsing_service.h" @@ -22,6 +23,7 @@ #include "components/password_manager/core/browser/password_manager_test_utils.h" #include "components/safe_browsing/core/browser/db/util.h" #include "components/safe_browsing/core/common/safe_browsing_prefs.h" +#include "components/security_interstitials/content/security_interstitial_controller_client.h" #include "components/security_interstitials/content/unsafe_resource_util.h" #include "components/security_interstitials/core/base_safe_browsing_error_ui.h" #include "components/security_interstitials/core/unsafe_resource.h" @@ -463,6 +465,10 @@ web_contents, main_frame_url, unsafe_resources, + ChromeSafeBrowsingBlockingPageFactory::CreateControllerClient( + web_contents, + unsafe_resources, + manager), BaseSafeBrowsingErrorUI::SBErrorDisplayOptions( BaseBlockingPage::IsMainPageLoadBlocked(unsafe_resources), false, // is_extended_reporting_opt_in_allowed
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProvider.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProvider.java index 1232f9c..c4af5b8 100644 --- a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProvider.java +++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProvider.java
@@ -7,6 +7,7 @@ import android.app.Activity; import android.content.ClipData; import android.content.ClipboardManager; +import android.content.ComponentName; import android.content.Context; import android.graphics.drawable.Drawable; import android.view.View; @@ -23,7 +24,6 @@ import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.preferences.Pref; import org.chromium.chrome.browser.profiles.Profile; -import org.chromium.chrome.browser.share.ChromeShareExtras; import org.chromium.chrome.browser.share.link_to_text.LinkToTextCoordinator; import org.chromium.chrome.browser.share.link_to_text.LinkToTextCoordinator.LinkGeneration; import org.chromium.chrome.browser.share.link_to_text.LinkToTextMetricsHelper; @@ -58,7 +58,11 @@ /** * Provides {@code PropertyModel}s of Chrome-provided sharing options. */ -class ChromeProvidedSharingOptionsProvider { +public class ChromeProvidedSharingOptionsProvider { + // ComponentName used for Chrome share options in ShareParams.TargetChosenCallback + public static final ComponentName CHROME_PROVIDED_FEATURE_COMPONENT_NAME = + new ComponentName("CHROME", "CHROME_FEATURE"); + private final Activity mActivity; private final Supplier<Tab> mTabProvider; private final BottomSheetController mBottomSheetController; @@ -70,11 +74,11 @@ private final long mShareStartTime; private final List<FirstPartyOption> mOrderedFirstPartyOptions; private final ChromeOptionShareCallback mChromeOptionShareCallback; - private ScreenshotCoordinator mScreenshotCoordinator; private final String mUrl; private final ImageEditorModuleProvider mImageEditorModuleProvider; private final Tracker mFeatureEngagementTracker; - private @LinkGeneration int mLinkGenerationStatusForMetrics = LinkGeneration.MAX; + private final @LinkGeneration int mLinkGenerationStatusForMetrics; + private ScreenshotCoordinator mScreenshotCoordinator; /** * Constructs a new {@link ChromeProvidedSharingOptionsProvider}. @@ -85,7 +89,6 @@ * @param bottomSheetContent The {@link ShareSheetBottomSheetContent} for the current * activity. * @param shareParams The {@link ShareParams} for the current share. - * @param chromeShareExtras The {@link ChromeShareExtras} for the current share. * @param printTab A {@link Callback} that will print a given Tab. * @param shareStartTime The start time of the current share. * @param chromeOptionShareCallback A ChromeOptionShareCallback that can be used by @@ -93,16 +96,14 @@ * @param imageEditorModuleProvider Image Editor module entry point if present in the APK. * @param featureEngagementTracker feature engagement tracker. * @param url Url to share. - * @param shareDetailsForMetrics User action of sharing text from failed link-to-text - * generation, - * sharing text from successful link-to-text generation, or sharing link-to-text. + * @param linkGenerationStatusForMetrics User action of sharing text from failed link-to-text + * generation, sharing text from successful link-to-text generation, or sharing link-to-text. */ ChromeProvidedSharingOptionsProvider(Activity activity, Supplier<Tab> tabProvider, BottomSheetController bottomSheetController, ShareSheetBottomSheetContent bottomSheetContent, ShareParams shareParams, - ChromeShareExtras chromeShareExtras, Callback<Tab> printTab, - SettingsLauncher settingsLauncher, boolean isSyncEnabled, long shareStartTime, - ChromeOptionShareCallback chromeOptionShareCallback, + Callback<Tab> printTab, SettingsLauncher settingsLauncher, boolean isSyncEnabled, + long shareStartTime, ChromeOptionShareCallback chromeOptionShareCallback, ImageEditorModuleProvider imageEditorModuleProvider, Tracker featureEngagementTracker, String url, @LinkGeneration int linkGenerationStatusForMetrics) { mActivity = activity; @@ -203,6 +204,7 @@ recordTimeToShare(mShareStartTime); mBottomSheetController.hideContent(mBottomSheetContent, true); mOnClickCallback.onResult(view); + callTargetChosenCallback(); }, /*showNewBadge*/ false); return new FirstPartyOption(model, Arrays.asList(mContentTypesInBuilder), Arrays.asList(mContentTypesToDisableFor), mDisableForMultiWindow); @@ -297,6 +299,7 @@ // observer will then remove itself. mBottomSheetController.addObserver(mSheetObserver); mBottomSheetController.hideContent(mBottomSheetContent, true); + callTargetChosenCallback(); }, showNewBadge); return new FirstPartyOption(propertyModel, @@ -319,6 +322,7 @@ // observer will then remove itself. mBottomSheetController.addObserver(mSheetObserver); mBottomSheetController.hideContent(mBottomSheetContent, true); + callTargetChosenCallback(); }, /*showNewBadge*/ false); return new FirstPartyOption(propertyModel, Arrays.asList(ContentType.LINK_PAGE_VISIBLE, ContentType.TEXT, @@ -451,6 +455,16 @@ .build(); } + private void callTargetChosenCallback() { + ShareParams.TargetChosenCallback callback = mShareParams.getCallback(); + if (callback != null) { + callback.onTargetChosen(CHROME_PROVIDED_FEATURE_COMPONENT_NAME); + // Reset callback after onTargetChosen() is called to prevent cancel() being called when + // the sheet is closed. + mShareParams.setCallback(null); + } + } + static void recordTimeToShare(long shareStartTime) { RecordHistogram.recordMediumTimesHistogram("Sharing.SharingHubAndroid.TimeToShare", System.currentTimeMillis() - shareStartTime);
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetCoordinator.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetCoordinator.java index 479dd0d..f49afbc 100644 --- a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetCoordinator.java +++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetCoordinator.java
@@ -254,8 +254,8 @@ return new ArrayList<>(); } mChromeProvidedSharingOptionsProvider = new ChromeProvidedSharingOptionsProvider(activity, - mTabProvider, mBottomSheetController, mBottomSheet, shareParams, chromeShareExtras, - mPrintTabCallback, mSettingsLauncher, mIsSyncEnabled, mShareStartTime, this, + mTabProvider, mBottomSheetController, mBottomSheet, shareParams, mPrintTabCallback, + mSettingsLauncher, mIsSyncEnabled, mShareStartTime, this, mImageEditorModuleProvider, mFeatureEngagementTracker, getUrlToShare(shareParams, chromeShareExtras, mTabProvider.get().isInitialized() ? mTabProvider.get().getUrl().getSpec() @@ -287,9 +287,9 @@ PostTask.postTask(UiThreadTaskTraits.DEFAULT, callback.bind(null)); return; } - List<PropertyModel> models = mPropertyModelBuilder.selectThirdPartyApps(mBottomSheet, - contentTypes, params, saveLastUsed, params.getWindow(), mShareStartTime, - mLinkGenerationStatusForMetrics); + List<PropertyModel> models = + mPropertyModelBuilder.selectThirdPartyApps(mBottomSheet, contentTypes, params, + saveLastUsed, mShareStartTime, mLinkGenerationStatusForMetrics); // More... PropertyModel morePropertyModel = ShareSheetPropertyModelBuilder.createPropertyModel( AppCompatResources.getDrawable(activity, R.drawable.sharing_more), @@ -308,6 +308,10 @@ profile = Profile.fromWebContents(mTabProvider.get().getWebContents()); } ShareHelper.showDefaultShareUi(params, profile, saveLastUsed); + // Reset callback to prevent cancel() being called when the custom sheet is + // closed. The callback will be called by ShareHelper on actions from the + // default share UI. + params.setCallback(null); }, /*displayNew*/ false); models.add(morePropertyModel);
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetPropertyModelBuilder.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetPropertyModelBuilder.java index b169460a..e915dec 100644 --- a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetPropertyModelBuilder.java +++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetPropertyModelBuilder.java
@@ -25,7 +25,6 @@ import org.chromium.chrome.browser.share.link_to_text.LinkToTextMetricsHelper; import org.chromium.components.browser_ui.bottomsheet.BottomSheetController; import org.chromium.components.browser_ui.share.ShareParams; -import org.chromium.ui.base.WindowAndroid; import org.chromium.ui.modelutil.PropertyModel; import java.lang.annotation.Retention; @@ -152,10 +151,8 @@ protected List<PropertyModel> selectThirdPartyApps(ShareSheetBottomSheetContent bottomSheet, Set<Integer> contentTypes, ShareParams params, boolean saveLastUsed, - WindowAndroid window, long shareStartTime, - @LinkGeneration int linkGenerationStatusForMetrics) { + long shareStartTime, @LinkGeneration int linkGenerationStatusForMetrics) { List<String> thirdPartyActivityNames = getThirdPartyActivityNames(); - final ShareParams.TargetChosenCallback callback = params.getCallback(); List<ResolveInfo> resolveInfoList = getCompatibleApps(contentTypes, params.getFileContentType()); List<ResolveInfo> thirdPartyActivities = new ArrayList<>(); @@ -190,11 +187,9 @@ for (int i = 0; i < MAX_NUM_APPS && i < thirdPartyActivities.size(); ++i) { ResolveInfo info = thirdPartyActivities.get(i); final int logIndex = i; - OnClickListener onClickListener = v -> { - onThirdPartyAppSelected(bottomSheet, params, window, callback, saveLastUsed, - info.activityInfo, logIndex, shareStartTime, - linkGenerationStatusForMetrics); - }; + OnClickListener onClickListener = v + -> onThirdPartyAppSelected(bottomSheet, params, saveLastUsed, info.activityInfo, + logIndex, shareStartTime, linkGenerationStatusForMetrics); PropertyModel propertyModel = createPropertyModel(ShareHelper.loadIconForResolveInfo(info, mPackageManager), (String) info.loadLabel(mPackageManager), onClickListener, @@ -206,9 +201,8 @@ } private void onThirdPartyAppSelected(ShareSheetBottomSheetContent bottomSheet, - ShareParams params, WindowAndroid window, ShareParams.TargetChosenCallback callback, - boolean saveLastUsed, ActivityInfo ai, int logIndex, long shareStartTime, - @LinkGeneration int linkGenerationStatusForMetrics) { + ShareParams params, boolean saveLastUsed, ActivityInfo ai, int logIndex, + long shareStartTime, @LinkGeneration int linkGenerationStatusForMetrics) { // Record all metrics. RecordUserAction.record("SharingHubAndroid.ThirdPartyAppSelected"); RecordHistogram.recordEnumeratedHistogram( @@ -219,8 +213,12 @@ linkGenerationStatusForMetrics); } ComponentName component = new ComponentName(ai.applicationInfo.packageName, ai.name); + ShareParams.TargetChosenCallback callback = params.getCallback(); if (callback != null) { callback.onTargetChosen(component); + // Reset callback after onTargetChosen() is called to prevent cancel() being called when + // the sheet is closed. + params.setCallback(null); } if (saveLastUsed) { ShareHelper.setLastShareComponentName(mProfile, component);
diff --git a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProviderTest.java b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProviderTest.java index 5b1fe71..3032fe0b 100644 --- a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProviderTest.java +++ b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProviderTest.java
@@ -40,7 +40,6 @@ import org.chromium.chrome.browser.feature_engagement.TrackerFactory; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.profiles.Profile; -import org.chromium.chrome.browser.share.ChromeShareExtras; import org.chromium.chrome.browser.share.link_to_text.LinkToTextCoordinator.LinkGeneration; import org.chromium.chrome.browser.share.share_sheet.ShareSheetPropertyModelBuilder.ContentType; import org.chromium.chrome.browser.tab.Tab; @@ -78,36 +77,31 @@ @Rule public JniMocker mJniMocker = new JniMocker(); + private static final String URL = "http://www.google.com/"; + @Mock private UserPrefs.Natives mUserPrefsNatives; - @Mock private Profile mProfile; @Mock private PrefService mPrefService; - - private static final String URL = "http://www.google.com/"; - @Mock private ShareSheetCoordinator mShareSheetCoordinator; + @Mock + private Supplier<Tab> mTabProvider; + @Mock + private Tab mTab; + @Mock + private BottomSheetController mBottomSheetController; + @Mock + private WebContents mWebContents; + @Mock + private Tracker mTracker; + @Mock + private ShareParams.TargetChosenCallback mTargetChosenCallback; private Activity mActivity; private ChromeProvidedSharingOptionsProvider mChromeProvidedSharingOptionsProvider; - - @Mock - private Supplier<Tab> mTabProvider; - - @Mock - private Tab mTab; - - @Mock - private BottomSheetController mBottomSheetController; - - @Mock - private WebContents mWebContents; - - @Mock - private Tracker mTracker; private UserActionTester mActionTester; @Before @@ -346,7 +340,6 @@ @LinkGeneration int linkGenerationStatus = LinkGeneration.LINK; - String detailMetrics = "LinkGeneration.DetailsMetrics"; setUpChromeProvidedSharingOptionsProviderTest( /*printingEnabled=*/false, linkGenerationStatus); List<PropertyModel> propertyModels = @@ -356,17 +349,36 @@ assertCorrectMetrics(propertyModels, linkGenerationStatus); } + @Test + @MediumTest + public void getPropertyModels_onClick_callsOnTargetChosen() { + setUpChromeProvidedSharingOptionsProviderTest( + /*printingEnabled=*/false, LinkGeneration.LINK); + + List<PropertyModel> propertyModels = + mChromeProvidedSharingOptionsProvider.getPropertyModels( + ImmutableSet.of(ContentType.LINK_PAGE_VISIBLE), /*isMultiWindow=*/false); + View.OnClickListener onClickListener = + propertyModels.get(0).get(ShareSheetItemViewProperties.CLICK_LISTENER); + + onClickListener.onClick(null); + Mockito.verify(mTargetChosenCallback, Mockito.times(1)) + .onTargetChosen(ChromeProvidedSharingOptionsProvider + .CHROME_PROVIDED_FEATURE_COMPONENT_NAME); + } + private void setUpChromeProvidedSharingOptionsProviderTest( boolean printingEnabled, @LinkGeneration int linkGenerationStatus) { Mockito.when(mPrefService.getBoolean(anyString())).thenReturn(printingEnabled); - ShareParams shareParams = new ShareParams.Builder(null, /*title=*/"", /*url=*/"").build(); + ShareParams shareParams = new ShareParams.Builder(null, /*title=*/"", /*url=*/"") + .setCallback(mTargetChosenCallback) + .build(); mChromeProvidedSharingOptionsProvider = new ChromeProvidedSharingOptionsProvider(mActivity, mTabProvider, mBottomSheetController, new ShareSheetBottomSheetContent( mActivity, null, mShareSheetCoordinator, shareParams), - new ShareParams.Builder(null, "", "").build(), - new ChromeShareExtras.Builder().build(), + shareParams, /*TabPrinterDelegate=*/null, /*settingsLauncher=*/null, /*syncState=*/false,
diff --git a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetCoordinatorTest.java b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetCoordinatorTest.java index 02e5d78..b008c49 100644 --- a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetCoordinatorTest.java +++ b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetCoordinatorTest.java
@@ -5,16 +5,20 @@ package org.chromium.chrome.browser.share.share_sheet; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anySet; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Matchers.any; import static org.mockito.Mockito.when; import android.app.Activity; +import android.view.View; -import androidx.test.filters.MediumTest; +import androidx.test.filters.SmallTest; import org.junit.Before; import org.junit.Rule; @@ -23,21 +27,26 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.robolectric.Robolectric; -import org.chromium.base.test.BaseActivityTestRule; +import org.chromium.base.supplier.Supplier; +import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.base.test.util.CallbackHelper; -import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.JniMocker; import org.chromium.chrome.R; -import org.chromium.chrome.browser.flags.ChromeSwitches; +import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher; -import org.chromium.chrome.test.ChromeBrowserTestRule; -import org.chromium.chrome.test.ChromeJUnit4ClassRunner; +import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.test.util.browser.Features; import org.chromium.components.browser_ui.bottomsheet.BottomSheetController; import org.chromium.components.browser_ui.share.ShareParams; +import org.chromium.components.dom_distiller.core.DomDistillerUrlUtils; +import org.chromium.components.dom_distiller.core.DomDistillerUrlUtilsJni; +import org.chromium.ui.base.WindowAndroid; import org.chromium.ui.modelutil.PropertyModel; -import org.chromium.ui.test.util.DummyUiActivity; +import org.chromium.url.JUnitTestGURLs; +import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -47,40 +56,41 @@ /** * Tests {@link ShareSheetCoordinator}. */ -@RunWith(ChromeJUnit4ClassRunner.class) -@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) +@RunWith(BaseRobolectricTestRunner.class) +@Features.EnableFeatures({ChromeFeatureList.PREEMPTIVE_LINK_TO_TEXT_GENERATION}) public final class ShareSheetCoordinatorTest { - @Rule - public final ChromeBrowserTestRule mBrowserTestRule = new ChromeBrowserTestRule(); - - @Rule - public BaseActivityTestRule<DummyUiActivity> mActivityTestRule = - new BaseActivityTestRule<>(DummyUiActivity.class); + private static final String MOCK_URL = JUnitTestGURLs.EXAMPLE_URL; @Rule public TestRule mFeatureProcessor = new Features.JUnitProcessor(); + @Rule + public JniMocker mJniMocker = new JniMocker(); @Mock + private DomDistillerUrlUtils.Natives mDistillerUrlUtilsJniMock; + @Mock private ActivityLifecycleDispatcher mLifecycleDispatcher; - @Mock private BottomSheetController mController; - @Mock private ShareSheetPropertyModelBuilder mPropertyModelBuilder; - @Mock - private ShareParams mParams; + private ShareParams.TargetChosenCallback mTargetChosenCallback; + @Mock + private Supplier<Tab> mTabProvider; + @Mock + private WindowAndroid mWindow; private Activity mActivity; + private ShareParams mParams; private ShareSheetCoordinator mShareSheetCoordinator; @Before public void setUp() { - mActivityTestRule.launchActivity(null); - mActivity = mActivityTestRule.getActivity(); - MockitoAnnotations.initMocks(this); + mJniMocker.mock(DomDistillerUrlUtilsJni.TEST_HOOKS, mDistillerUrlUtilsJniMock); + + mActivity = Robolectric.setupActivity(Activity.class); PropertyModel testModel1 = new PropertyModel.Builder(ShareSheetItemViewProperties.ALL_KEYS) .with(ShareSheetItemViewProperties.ICON, null) .with(ShareSheetItemViewProperties.LABEL, "testModel1") @@ -94,16 +104,22 @@ ArrayList<PropertyModel> thirdPartyPropertyModels = new ArrayList<>(Arrays.asList(testModel1, testModel2)); + when(mWindow.getActivity()).thenReturn(new WeakReference<>(mActivity)); when(mPropertyModelBuilder.selectThirdPartyApps( - any(), anySet(), any(), anyBoolean(), any(), anyLong(), anyInt())) + any(), anySet(), any(), anyBoolean(), anyLong(), anyInt())) .thenReturn(thirdPartyPropertyModels); + when(mDistillerUrlUtilsJniMock.getOriginalUrlFromDistillerUrl(anyString())) + .thenReturn(JUnitTestGURLs.getGURL(MOCK_URL)); - mShareSheetCoordinator = new ShareSheetCoordinator(mController, mLifecycleDispatcher, null, - mPropertyModelBuilder, null, null, null, false, null, null); + mParams = new ShareParams.Builder(mWindow, "title", MOCK_URL) + .setCallback(mTargetChosenCallback) + .build(); + mShareSheetCoordinator = new ShareSheetCoordinator(mController, mLifecycleDispatcher, + mTabProvider, mPropertyModelBuilder, null, null, null, false, null, null); } @Test - @MediumTest + @SmallTest public void disableFirstPartyFeatures() { mShareSheetCoordinator.disableFirstPartyFeaturesForTesting(); @@ -114,10 +130,9 @@ } @Test - @MediumTest + @SmallTest public void testCreateThirdPartyPropertyModels() throws TimeoutException { - final AtomicReference<List<PropertyModel>> resultPropertyModels = - new AtomicReference<List<PropertyModel>>(); + final AtomicReference<List<PropertyModel>> resultPropertyModels = new AtomicReference<>(); CallbackHelper helper = new CallbackHelper(); mShareSheetCoordinator.createThirdPartyPropertyModels(mActivity, mParams, ShareSheetPropertyModelBuilder.ALL_CONTENT_TYPES_FOR_TEST, @@ -137,4 +152,26 @@ mActivity.getResources().getString(R.string.sharing_more_icon_label), propertyModels.get(2).get(ShareSheetItemViewProperties.LABEL)); } + + @Test + @SmallTest + public void testClickMoreRemovesCallback() throws TimeoutException { + final AtomicReference<List<PropertyModel>> resultPropertyModels = new AtomicReference<>(); + CallbackHelper helper = new CallbackHelper(); + mShareSheetCoordinator.createThirdPartyPropertyModels(mActivity, mParams, + ShareSheetPropertyModelBuilder.ALL_CONTENT_TYPES_FOR_TEST, + /*saveLastUsed=*/false, models -> { + resultPropertyModels.set(models); + helper.notifyCalled(); + }); + helper.waitForFirst(); + List<PropertyModel> propertyModels = resultPropertyModels.get(); + + View.OnClickListener onClickListener = + propertyModels.get(2).get(ShareSheetItemViewProperties.CLICK_LISTENER); + + assertNotNull("Callback should not be null before pressing More", mParams.getCallback()); + onClickListener.onClick(null); + assertNull("Callback should be null after pressing More", mParams.getCallback()); + } }
diff --git a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetPropertyModelBuilderTest.java b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetPropertyModelBuilderTest.java index f95dfbe..6ba5b6b 100644 --- a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetPropertyModelBuilderTest.java +++ b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetPropertyModelBuilderTest.java
@@ -280,8 +280,7 @@ List<PropertyModel> propertyModels = mPropertyModelBuilder.selectThirdPartyApps(null, ImmutableSet.of(ContentType.LINK_PAGE_VISIBLE), shareParams, /*saveLastUsed=*/false, - /*WindowAndroid=*/null, /*shareStartTime=*/0, - /*linkGenerationStatusForMetrics=*/LinkGeneration.MAX); + /*shareStartTime=*/0, /*linkGenerationStatusForMetrics=*/LinkGeneration.MAX); assertEquals("Incorrect number of property models.", 2, propertyModels.size()); assertModelsAreInTheRightOrder( @@ -296,8 +295,7 @@ List<PropertyModel> propertyModels = mPropertyModelBuilder.selectThirdPartyApps(null, ImmutableSet.of(ContentType.IMAGE), shareParams, /*saveLastUsed=*/false, - /*WindowAndroid=*/null, /*shareStartTime=*/0, - /*linkGenerationStatusForMetrics=*/LinkGeneration.MAX); + /*shareStartTime=*/0, /*linkGenerationStatusForMetrics=*/LinkGeneration.MAX); assertEquals("Incorrect number of property models.", 2, propertyModels.size()); assertModelsAreInTheRightOrder( @@ -312,7 +310,7 @@ List<PropertyModel> propertyModels = mPropertyModelBuilder.selectThirdPartyApps(null, ImmutableSet.of(ContentType.LINK_PAGE_VISIBLE, ContentType.IMAGE), shareParams, - /*saveLastUsed=*/false, /*WindowAndroid=*/null, /*shareStartTime=*/0, + /*saveLastUsed=*/false, /*shareStartTime=*/0, /*linkGenerationStatusForMetrics=*/LinkGeneration.MAX); assertEquals("Incorrect number of property models.", 4, propertyModels.size());
diff --git a/chrome/browser/share/android/test_java_sources.gni b/chrome/browser/share/android/test_java_sources.gni index 425204ef..33b670b 100644 --- a/chrome/browser/share/android/test_java_sources.gni +++ b/chrome/browser/share/android/test_java_sources.gni
@@ -13,7 +13,6 @@ "//chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/send_tab_to_self/SendTabToSelfCoordinatorTest.java", "//chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProviderTest.java", "//chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetBottomSheetContentTest.java", - "//chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetCoordinatorTest.java", "//chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetPropertyModelBuilderTest.java", ] @@ -28,6 +27,7 @@ "//chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/screenshot/ScreenshotShareSheetMediatorUnitTest.java", "//chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/send_tab_to_self/NotificationSharedPrefManagerTest.java", "//chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/send_tab_to_self/SendTabToSelfAndroidBridgeTest.java", + "//chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetCoordinatorTest.java", ] share_junit_test_java_deps = [
diff --git a/chrome/browser/sync/test/integration/single_client_sync_invalidations_test.cc b/chrome/browser/sync/test/integration/single_client_sync_invalidations_test.cc index 2afcae7c..c1c9d90 100644 --- a/chrome/browser/sync/test/integration/single_client_sync_invalidations_test.cc +++ b/chrome/browser/sync/test/integration/single_client_sync_invalidations_test.cc
@@ -3,6 +3,8 @@ // found in the LICENSE file. #include "base/test/scoped_feature_list.h" +#include "base/time/time.h" +#include "base/time/time_override.h" #include "build/chromeos_buildflags.h" #include "chrome/browser/sync/sync_invalidations_service_factory.h" #include "chrome/browser/sync/test/integration/bookmarks_helper.h" @@ -38,6 +40,12 @@ const char kSyncedBookmarkURL[] = "http://www.mybookmark.com"; +MATCHER(HasBeenRecentlyUpdated, "") { + return syncer::ProtoTimeToTime( + arg.specifics().device_info().last_updated_timestamp()) > + base::Time::Now() - base::TimeDelta::FromMinutes(10); +} + MATCHER_P(HasCacheGuid, expected_cache_guid, "") { return arg.specifics().device_info().cache_guid() == expected_cache_guid; } @@ -88,6 +96,51 @@ .instance_id_token() == expected_token; } +// This class helps to count the number of GU_TRIGGER events for the |type| +// since the object has been created. +class GetUpdatesTriggeredObserver : public fake_server::FakeServer::Observer { + public: + GetUpdatesTriggeredObserver(fake_server::FakeServer* fake_server, + syncer::ModelType type) + : fake_server_(fake_server), type_(type) { + fake_server_->AddObserver(this); + } + + ~GetUpdatesTriggeredObserver() override { + fake_server_->RemoveObserver(this); + } + + void OnSuccessfulGetUpdates() override { + sync_pb::ClientToServerMessage message; + fake_server_->GetLastGetUpdatesMessage(&message); + + if (message.get_updates().get_updates_origin() != + sync_pb::SyncEnums::GU_TRIGGER) { + return; + } + for (const sync_pb::DataTypeProgressMarker& progress_marker : + message.get_updates().from_progress_marker()) { + if (progress_marker.data_type_id() != + syncer::GetSpecificsFieldNumberFromModelType(type_)) { + continue; + } + if (progress_marker.get_update_triggers().datatype_refresh_nudges() > 0) { + num_nudged_get_updates_for_data_type_++; + } + } + } + + size_t num_nudged_get_updates_for_data_type() const { + return num_nudged_get_updates_for_data_type_; + } + + private: + fake_server::FakeServer* const fake_server_; + const syncer::ModelType type_; + + size_t num_nudged_get_updates_for_data_type_ = 0; +}; + sync_pb::DeviceInfoSpecifics CreateDeviceInfoSpecifics( const std::string& cache_guid, const std::string& fcm_registration_token) { @@ -246,6 +299,65 @@ ElementsAre(kRemoteFCMRegistrationToken)); } +IN_PROC_BROWSER_TEST_F(SingleClientWithUseSyncInvalidationsTest, + PRE_ShouldNotSendAdditionalGetUpdates) { + base::subtle::ScopedTimeClockOverrides time_clock_overrides( + []() { + const base::TimeDelta time_delta = base::TimeDelta::FromDays(2); + return base::subtle::TimeNowIgnoringOverride() - time_delta; + }, + nullptr, nullptr); + + ASSERT_TRUE(SetupSync()); +} + +IN_PROC_BROWSER_TEST_F(SingleClientWithUseSyncInvalidationsTest, + ShouldNotSendAdditionalGetUpdates) { + // Verify that DeviceInfo has been updated long time ago. + ASSERT_THAT(fake_server_->GetSyncEntitiesByModelType(syncer::DEVICE_INFO), + ElementsAre(testing::Not(HasBeenRecentlyUpdated()))); + + GetUpdatesTriggeredObserver observer(GetFakeServer(), + syncer::ModelType::AUTOFILL); + ASSERT_TRUE(SetupClients()); + ASSERT_TRUE(GetClient(0)->AwaitEngineInitialization()); + ASSERT_TRUE(GetClient(0)->AwaitSyncSetupCompletion()); + + // Wait until DeviceInfo is updated. + ASSERT_TRUE(ServerDeviceInfoMatchChecker( + GetFakeServer(), ElementsAre(HasBeenRecentlyUpdated())) + .Wait()); + + // Perform an additional sync cycle to be sure that there will be at least one + // more GetUpdates request if it was triggered. + const std::string kTitle1 = "Title 1"; + AddFolder(0, GetBookmarkBarNode(0), 0, kTitle1); + ASSERT_TRUE(ServerBookmarksEqualityChecker(GetSyncService(0), GetFakeServer(), + {{kTitle1, GURL()}}, + /*cryptographer=*/nullptr) + .Wait()); + + const std::string kTitle2 = "Title 2"; + AddFolder(0, GetBookmarkBarNode(0), 0, kTitle2); + ASSERT_TRUE( + ServerBookmarksEqualityChecker(GetSyncService(0), GetFakeServer(), + {{kTitle1, GURL()}, {kTitle2, GURL()}}, + /*cryptographer=*/nullptr) + .Wait()); + + // There will be one TriggerRefresh request in tests due to + // ConfigurationRefresher. There shouldn't be any additional GU_TRIGGER + // with nudge DeviceInfo data type. +#if BUILDFLAG(IS_CHROMEOS_ASH) + // On ChromeOS tests data types are configured twice and hence there are two + // expected TriggerRefresh calls during initialization. It happens due to + // SyncArcPackageHelper which eventually triggers reconfiguration. + EXPECT_EQ(2u, observer.num_nudged_get_updates_for_data_type()); +#else + EXPECT_EQ(1u, observer.num_nudged_get_updates_for_data_type()); +#endif +} + class SingleClientWithUseSyncInvalidationsForWalletAndOfferTest : public SyncTest { public:
diff --git a/chrome/browser/tabmodel/BUILD.gn b/chrome/browser/tabmodel/BUILD.gn index fefa085..a956cf4 100644 --- a/chrome/browser/tabmodel/BUILD.gn +++ b/chrome/browser/tabmodel/BUILD.gn
@@ -16,6 +16,7 @@ "android/java/src/org/chromium/chrome/browser/tabmodel/IncognitoStateProvider.java", "android/java/src/org/chromium/chrome/browser/tabmodel/IncognitoTabHost.java", "android/java/src/org/chromium/chrome/browser/tabmodel/IncognitoTabHostRegistry.java", + "android/java/src/org/chromium/chrome/browser/tabmodel/IncognitoTabHostUtils.java", "android/java/src/org/chromium/chrome/browser/tabmodel/IncognitoTabModel.java", "android/java/src/org/chromium/chrome/browser/tabmodel/IncognitoTabModelImpl.java", "android/java/src/org/chromium/chrome/browser/tabmodel/IncognitoTabModelObserver.java",
diff --git a/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/IncognitoTabHostUtils.java b/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/IncognitoTabHostUtils.java new file mode 100644 index 0000000..8b03486c --- /dev/null +++ b/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/IncognitoTabHostUtils.java
@@ -0,0 +1,43 @@ +// 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. + +package org.chromium.chrome.browser.tabmodel; + +/** + * Utilities concerning all incognito tabs in all {@link IncognitoTabHost}s. + */ +public class IncognitoTabHostUtils { + /** + * Determine whether there are any incognito tabs. + */ + public static boolean doIncognitoTabsExist() { + for (IncognitoTabHost host : IncognitoTabHostRegistry.getInstance().getHosts()) { + if (host.hasIncognitoTabs()) { + return true; + } + } + return false; + } + + /** + * Determine whether the incognito tab model is active. + */ + public static boolean isIncognitoTabModelActive() { + for (IncognitoTabHost host : IncognitoTabHostRegistry.getInstance().getHosts()) { + if (host.isActiveModel()) { + return true; + } + } + return false; + } + + /** + * Closes all incognito tabs. + */ + public static void closeAllIncognitoTabs() { + for (IncognitoTabHost host : IncognitoTabHostRegistry.getInstance().getHosts()) { + host.closeAllIncognitoTabs(); + } + } +}
diff --git a/chrome/browser/translate/translate_manager_browsertest.cc b/chrome/browser/translate/translate_manager_browsertest.cc index fddf235..6db512d 100644 --- a/chrome/browser/translate/translate_manager_browsertest.cc +++ b/chrome/browser/translate/translate_manager_browsertest.cc
@@ -2073,9 +2073,8 @@ } // Test that iframes can be translated. -// TODO(https://crbug.com/1106446) disabled due to flakiness IN_PROC_BROWSER_TEST_F(TranslateManagerWithSubFrameSupportBrowserTest, - DISABLED_TranslateIframe) { + TranslateIframe) { base::HistogramTester histograms; SetTranslateScript(kTestValidScript);
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd index 71d5252d..2850876f 100644 --- a/chrome/browser/ui/android/strings/android_chrome_strings.grd +++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
@@ -443,7 +443,7 @@ <message name="IDS_AUTOFILL_PROFILE_EDITOR_COUNTRY" desc="Label for a spinner input field containing a list of countries or regions [CHAR_LIMIT=32]"> Country/Region </message> - <message name="IDS_AUTOFILL_PROFILE_EDITOR_HONORIFIC_PREFIX" desc="Label for text input field containing a title that can be auto-filled by Chrome. [CHAR_LIMIT=32]" meaning="A 'Title' field in a web form could be a prefix like Ms., Mx., or Dr. or a position held, like Captain or Rabbi."> + <message name="IDS_AUTOFILL_PROFILE_EDITOR_HONORIFIC_PREFIX" desc="Label for text input field containing a title that can be auto-filled by Chrome. A 'Title' field in a web form could be a prefix like Ms., Mx., or Dr. or a position held, like Captain or Rabbi. [CHAR_LIMIT=32]" meaning="Honorific"> Title </message> <message name="IDS_AUTOFILL_PROFILE_EDITOR_EMAIL_ADDRESS" desc="Label for text input field containing an e-mail address. [CHAR_LIMIT=32]">
diff --git a/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc b/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc index dc4ad773..7db1b58 100644 --- a/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc +++ b/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc
@@ -351,17 +351,9 @@ ASSERT_FALSE(IsWindowFullscreenForTabOrPending()); } -// Disabled due to flakiness. -// TODO(crbug.com/976883): Fix and re-enable this. // Tests mouse lock and fullscreen modes can be escaped with ESC key. -#if defined(OS_WIN) -#define MAYBE_EscapingMouseLockAndFullscreen EscapingMouseLockAndFullscreen -#else -#define MAYBE_EscapingMouseLockAndFullscreen \ - DISABLED_EscapingMouseLockAndFullscreen -#endif IN_PROC_BROWSER_TEST_F(FullscreenControllerInteractiveTest, - MAYBE_EscapingMouseLockAndFullscreen) { + EscapingMouseLockAndFullscreen) { auto test_server_handle = embedded_test_server()->StartAndReturnHandle(); ASSERT_TRUE(test_server_handle); ui_test_utils::NavigateToURL( @@ -492,21 +484,15 @@ ASSERT_TRUE(IsMouseLocked()); } +// Tests mouse lock is exited on page navigation. #if (defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)) && defined(USE_AURA) -// These are flaky on linux_aura. -// http://crbug.com/163931 +// https://crbug.com/1191964 #define MAYBE_TestTabExitsMouseLockOnNavigation \ DISABLED_TestTabExitsMouseLockOnNavigation -#define MAYBE_TestTabExitsMouseLockOnGoBack \ - DISABLED_TestTabExitsMouseLockOnGoBack #else #define MAYBE_TestTabExitsMouseLockOnNavigation \ TestTabExitsMouseLockOnNavigation -#define MAYBE_TestTabExitsMouseLockOnGoBack \ - TestTabExitsMouseLockOnGoBack #endif - -// Tests mouse lock is exited on page navigation. IN_PROC_BROWSER_TEST_F(FullscreenControllerInteractiveTest, MAYBE_TestTabExitsMouseLockOnNavigation) { auto test_server_handle = embedded_test_server()->StartAndReturnHandle(); @@ -526,6 +512,13 @@ } // Tests mouse lock is exited when navigating back. +#if (defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)) && defined(USE_AURA) +// https://crbug.com/1192097 +#define MAYBE_TestTabExitsMouseLockOnGoBack \ + DISABLED_TestTabExitsMouseLockOnGoBack +#else +#define MAYBE_TestTabExitsMouseLockOnGoBack TestTabExitsMouseLockOnGoBack +#endif IN_PROC_BROWSER_TEST_F(FullscreenControllerInteractiveTest, MAYBE_TestTabExitsMouseLockOnGoBack) { auto test_server_handle = embedded_test_server()->StartAndReturnHandle(); @@ -584,17 +577,8 @@ } // Tests Mouse Lock and Fullscreen are exited upon reload. -// http://crbug.com/137486 -// mac: http://crbug.com/103912 -#if defined(OS_WIN) -#define MAYBE_ReloadExitsMouseLockAndFullscreen \ - ReloadExitsMouseLockAndFullscreen -#else -#define MAYBE_ReloadExitsMouseLockAndFullscreen \ - DISABLED_ReloadExitsMouseLockAndFullscreen -#endif IN_PROC_BROWSER_TEST_F(FullscreenControllerInteractiveTest, - MAYBE_ReloadExitsMouseLockAndFullscreen) { + ReloadExitsMouseLockAndFullscreen) { auto test_server_handle = embedded_test_server()->StartAndReturnHandle(); ASSERT_TRUE(test_server_handle); ui_test_utils::NavigateToURL(
diff --git a/chrome/browser/ui/passwords/bubble_controllers/save_update_with_account_store_bubble_controller.cc b/chrome/browser/ui/passwords/bubble_controllers/save_update_with_account_store_bubble_controller.cc index 5403cea..cfceaa8a 100644 --- a/chrome/browser/ui/passwords/bubble_controllers/save_update_with_account_store_bubble_controller.cc +++ b/chrome/browser/ui/passwords/bubble_controllers/save_update_with_account_store_bubble_controller.cc
@@ -20,7 +20,7 @@ #include "components/password_manager/core/browser/password_form_metrics_recorder.h" #include "components/password_manager/core/browser/password_manager_features_util.h" #include "components/password_manager/core/browser/password_manager_metrics_util.h" -#include "components/password_manager/core/browser/password_store.h" +#include "components/password_manager/core/browser/password_store_interface.h" #include "components/password_manager/core/common/password_manager_features.h" #include "components/password_manager/core/common/password_manager_pref_names.h" #include "components/prefs/pref_service.h" @@ -65,11 +65,14 @@ void CleanStatisticsForSite(Profile* profile, const url::Origin& origin) { DCHECK(profile); - password_manager::PasswordStore* password_store = + password_manager::PasswordStoreInterface* password_store = PasswordStoreFactory::GetForProfile(profile, ServiceAccessType::IMPLICIT_ACCESS) .get(); - password_store->RemoveSiteStats(origin.GetURL()); + password_manager::SmartBubbleStatsStore* stats_store = + password_store->GetSmartBubbleStatsStore(); + if (stats_store) + stats_store->RemoveSiteStats(origin.GetURL()); } std::vector<password_manager::PasswordForm> DeepCopyForms( @@ -328,11 +331,14 @@ interaction_stats_.dismissal_count)>::max()) interaction_stats_.dismissal_count++; interaction_stats_.update_time = clock_->Now(); - password_manager::PasswordStore* password_store = + password_manager::PasswordStoreInterface* password_store = PasswordStoreFactory::GetForProfile( profile, ServiceAccessType::IMPLICIT_ACCESS) .get(); - password_store->AddSiteStats(interaction_stats_); + password_manager::SmartBubbleStatsStore* stats_store = + password_store->GetSmartBubbleStatsStore(); + if (stats_store) + stats_store->AddSiteStats(interaction_stats_); } } }
diff --git a/chrome/browser/ui/views/dropdown_bar_host.cc b/chrome/browser/ui/views/dropdown_bar_host.cc index 862d979d..4559046 100644 --- a/chrome/browser/ui/views/dropdown_bar_host.cc +++ b/chrome/browser/ui/views/dropdown_bar_host.cc
@@ -133,6 +133,7 @@ void DropdownBarHost::Hide(bool animate) { if (!IsVisible()) return; + if (animate && !disable_animations_during_testing_ && !animation_->IsClosing()) { animation_->Hide(); @@ -201,6 +202,11 @@ } void DropdownBarHost::AnimationEnded(const gfx::Animation* animation) { + // Ensure the position gets a final update. This is important when ending the + // animation early (e.g. closing a tab with an open find bar), since otherwise + // the position will be out of date at the start of the next animation. + AnimationProgressed(animation); + if (!animation_->IsShowing()) { // Animation has finished closing. host_->Hide();
diff --git a/chrome/browser/ui/views/profiles/profile_menu_view.cc b/chrome/browser/ui/views/profiles/profile_menu_view.cc index 6d8b13da..258d95c 100644 --- a/chrome/browser/ui/views/profiles/profile_menu_view.cc +++ b/chrome/browser/ui/views/profiles/profile_menu_view.cc
@@ -180,30 +180,21 @@ if (profile->IsOffTheRecord() || profile->IsGuestSession()) return gfx::ImageSkia(); - absl::optional<AvatarSyncErrorType> error = GetAvatarSyncErrorType(profile); bool is_sync_feature_enabled = IdentityManagerFactory::GetForProfile(profile)->HasPrimaryAccount( signin::ConsentLevel::kSync); - if (!error) { - // There's no error, so just show the sync on/off icon depending on whether - // sync-the-feature is enabled. - if (is_sync_feature_enabled) { - return ColoredImageForMenu( - kSyncCircleIcon, GetNativeTheme()->GetSystemColor( - ui::NativeTheme::kColorId_AlertSeverityLow)); - } + if (!is_sync_feature_enabled) { + // This is done regardless of GetAvatarSyncErrorType() because the icon + // should reflect that sync-the-feature is off. The error will still be + // highlighted by other parts of the UI. return ColoredImageForMenu(kSyncPausedCircleIcon, gfx::kGoogleGrey500); } - // There's an error. Usually a red sync-paused icon will be used, but some - // errors have special icons. - if ((error == AvatarSyncErrorType::kTrustedVaultKeyMissingForPasswordsError || - error == AvatarSyncErrorType:: - kTrustedVaultRecoverabilityDegradedForPasswordsError) && - !is_sync_feature_enabled) { - return ColoredImageForMenu( - kKeyCrossedIcon, GetNativeTheme()->GetSystemColor( - ui::NativeTheme::kColorId_AlertSeverityHigh)); + absl::optional<AvatarSyncErrorType> error = GetAvatarSyncErrorType(profile); + if (!error) { + return ColoredImageForMenu( + kSyncCircleIcon, GetNativeTheme()->GetSystemColor( + ui::NativeTheme::kColorId_AlertSeverityLow)); } ui::NativeTheme::ColorId color_id = @@ -530,7 +521,7 @@ : ui::NativeTheme::kColorId_SyncInfoContainerError, base::BindRepeating(&ProfileMenuView::OnSyncErrorButtonClicked, base::Unretained(this), *error), - /*show_badge=*/true); + /*show_sync_badge=*/is_sync_feature_enabled); return; } @@ -556,7 +547,7 @@ ui::NativeTheme::kColorId_SyncInfoContainerNoPrimaryAccount, base::BindRepeating(&ProfileMenuView::OnSigninAccountButtonClicked, base::Unretained(this), account_info), - /*show_badge=*/true); + /*show_sync_badge=*/true); } else { #if BUILDFLAG(IS_CHROMEOS_ASH) // There is always an account on ChromeOS. @@ -568,7 +559,7 @@ ui::NativeTheme::kColorId_SyncInfoContainerNoPrimaryAccount, base::BindRepeating(&ProfileMenuView::OnSigninButtonClicked, base::Unretained(this)), - /*show_badge=*/false); + /*show_sync_badge=*/false); #endif } }
diff --git a/chrome/browser/ui/views/profiles/profile_menu_view_base.cc b/chrome/browser/ui/views/profiles/profile_menu_view_base.cc index a2a02176..99fe8401 100644 --- a/chrome/browser/ui/views/profiles/profile_menu_view_base.cc +++ b/chrome/browser/ui/views/profiles/profile_menu_view_base.cc
@@ -649,7 +649,7 @@ const std::u16string& button_text, ui::NativeTheme::ColorId background_color_id, const base::RepeatingClosure& action, - bool show_badge) { + bool show_sync_badge) { const int kDescriptionIconSpacing = ChromeLayoutProvider::Get()->GetDistanceMetric( views::DISTANCE_RELATED_LABEL_HORIZONTAL); @@ -687,7 +687,7 @@ .SetDefault(views::kMarginsKey, gfx::Insets(0, kDescriptionIconSpacing)); - if (show_badge) { + if (show_sync_badge) { description_container->AddChildView(std::make_unique<SyncImageView>(this)); } else { // If there is no image, the description is centered.
diff --git a/chrome/browser/ui/views/profiles/profile_menu_view_base.h b/chrome/browser/ui/views/profiles/profile_menu_view_base.h index cdb5579..55380425 100644 --- a/chrome/browser/ui/views/profiles/profile_menu_view_base.h +++ b/chrome/browser/ui/views/profiles/profile_menu_view_base.h
@@ -126,7 +126,7 @@ const std::u16string& button_text, ui::NativeTheme::ColorId background_color_id, const base::RepeatingClosure& action, - bool show_badge); + bool show_sync_badge); // Displays the sync info section as a rectangle with text. Clicking the // rectangle triggers |action|. void BuildSyncInfoWithoutCallToAction(const std::u16string& text,
diff --git a/chrome/browser/ui/webui/chromeos/login/arc_terms_of_service_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/arc_terms_of_service_screen_handler.cc index cd4763a9..7682e7e 100644 --- a/chrome/browser/ui/webui/chromeos/login/arc_terms_of_service_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/arc_terms_of_service_screen_handler.cc
@@ -114,8 +114,12 @@ void ArcTermsOfServiceScreenHandler::DeclareLocalizedValues( ::login::LocalizedValuesBuilder* builder) { builder->Add("arcTermsOfServiceScreenHeading", IDS_ARC_OOBE_TERMS_HEADING); + builder->Add("arcTermsOfServiceScreenHeadingForChild", + IDS_ARC_OOBE_TERMS_HEADING_CHILD); builder->Add("arcTermsOfServiceScreenDescription", IDS_ARC_OOBE_TERMS_DESCRIPTION); + builder->Add("arcTermsOfServiceScreenDescriptionForChild", + IDS_ARC_OOBE_TERMS_DESCRIPTION_CHILD); builder->Add("arcTermsOfServiceLoading", IDS_ARC_OOBE_TERMS_LOADING); builder->Add("arcTermsOfServiceErrorTitle", IDS_OOBE_GENERIC_FATAL_ERROR_TITLE); builder->Add("arcTermsOfServiceErrorMessage", IDS_ARC_OOBE_TERMS_LOAD_ERROR); @@ -338,8 +342,8 @@ action_taken_ = false; ShowScreen(kScreenId); - arc_managed_ = arc::IsArcPlayStoreEnabledPreferenceManagedForProfile(profile); + is_child_account_ = user_manager::UserManager::Get()->IsLoggedInAsChildUser(); CallJS("login.ArcTermsOfServiceScreen.setArcManaged", arc_managed_, is_child_account_);
diff --git a/chrome/browser/ui/webui/inspect_ui.cc b/chrome/browser/ui/webui/inspect_ui.cc index c971958..e0de6f1 100644 --- a/chrome/browser/ui/webui/inspect_ui.cc +++ b/chrome/browser/ui/webui/inspect_ui.cc
@@ -682,32 +682,30 @@ Profile* profile = Profile::FromWebUI(web_ui()); PrefService* prefs = profile->GetPrefs(); - bool default_set; - if (!GetPrefValue(prefs::kDevToolsPortForwardingDefaultSet)-> - GetAsBoolean(&default_set) || default_set) { + auto default_set = + GetPrefValue(prefs::kDevToolsPortForwardingDefaultSet)->GetIfBool(); + if (!default_set || default_set.value()) return; - } // This is the first chrome://inspect invocation on a fresh profile or after // upgrade from a version that did not have kDevToolsPortForwardingDefaultSet. prefs->SetBoolean(prefs::kDevToolsPortForwardingDefaultSet, true); - bool enabled; + auto enabled = + GetPrefValue(prefs::kDevToolsPortForwardingEnabled)->GetIfBool(); const base::DictionaryValue* config; - if (!GetPrefValue(prefs::kDevToolsPortForwardingEnabled)-> - GetAsBoolean(&enabled) || - !GetPrefValue(prefs::kDevToolsPortForwardingConfig)-> - GetAsDictionary(&config)) { + if (!enabled || !GetPrefValue(prefs::kDevToolsPortForwardingConfig) + ->GetAsDictionary(&config)) { return; } // Do nothing if user already took explicit action. - if (enabled || !config->DictEmpty()) + if (enabled.value() || !config->DictEmpty()) return; base::DictionaryValue default_config; - default_config.SetString(kInspectUiPortForwardingDefaultPort, - kInspectUiPortForwardingDefaultLocation); + default_config.SetStringPath(kInspectUiPortForwardingDefaultPort, + kInspectUiPortForwardingDefaultLocation); prefs->Set(prefs::kDevToolsPortForwardingConfig, default_config); }
diff --git a/chrome/browser/ui/webui/signin/profile_picker_handler.cc b/chrome/browser/ui/webui/signin/profile_picker_handler.cc index c80651527..d7c5343 100644 --- a/chrome/browser/ui/webui/signin/profile_picker_handler.cc +++ b/chrome/browser/ui/webui/signin/profile_picker_handler.cc
@@ -12,6 +12,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/util/values/values_util.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_attributes_entry.h" #include "chrome/browser/profiles/profile_attributes_storage.h" #include "chrome/browser/profiles/profile_avatar_icon_util.h" @@ -171,22 +172,6 @@ } } -#if BUILDFLAG(IS_CHROMEOS_LACROS) -Profile* FindPrimaryProfile() { - const auto profiles = - g_browser_process->profile_manager()->GetLoadedProfiles(); - const auto primary_profile_iter = std::find_if( - profiles.cbegin(), profiles.cend(), - [](const Profile* const profile) { return profile->IsMainProfile(); }); - - if (primary_profile_iter == profiles.cend()) { - return nullptr; - } - - return *primary_profile_iter; -} -#endif // BUILDFLAG(IS_CHROMEOS_LACROS) - base::Value CreateProfileEntry(const ProfileAttributesEntry* entry, int avatar_icon_size) { base::Value profile_entry(base::Value::Type::DICTIONARY); @@ -208,10 +193,8 @@ std::string icon_url = webui::GetBitmapDataUrl(icon.AsBitmap()); profile_entry.SetStringKey("avatarIcon", icon_url); #if BUILDFLAG(IS_CHROMEOS_LACROS) - Profile* primary_profile = FindPrimaryProfile(); - profile_entry.SetBoolKey( - "isPrimaryLacrosProfile", - primary_profile && primary_profile->GetPath() == entry->GetPath()); + profile_entry.SetBoolKey("isPrimaryLacrosProfile", + Profile::IsMainProfilePath(entry->GetPath())); #else profile_entry.SetBoolKey("isPrimaryLacrosProfile", false); #endif // BUILDFLAG(IS_CHROMEOS_LACROS) @@ -390,8 +373,7 @@ #if BUILDFLAG(IS_CHROMEOS_LACROS) if (!profiles::AreSecondaryProfilesAllowed()) { - Profile* primary_profile = FindPrimaryProfile(); - if (primary_profile && primary_profile->GetPath() != *profile_path) { + if (Profile::IsMainProfilePath(*profile_path)) { LoginUIServiceFactory::GetForProfile( Profile::FromWebUI(web_ui())->GetOriginalProfile()) ->SetProfileBlockingErrorMessage(); @@ -661,8 +643,7 @@ #if BUILDFLAG(IS_CHROMEOS_LACROS) // On Lacros, the primary profile should never be deleted. - Profile* primary_profile = FindPrimaryProfile(); - CHECK(!primary_profile || primary_profile->GetPath() != *profile_path); + CHECK(!Profile::IsMainProfilePath(*profile_path)); #endif // BUILDFLAG(IS_CHROMEOS_LACROS) RecordProfilePickerAction(ProfilePickerAction::kDeleteProfile);
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index b8d1a9e5..ba9ebea0 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc
@@ -3221,10 +3221,10 @@ "net.explicitly_allowed_network_ports"; #if !defined(OS_ANDROID) -// Pref name for whether force-installed web apps are able to query +// Pref name for whether force-installed web apps (origins) are able to query // device attributes. -const char kManagedWebAppsAccessToDeviceAttributesAllowed[] = - "policy.managed_web_apps_access_to_device_attributes_allowed"; +const char kDeviceAttributesAllowedForOrigins[] = + "policy.device_attributes_allowed_for_origins"; #endif #if !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index 16f9027..813799a 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h
@@ -1148,7 +1148,7 @@ extern const char kExplicitlyAllowedNetworkPorts[]; #if !defined(OS_ANDROID) -extern const char kManagedWebAppsAccessToDeviceAttributesAllowed[]; +extern const char kDeviceAttributesAllowedForOrigins[]; #endif #if !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 49299a5a..1498a29b 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -4461,8 +4461,6 @@ "../browser/profiles/incognito_mode_policy_handler_unittest.cc", "../browser/profiles/profile_attributes_storage_unittest.cc", "../browser/profiles/profile_downloader_unittest.cc", - "../browser/profiles/profile_info_cache_unittest.cc", - "../browser/profiles/profile_info_cache_unittest.h", "../browser/profiles/profile_manager_unittest.cc", "../browser/profiles/profiles_state_unittest.cc", "../browser/profiling_host/chrome_client_connection_manager_unittest.cc",
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/batch/BlankCTATabInitialStateRule.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/batch/BlankCTATabInitialStateRule.java index 87ea585..c9e4d1f1 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/batch/BlankCTATabInitialStateRule.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/batch/BlankCTATabInitialStateRule.java
@@ -11,9 +11,9 @@ import org.chromium.base.test.util.Batch; import org.chromium.chrome.browser.ChromeTabbedActivity; import org.chromium.chrome.browser.firstrun.FirstRunStatus; -import org.chromium.chrome.browser.incognito.IncognitoUtils; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabLaunchType; +import org.chromium.chrome.browser.tabmodel.IncognitoTabHostUtils; import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.browser.tabmodel.TabModelUtils; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; @@ -95,7 +95,7 @@ // quickly, at the cost of thoroughness. This should be adequate for most tests. private void resetTabStateFast() { TestThreadUtils.runOnUiThreadBlocking(() -> { - IncognitoUtils.closeAllIncognitoTabs(); + IncognitoTabHostUtils.closeAllIncognitoTabs(); // Close all but the first regular tab as these tests expect to start with a single // tab. TabModel regularTabModel = @@ -117,7 +117,7 @@ // tabs are closed. Tab newTab = sActivity.getTabCreator(false).launchUrl( "about:blank", TabLaunchType.FROM_CHROME_UI); - IncognitoUtils.closeAllIncognitoTabs(); + IncognitoTabHostUtils.closeAllIncognitoTabs(); TabModel regularTabModel = sActivity.getTabModelSelector().getModel(/*incognito=*/false);
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/signin/AccountManagerTestRule.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/signin/AccountManagerTestRule.java index 8018d591..b60c787 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/signin/AccountManagerTestRule.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/signin/AccountManagerTestRule.java
@@ -106,12 +106,18 @@ } /** - * Add an account to the fake AccountManagerFacade. + * Add an account to the fake AccountManagerFacade, if the {@link FakeAccountInfoService} is + * set up, add the corresponding {@link AccountInfo} to the {@link FakeAccountInfoService}. * @return The CoreAccountInfo for the account added. */ public CoreAccountInfo addAccount(Account account) { - mFakeAccountManagerFacade.addAccount(account); - return toCoreAccountInfo(account.name); + if (mFakeAccountInfoService != null) { + return addAccount( + account.name, /* fullName= */ "", /* givenName= */ "", /* avatar= */ null); + } else { + mFakeAccountManagerFacade.addAccount(account); + return toCoreAccountInfo(account.name); + } } /** @@ -141,7 +147,9 @@ String email, String fullName, String givenName, @Nullable Bitmap avatar) { assert mFakeAccountManagerFacade != null; mFakeAccountInfoService.addAccountInfo(email, fullName, givenName, avatar); - return addAccount(email); + final Account account = AccountUtils.createAccountFromName(email); + mFakeAccountManagerFacade.addAccount(account); + return toCoreAccountInfo(email); } /**
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json index c2aa0e63..b6a542bb 100644 --- a/chrome/test/data/policy/policy_test_cases.json +++ b/chrome/test/data/policy/policy_test_cases.json
@@ -4818,12 +4818,12 @@ ] }, - "ManagedWebAppsAccessToDeviceAttributesAllowed": { + "DeviceAttributesAllowedForOrigins": { "os": ["chromeos"], "policy_pref_mapping_tests": [ { - "policies": { "ManagedWebAppsAccessToDeviceAttributesAllowed": true }, - "prefs": { "policy.managed_web_apps_access_to_device_attributes_allowed": {} } + "policies": { "DeviceAttributesAllowedForOrigins": ["https://www.google.com"] }, + "prefs": { "policy.device_attributes_allowed_for_origins": {"value" : ["https://www.google.com"] } } } ] },
diff --git a/chrome/test/data/webui/settings/chromeos/app_notifications_subpage_tests.js b/chrome/test/data/webui/settings/chromeos/app_notifications_subpage_tests.js index ba7c770f..2a89b2f 100644 --- a/chrome/test/data/webui/settings/chromeos/app_notifications_subpage_tests.js +++ b/chrome/test/data/webui/settings/chromeos/app_notifications_subpage_tests.js
@@ -21,9 +21,12 @@ flush(); }); - test('Page is loaded properly', function() { + test('Each app-notification-row displays correctly', function() { assertTrue(!!page); flush(); - assertEquals('Notifications', page.$.testDiv.textContent.trim()); + assertEquals( + 'Chrome', + page.$.appNotificationsList.firstElementChild.$.appTitle.textContent + .trim()); }); }); \ No newline at end of file
diff --git a/chromecast/base/cast_features.cc b/chromecast/base/cast_features.cc index 49382b4..da7d8c5c 100644 --- a/chromecast/base/cast_features.cc +++ b/chromecast/base/cast_features.cc
@@ -213,7 +213,7 @@ all_disable_features); // Override defaults from the DCS config. - for (const auto& kv : dcs_features.DictItems()) { + for (const auto kv : dcs_features.DictItems()) { // Each feature must have its own FieldTrial object. Since experiments are // controlled server-side for Chromecast, and this class is designed with a // client-side experimentation framework in mind, these parameters are @@ -259,7 +259,7 @@ // Build a map of the FieldTrial parameters and associate it to the // FieldTrial. base::FieldTrialParams params; - for (const auto& params_kv : kv.second.DictItems()) { + for (const auto params_kv : kv.second.DictItems()) { if (params_kv.second.is_string()) { params[params_kv.first] = params_kv.second.GetString(); } else { @@ -293,7 +293,7 @@ base::Value persistent_dict(base::Value::Type::DICTIONARY); // |features| maps feature names to either a boolean or a dict of params. - for (const auto& feature : features.DictItems()) { + for (const auto feature : features.DictItems()) { if (feature.second.is_bool()) { persistent_dict.SetBoolKey(feature.first, feature.second.GetBool()); continue;
diff --git a/chromecast/base/device_capabilities_impl.cc b/chromecast/base/device_capabilities_impl.cc index 4aa23c7f..b1852f76 100644 --- a/chromecast/base/device_capabilities_impl.cc +++ b/chromecast/base/device_capabilities_impl.cc
@@ -280,7 +280,7 @@ void DeviceCapabilitiesImpl::MergeDictionary(const base::Value& dict_value) { DCHECK(dict_value.is_dict()); - for (const auto& kv : dict_value.DictItems()) { + for (const auto kv : dict_value.DictItems()) { SetCapability(kv.first, kv.second.Clone()); } }
diff --git a/chromecast/common/cast_redirect_manifest_handler.cc b/chromecast/common/cast_redirect_manifest_handler.cc index 3525a3f..26698f7 100644 --- a/chromecast/common/cast_redirect_manifest_handler.cc +++ b/chromecast/common/cast_redirect_manifest_handler.cc
@@ -33,7 +33,7 @@ std::unique_ptr<Data> info(new Data); const base::DictionaryValue* dict; if (extension->manifest()->GetDictionary(kCastRedirect, &dict)) { - for (const auto& kv : dict->DictItems()) { + for (const auto kv : dict->DictItems()) { std::string path; if (kv.second.GetAsString(&path)) { info->redirects.emplace_back(kv.first, path);
diff --git a/chromecast/media/cma/backend/mixer/filter_group.cc b/chromecast/media/cma/backend/mixer/filter_group.cc index 09c5f5be..b2931b861 100644 --- a/chromecast/media/cma/backend/mixer/filter_group.cc +++ b/chromecast/media/cma/backend/mixer/filter_group.cc
@@ -131,7 +131,7 @@ } float min, max; - for (const auto& item : volume_limits->DictItems()) { + for (const auto item : volume_limits->DictItems()) { if (ParseVolumeLimit(&item.second, &min, &max)) { AUDIO_LOG(INFO) << "Volume limits for device ID '" << item.first << "' = [" << min << ", " << max << "]";
diff --git a/chromeos/components/sync_wifi/pending_network_configuration_tracker_impl.cc b/chromeos/components/sync_wifi/pending_network_configuration_tracker_impl.cc index d64e253..93f2879 100644 --- a/chromeos/components/sync_wifi/pending_network_configuration_tracker_impl.cc +++ b/chromeos/components/sync_wifi/pending_network_configuration_tracker_impl.cc
@@ -119,7 +119,7 @@ std::vector<PendingNetworkConfigurationUpdate> PendingNetworkConfigurationTrackerImpl::GetPendingUpdates() { std::vector<PendingNetworkConfigurationUpdate> list; - for (const auto& entry : dict_.DictItems()) { + for (const auto entry : dict_.DictItems()) { list.push_back(ConvertToPendingUpdate( /*dict=*/&entry.second, NetworkIdentifier::DeserializeFromString(entry.first)));
diff --git a/chromeos/dbus/dbus_clients_browser.h b/chromeos/dbus/dbus_clients_browser.h index e98902b..e9c5a2e 100644 --- a/chromeos/dbus/dbus_clients_browser.h +++ b/chromeos/dbus/dbus_clients_browser.h
@@ -38,8 +38,10 @@ class VirtualFileProviderClient; class VmPluginDispatcherClient; -// D-Bus clients used only in the browser process. -// TODO(jamescook): Move this under //chrome/browser. http://crbug.com/647367 +// Owns D-Bus clients. +// TODO(jamescook): Rename this class. "Browser" refers to the browser process +// versus ash process distinction from the mustash project, which was cancelled +// in 2019. class COMPONENT_EXPORT(CHROMEOS_DBUS) DBusClientsBrowser { public: // Creates real implementations if |use_real_clients| is true and fakes
diff --git a/chromeos/dbus/dbus_thread_manager.cc b/chromeos/dbus/dbus_thread_manager.cc index 8a44019..11133d9 100644 --- a/chromeos/dbus/dbus_thread_manager.cc +++ b/chromeos/dbus/dbus_thread_manager.cc
@@ -44,11 +44,9 @@ static DBusThreadManager* g_dbus_thread_manager = nullptr; static DBusThreadManagerSetter* g_setter = nullptr; -DBusThreadManager::DBusThreadManager(ClientSet client_set) { - if (client_set == DBusThreadManager::kAll) - clients_browser_ = std::make_unique<DBusClientsBrowser>(use_real_clients_); - // NOTE: When there are clients only used by ash, create them here. -} +DBusThreadManager::DBusThreadManager() + : clients_browser_( + std::make_unique<DBusClientsBrowser>(use_real_clients_)) {} DBusThreadManager::~DBusThreadManager() { // Delete all D-Bus clients before shutting down the system bus. @@ -210,15 +208,10 @@ } // static -void DBusThreadManager::Initialize(ClientSet client_set) { - CHECK(!g_dbus_thread_manager); - g_dbus_thread_manager = new DBusThreadManager(client_set); - g_dbus_thread_manager->InitializeClients(); -} - -// static void DBusThreadManager::Initialize() { - Initialize(kAll); + CHECK(!g_dbus_thread_manager); + g_dbus_thread_manager = new DBusThreadManager(); + g_dbus_thread_manager->InitializeClients(); } // static
diff --git a/chromeos/dbus/dbus_thread_manager.h b/chromeos/dbus/dbus_thread_manager.h index cda37e9..28da8e0 100644 --- a/chromeos/dbus/dbus_thread_manager.h +++ b/chromeos/dbus/dbus_thread_manager.h
@@ -54,26 +54,11 @@ class COMPONENT_EXPORT(CHROMEOS_DBUS) DBusThreadManager : public DBusThreadManagerBase { public: - // Processes for which to create and initialize the D-Bus clients. - // TODO(jamescook): Move creation of clients into //ash and //chrome/browser. - // http://crbug.com/647367 - enum ClientSet { - // Common clients needed by both ash and the browser. - kShared, - - // Includes the client in |kShared| as well as the clients used only by - // the browser (and not ash). - kAll - }; // Sets the global instance. Must be called before any calls to Get(). // We explicitly initialize and shut down the global object, rather than // making it a Singleton, to ensure clean startup and shutdown. // This will initialize real or fake DBusClients depending on command-line // arguments and whether this process runs in a ChromeOS environment. - // Only D-Bus clients specified in |client_set| will be created. - static void Initialize(ClientSet client_set); - - // Equivalent to Initialize(kAll). static void Initialize(); // Returns a DBusThreadManagerSetter instance that allows tests to replace @@ -131,8 +116,7 @@ ShillThirdPartyVpnDriverClient* GetShillThirdPartyVpnDriverClient(); private: - // Creates dbus clients based on |client_set|. - explicit DBusThreadManager(ClientSet client_set); + DBusThreadManager(); DBusThreadManager(const DBusThreadManager&) = delete; const DBusThreadManager& operator=(const DBusThreadManager&) = delete; ~DBusThreadManager() override; @@ -141,7 +125,7 @@ // performs additional setup. void InitializeClients(); - // Clients used only by the browser process. Null in other processes. + // Owns the clients. std::unique_ptr<DBusClientsBrowser> clients_browser_; };
diff --git a/chromeos/dbus/dbus_thread_manager_unittest.cc b/chromeos/dbus/dbus_thread_manager_unittest.cc index 01ba809..12f30cf 100644 --- a/chromeos/dbus/dbus_thread_manager_unittest.cc +++ b/chromeos/dbus/dbus_thread_manager_unittest.cc
@@ -42,64 +42,4 @@ EXPECT_FALSE(DBusThreadManager::IsInitialized()); } -// Tests that clients can be created for the browser process. -TEST(DBusThreadManagerTest, InitializeForBrowser) { - DBusThreadManager::Initialize(DBusThreadManager::kAll); - DBusThreadManager* manager = DBusThreadManager::Get(); - ASSERT_TRUE(manager); - - // Common clients were created. - EXPECT_TRUE(manager->GetModemMessagingClient()); - EXPECT_TRUE(manager->GetShillDeviceClient()); - EXPECT_TRUE(manager->GetShillIPConfigClient()); - EXPECT_TRUE(manager->GetShillManagerClient()); - EXPECT_TRUE(manager->GetShillProfileClient()); - EXPECT_TRUE(manager->GetShillServiceClient()); - EXPECT_TRUE(manager->GetShillThirdPartyVpnDriverClient()); - EXPECT_TRUE(manager->GetSMSClient()); - EXPECT_TRUE(manager->GetUpdateEngineClient()); - - // Clients for the browser were created. - EXPECT_TRUE(manager->GetAnomalyDetectorClient()); - EXPECT_TRUE(manager->GetArcMidisClient()); - EXPECT_TRUE(manager->GetArcObbMounterClient()); - EXPECT_TRUE(manager->GetCrosDisksClient()); - EXPECT_TRUE(manager->GetDebugDaemonClient()); - EXPECT_TRUE(manager->GetEasyUnlockClient()); - EXPECT_TRUE(manager->GetImageBurnerClient()); - EXPECT_TRUE(manager->GetLorgnetteManagerClient()); - - DBusThreadManager::Shutdown(); -} - -// Tests that clients can be created for the ash process. -TEST(DBusThreadManagerTest, InitializeForAsh) { - DBusThreadManager::Initialize(DBusThreadManager::kShared); - DBusThreadManager* manager = DBusThreadManager::Get(); - ASSERT_TRUE(manager); - - // Common clients were created. - EXPECT_TRUE(manager->GetModemMessagingClient()); - EXPECT_TRUE(manager->GetShillDeviceClient()); - EXPECT_TRUE(manager->GetShillIPConfigClient()); - EXPECT_TRUE(manager->GetShillManagerClient()); - EXPECT_TRUE(manager->GetShillProfileClient()); - EXPECT_TRUE(manager->GetShillServiceClient()); - EXPECT_TRUE(manager->GetShillThirdPartyVpnDriverClient()); - EXPECT_TRUE(manager->GetSMSClient()); - - // Clients for other processes were not created. - EXPECT_FALSE(manager->GetAnomalyDetectorClient()); - EXPECT_FALSE(manager->GetArcMidisClient()); - EXPECT_FALSE(manager->GetArcObbMounterClient()); - EXPECT_FALSE(manager->GetCrosDisksClient()); - EXPECT_FALSE(manager->GetDebugDaemonClient()); - EXPECT_FALSE(manager->GetEasyUnlockClient()); - EXPECT_FALSE(manager->GetImageBurnerClient()); - EXPECT_FALSE(manager->GetLorgnetteManagerClient()); - EXPECT_FALSE(manager->GetUpdateEngineClient()); - - DBusThreadManager::Shutdown(); -} - } // namespace chromeos
diff --git a/chromeos/dbus/debug_daemon/debug_daemon_client.cc b/chromeos/dbus/debug_daemon/debug_daemon_client.cc index d56f7522..f97448e 100644 --- a/chromeos/dbus/debug_daemon/debug_daemon_client.cc +++ b/chromeos/dbus/debug_daemon/debug_daemon_client.cc
@@ -88,7 +88,7 @@ } std::map<std::string, std::string> data; - for (const auto& entry : logs->DictItems()) + for (const auto entry : logs->DictItems()) data[entry.first] = entry.second.GetString(); RunCallbackAndDestroy(std::move(data)); }
diff --git a/chromeos/dbus/shill/fake_shill_profile_client.cc b/chromeos/dbus/shill/fake_shill_profile_client.cc index 2597ece..5e329f88 100644 --- a/chromeos/dbus/shill/fake_shill_profile_client.cc +++ b/chromeos/dbus/shill/fake_shill_profile_client.cc
@@ -56,7 +56,7 @@ } base::Value entry_paths(base::Value::Type::LIST); - for (const auto& it : profile->entries.DictItems()) { + for (const auto it : profile->entries.DictItems()) { entry_paths.Append(it.first); }
diff --git a/chromeos/dbus/shill/fake_shill_service_client.cc b/chromeos/dbus/shill/fake_shill_service_client.cc index f4f77371..4788ed5 100644 --- a/chromeos/dbus/shill/fake_shill_service_client.cc +++ b/chromeos/dbus/shill/fake_shill_service_client.cc
@@ -613,7 +613,7 @@ std::string FakeShillServiceClient::FindServiceMatchingGUID( const std::string& guid) { - for (const auto& service_pair : stub_services_.DictItems()) { + for (const auto service_pair : stub_services_.DictItems()) { const auto& service_path = service_pair.first; const auto& service_properties = service_pair.second; @@ -633,7 +633,7 @@ if (!template_type) return std::string(); - for (const auto& service_pair : stub_services_.DictItems()) { + for (const auto service_pair : stub_services_.DictItems()) { const auto& service_path = service_pair.first; const auto& service_properties = service_pair.second;
diff --git a/chromeos/metrics/login_event_recorder.h b/chromeos/metrics/login_event_recorder.h index 81a91f6..625eeff9 100644 --- a/chromeos/metrics/login_event_recorder.h +++ b/chromeos/metrics/login_event_recorder.h
@@ -10,6 +10,7 @@ #include "base/callback.h" #include "base/component_export.h" #include "base/memory/ref_counted.h" +#include "base/time/time.h" #include "third_party/abseil-cpp/absl/types/optional.h" namespace base {
diff --git a/chromeos/network/network_configuration_handler.cc b/chromeos/network/network_configuration_handler.cc index a02dec7d..3af9cb07 100644 --- a/chromeos/network/network_configuration_handler.cc +++ b/chromeos/network/network_configuration_handler.cc
@@ -142,7 +142,7 @@ return; } - for (const auto& iter : profile_entries->DictItems()) { + for (const auto iter : profile_entries->DictItems()) { std::string profile_path = StripQuotations(iter.first); std::string entry_path; if (iter.second.is_string()) {
diff --git a/chromeos/network/onc/onc_translator_onc_to_shill.cc b/chromeos/network/onc/onc_translator_onc_to_shill.cc index db8ed30..b79c83a 100644 --- a/chromeos/network/onc/onc_translator_onc_to_shill.cc +++ b/chromeos/network/onc/onc_translator_onc_to_shill.cc
@@ -231,7 +231,7 @@ // Modified CopyFieldsAccordingToSignature to handle RemoteCertKU and // ServerCAPEMs and handle all other fields as strings. - for (const auto& it : onc_object_->DictItems()) { + for (const auto it : onc_object_->DictItems()) { std::string key = it.first; base::Value translated; if (key == ::onc::openvpn::kRemoteCertKU || @@ -448,7 +448,7 @@ } void LocalTranslator::CopyFieldsAccordingToSignature() { - for (const auto& it : onc_object_->DictItems()) { + for (const auto it : onc_object_->DictItems()) { AddValueAccordingToSignature(it.first, it.second); } } @@ -529,7 +529,7 @@ translator.TranslateFields(); // Recurse into nested objects. - for (const auto& it : onc_object.DictItems()) { + for (const auto it : onc_object.DictItems()) { if (!it.second.is_dict()) continue;
diff --git a/chromeos/network/onc/variable_expander.cc b/chromeos/network/onc/variable_expander.cc index 63d7ea3..0e8ee1e 100644 --- a/chromeos/network/onc/variable_expander.cc +++ b/chromeos/network/onc/variable_expander.cc
@@ -128,7 +128,7 @@ } case base::Value::Type::DICTIONARY: { - for (const auto& child : value->DictItems()) + for (const auto child : value->DictItems()) no_error &= ExpandValue(&child.second); break; }
diff --git a/chromeos/network/shill_property_handler.cc b/chromeos/network/shill_property_handler.cc index 918298ac..843b456 100644 --- a/chromeos/network/shill_property_handler.cc +++ b/chromeos/network/shill_property_handler.cc
@@ -345,7 +345,7 @@ return; } NET_LOG(EVENT) << "ManagerPropertiesCallback: Success"; - for (const auto& item : properties->DictItems()) { + for (const auto item : properties->DictItems()) { ManagerPropertyChanged(item.first, item.second); }
diff --git a/chromeos/printing/ppd_metadata_parser.cc b/chromeos/printing/ppd_metadata_parser.cc index aab9504..2846d64 100644 --- a/chromeos/printing/ppd_metadata_parser.cc +++ b/chromeos/printing/ppd_metadata_parser.cc
@@ -210,7 +210,7 @@ return absl::nullopt; } ParsedManufacturers manufacturers; - for (const auto& iter : as_value.value().DictItems()) { + for (const auto iter : as_value.value().DictItems()) { std::string printers_metadata_basename; if (!iter.second.GetAsString(&printers_metadata_basename)) { continue; @@ -236,7 +236,7 @@ // Secondly, we iterate on the key-value pairs of the ppdIndex. // This yields a list of leaf values (dictionaries). - for (const auto& kv : ppd_index->DictItems()) { + for (const auto kv : ppd_index->DictItems()) { absl::optional<ParsedIndexValues> values = UnnestPpdMetadata(kv.second); if (values.has_value()) { parsed_index.insert_or_assign(kv.first, values.value()); @@ -257,7 +257,7 @@ } ParsedUsbIndex parsed_usb_index; - for (const auto& kv : usb_index->DictItems()) { + for (const auto kv : usb_index->DictItems()) { int product_id; if (!base::StringToInt(kv.first, &product_id)) { continue; @@ -341,7 +341,7 @@ } ParsedReverseIndex parsed; - for (const auto& kv : makes_and_models->DictItems()) { + for (const auto kv : makes_and_models->DictItems()) { if (!kv.second.is_dict()) { continue; }
diff --git a/chromeos/services/device_sync/cryptauth_device.cc b/chromeos/services/device_sync/cryptauth_device.cc index 3acc245..33c51c7 100644 --- a/chromeos/services/device_sync/cryptauth_device.cc +++ b/chromeos/services/device_sync/cryptauth_device.cc
@@ -37,7 +37,7 @@ std::map<multidevice::SoftwareFeature, multidevice::SoftwareFeatureState> feature_states; - for (const auto& feature_state_pair : dict->DictItems()) { + for (const auto feature_state_pair : dict->DictItems()) { int feature; if (!base::StringToInt(feature_state_pair.first, &feature) || !feature_state_pair.second.is_int()) {
diff --git a/chromeos/services/device_sync/cryptauth_device_manager_impl.cc b/chromeos/services/device_sync/cryptauth_device_manager_impl.cc index 0b4a32c..1239b09c 100644 --- a/chromeos/services/device_sync/cryptauth_device_manager_impl.cc +++ b/chromeos/services/device_sync/cryptauth_device_manager_impl.cc
@@ -348,7 +348,7 @@ cryptauth::ExternalDeviceInfo* external_device, bool old_unlock_key_value_from_prefs, bool old_mobile_hotspot_supported_from_prefs) { - for (const auto& it : software_features_dictionary.DictItems()) { + for (const auto it : software_features_dictionary.DictItems()) { std::string software_feature = it.first; if (SoftwareFeatureStringToEnum(software_feature) == cryptauth::SoftwareFeature::UNKNOWN_FEATURE) {
diff --git a/chromeos/services/device_sync/cryptauth_device_manager_impl_unittest.cc b/chromeos/services/device_sync/cryptauth_device_manager_impl_unittest.cc index 96d3a811..3bdb9d1 100644 --- a/chromeos/services/device_sync/cryptauth_device_manager_impl_unittest.cc +++ b/chromeos/services/device_sync/cryptauth_device_manager_impl_unittest.cc
@@ -341,7 +341,7 @@ std::vector<cryptauth::SoftwareFeature> supported_software_features; std::vector<cryptauth::SoftwareFeature> enabled_software_features; - for (const auto& it : software_features_from_prefs->DictItems()) { + for (const auto it : software_features_from_prefs->DictItems()) { ASSERT_TRUE(it.second.is_int()); cryptauth::SoftwareFeature software_feature =
diff --git a/chromeos/services/device_sync/cryptauth_device_registry_impl.cc b/chromeos/services/device_sync/cryptauth_device_registry_impl.cc index 6a3c81a..a1c4b2315 100644 --- a/chromeos/services/device_sync/cryptauth_device_registry_impl.cc +++ b/chromeos/services/device_sync/cryptauth_device_registry_impl.cc
@@ -52,8 +52,7 @@ const base::Value* dict = pref_service_->Get(prefs::kCryptAuthDeviceRegistry); CryptAuthDeviceRegistry::InstanceIdToDeviceMap instance_id_to_device_map; - for (const std::pair<const std::string&, const base::Value&>& id_device_pair : - dict->DictItems()) { + for (const auto id_device_pair : dict->DictItems()) { absl::optional<std::string> instance_id = util::DecodeFromString(id_device_pair.first); absl::optional<CryptAuthDevice> device =
diff --git a/components/autofill/ios/browser/suggestion_controller_java_script_feature.mm b/components/autofill/ios/browser/suggestion_controller_java_script_feature.mm index eadf5e4..eae6c553 100644 --- a/components/autofill/ios/browser/suggestion_controller_java_script_feature.mm +++ b/components/autofill/ios/browser/suggestion_controller_java_script_feature.mm
@@ -8,6 +8,7 @@ #include "base/bind.h" #include "base/strings/sys_string_conversions.h" +#include "base/time/time.h" #include "base/values.h" #import "components/autofill/ios/browser/autofill_java_script_feature.h"
diff --git a/components/autofill_assistant/browser/dom_action.proto b/components/autofill_assistant/browser/dom_action.proto index 6520f36..120accf 100644 --- a/components/autofill_assistant/browser/dom_action.proto +++ b/components/autofill_assistant/browser/dom_action.proto
@@ -158,7 +158,7 @@ // combination with |SendChangeEventProto|. If the element in |option| is // not an option of the element in |select|, an |OPTION_VALUE_NOT_FOUND| error // is returned. If the element in |select| is not an HTML <select> element, an -// |OPTION_VALUE_NOT_FOUND| error is returned. +// |INVALID_TARGET| error is returned. message SelectOptionElementProto { optional ClientIdProto select_id = 1; optional ClientIdProto option_id = 2; @@ -172,7 +172,7 @@ repeated string any_of_tag = 2; } -// Check whether the element in |option_d| is selected in the element in +// Check whether the element in |option_id| is selected in the element in // |select_id|. message CheckOptionElementProto { optional ClientIdProto select_id = 1;
diff --git a/components/autofill_assistant/browser/service.proto b/components/autofill_assistant/browser/service.proto index ebbaf25..7252b97 100644 --- a/components/autofill_assistant/browser/service.proto +++ b/components/autofill_assistant/browser/service.proto
@@ -1396,8 +1396,8 @@ // Contain all arguments to perform a select option action. This action also // fires a "change" event on the element. If the option is not found, an // |OPTION_VALUE_NOT_FOUND| error is returned. If the action is used on an -// element that is not an HTML <select> element, an |OPTION_VALUE_NOT_FOUND| -// error is returned. +// element that is not an HTML <select> element, an |INVALID_TARGET| error is +// returned. message SelectOptionProto { // The drop down element on which to select an option. optional SelectorProto element = 2;
diff --git a/components/browser_ui/styles/android/java/res/values-night/styles.xml b/components/browser_ui/styles/android/java/res/values-night/styles.xml index cd3d8a6..9f6b8314c 100644 --- a/components/browser_ui/styles/android/java/res/values-night/styles.xml +++ b/components/browser_ui/styles/android/java/res/values-night/styles.xml
@@ -6,25 +6,27 @@ <resources xmlns:tools="http://schemas.android.com/tools"> <style name="Base.ColorOverlay" parent=""> <!-- Attributes that point to the same color/attr in dark and light modes. --> + <item name="colorOnPrimaryContainer">@color/baseline_primary_900</item> <item name="colorPrimaryContainer">@color/baseline_primary_100</item> <item name="android:textColorPrimary">?attr/colorOnBackground</item> <item name="android:textColorSecondary">?attr/colorOnSurfaceVariant</item> <!-- Adaptive attributes --> - <item name="colorPrimary">@color/modern_blue_300</item> - <item name="colorError">@color/google_red_300</item> - <item name="android:colorBackground">@color/modern_grey_900</item> - <item name="colorSurface">@color/modern_grey_900</item> - <item name="colorOnBackground">@color/modern_white</item> - <item name="colorOnPrimary">@color/modern_blue_800</item> - <item name="colorOnPrimaryContainer">@color/baseline_primary_900</item> - <item name="colorOnSurface">@color/modern_grey_100</item> - <item name="colorOnSurfaceVariant">@color/white_alpha_70</item> - <item name="colorOnSurfaceInverse">@color/modern_grey_800</item> - <item name="elevationOverlayEnabled">true</item> - <item name="elevationOverlayColor">@color/modern_grey_200</item> - <item name="elevationOverlayAccentColor">?attr/colorPrimary</item> + <item name="android:colorBackground">@color/baseline_neutral_900</item> + <item name="colorError">@color/baseline_error_200</item> + <item name="colorOnBackground">@color/baseline_neutral_100</item> + <item name="colorOnPrimary">@color/baseline_primary_800</item> + <item name="colorOnSurface">@color/baseline_neutral_100</item> + <item name="colorOnSurfaceInverse">@color/baseline_neutral_800</item> + <item name="colorOnSurfaceVariant">@color/baseline_neutral_variant_200</item> <item name="colorOutline">@color/baseline_neutral_variant_400</item> + <item name="colorPrimary">@color/baseline_primary_200</item> + <item name="colorSurface">@color/baseline_neutral_900</item> + <item name="colorSurfaceVariant">@color/baseline_neutral_variant_700</item> + + <item name="elevationOverlayAccentColor">?attr/colorPrimary</item> + <item name="elevationOverlayColor">@color/baseline_neutral_200</item> + <item name="elevationOverlayEnabled">true</item> <item name="colorSwitchThumbNormal">?attr/colorOnSurface</item> <item name="colorSwitchThumbDisabled">?attr/colorFixedOnSurfaceAlpha38OverSurface</item>
diff --git a/components/browser_ui/styles/android/java/res/values/styles.xml b/components/browser_ui/styles/android/java/res/values/styles.xml index 6679658a..31305c87 100644 --- a/components/browser_ui/styles/android/java/res/values/styles.xml +++ b/components/browser_ui/styles/android/java/res/values/styles.xml
@@ -190,25 +190,28 @@ <style name="Base.ColorOverlay" parent=""> <!-- Attributes that point to the same color/attr in dark and light modes. --> + <item name="colorOnPrimaryContainer">@color/baseline_primary_900</item> <item name="colorPrimaryContainer">@color/baseline_primary_100</item> <item name="android:textColorPrimary">?attr/colorOnBackground</item> <item name="android:textColorSecondary">?attr/colorOnSurfaceVariant</item> + <!-- Adaptive attributes --> - <item name="colorPrimary">@color/modern_blue_600</item> - <item name="colorError">@color/google_red_600</item> - <item name="android:colorBackground">@color/modern_white</item> - <item name="colorSurface">@color/modern_white</item> + <item name="android:colorBackground">@color/baseline_neutral_0</item> + <item name="colorError">@color/baseline_error_600</item> + <item name="colorOnBackground">@color/baseline_neutral_900</item> + <item name="colorOnPrimary">@color/baseline_primary_0</item> + <item name="colorOnSurface">@color/baseline_neutral_900</item> + <item name="colorOnSurfaceInverse">@color/baseline_neutral_50</item> + <item name="colorOnSurfaceVariant">@color/baseline_neutral_variant_700</item> + <item name="colorOutline">@color/baseline_neutral_variant_500</item> + <item name="colorPrimary">@color/baseline_primary_600</item> + <item name="colorSurface">@color/baseline_neutral_0</item> <item name="colorSurfaceVariant">@color/baseline_neutral_variant_100</item> - <item name="colorOnBackground">@color/modern_grey_900</item> - <item name="colorOnPrimary">@color/modern_white</item> - <item name="colorOnPrimaryContainer">@color/baseline_primary_900</item> - <item name="colorOnSurface">@color/modern_grey_900</item> - <item name="colorOnSurfaceVariant">@color/modern_grey_700</item> - <item name="colorOnSurfaceInverse">@color/modern_white</item> - <item name="elevationOverlayEnabled">true</item> - <item name="elevationOverlayColor">@color/modern_grey_600</item> + <item name="elevationOverlayAccentColor">?attr/colorPrimary</item> + <item name="elevationOverlayColor">@color/baseline_neutral_600</item> + <item name="elevationOverlayEnabled">true</item> <item name="colorSwitchThumbNormal">?attr/colorSurface</item> <item name="colorSwitchThumbDisabled">?attr/colorSurface</item>
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/BidirectionalStreamQuicTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/BidirectionalStreamQuicTest.java index 5e640ea..4d41c31 100644 --- a/components/cronet/android/test/javatests/src/org/chromium/net/BidirectionalStreamQuicTest.java +++ b/components/cronet/android/test/javatests/src/org/chromium/net/BidirectionalStreamQuicTest.java
@@ -389,10 +389,11 @@ callback.blockForDone(); assertTrue(stream.isDone()); assertNotNull(callback.mError); - assertTrue(callback.mError instanceof QuicException); - QuicException quicException = (QuicException) callback.mError; - // Checks that detailed quic error code is not QUIC_NO_ERROR == 0. - assertTrue("actual error " + quicException.getQuicDetailedErrorCode(), - 0 < quicException.getQuicDetailedErrorCode()); + if (callback.mError instanceof QuicException) { + QuicException quicException = (QuicException) callback.mError; + // Checks that detailed quic error code is not QUIC_NO_ERROR == 0. + assertTrue("actual error " + quicException.getQuicDetailedErrorCode(), + 0 < quicException.getQuicDetailedErrorCode()); + } } }
diff --git a/components/cronet/ios/test/cronet_prefs_test.mm b/components/cronet/ios/test/cronet_prefs_test.mm index 9b81c8b2..107b83cc 100644 --- a/components/cronet/ios/test/cronet_prefs_test.mm +++ b/components/cronet/ios/test/cronet_prefs_test.mm
@@ -116,11 +116,11 @@ ASSERT_TRUE(prefs_file_content); ASSERT_TRUE( [prefs_file_content containsString:@"{\"http_server_properties\":"]) - << "Unable to find 'http_server_properties' in the JSON prefs."; + << "Unable to find 'http_server_properties' in the JSON prefs: " + << prefs_file_content.UTF8String; ASSERT_TRUE([prefs_file_content containsString:@"\"supports_quic\":"]) - << "Unable to find 'supports_quic' in the JSON prefs."; - ASSERT_TRUE([prefs_file_content containsString:@"\"server_info\":"]) - << "Unable to find 'server_info' in the JSON prefs."; + << "Unable to find 'supports_quic' in the JSON prefs: " + << prefs_file_content.UTF8String; // Delete the prefs file to avoid side effects with other tests. [[NSFileManager defaultManager] removeItemAtPath:prefs_file_name error:nil];
diff --git a/components/download/internal/background_service/ios/background_download_service_impl.cc b/components/download/internal/background_service/ios/background_download_service_impl.cc index 5fd2af2b..1d43967 100644 --- a/components/download/internal/background_service/ios/background_download_service_impl.cc +++ b/components/download/internal/background_service/ios/background_download_service_impl.cc
@@ -118,7 +118,16 @@ void BackgroundDownloadServiceImpl::OnModelReady(bool success) { init_success_ = success; - // TODO(xingliu): Ping clients for service status. + if (!success) { + for (const auto& client_it : *clients_.get()) + + client_it.second->OnServiceUnavailable(); + return; + } + + // TODO(xingliu): Create list of metadata and call OnServiceInitialized(). + for (const auto& client_it : *clients_.get()) + client_it.second->OnServiceUnavailable(); } void BackgroundDownloadServiceImpl::OnModelHardRecoverComplete(bool success) {} @@ -141,7 +150,10 @@ std::move(callback)); download_helper_->StartDownload( entry->guid, entry->request_params, entry->scheduling_params, - base::BindRepeating(&BackgroundDownloadServiceImpl::OnDownloadFinished, + base::BindOnce(&BackgroundDownloadServiceImpl::OnDownloadFinished, + weak_ptr_factory_.GetWeakPtr(), entry->client, + entry->guid), + base::BindRepeating(&BackgroundDownloadServiceImpl::OnDownloadUpdated, weak_ptr_factory_.GetWeakPtr(), entry->client, entry->guid)); } @@ -178,4 +190,16 @@ client->OnDownloadSucceeded(guid, completion_info); } -} // namespace download \ No newline at end of file +void BackgroundDownloadServiceImpl::OnDownloadUpdated( + DownloadClient download_client, + const std::string& guid, + int64_t bytes_downloaded) { + auto it = clients_->find(download_client); + if (it == clients_->end()) + return; + download::Client* client = it->second.get(); + client->OnDownloadUpdated(guid, /*bytes_uploaded*/ 0u, + static_cast<uint64_t>(bytes_downloaded)); +} + +} // namespace download
diff --git a/components/download/internal/background_service/ios/background_download_service_impl.h b/components/download/internal/background_service/ios/background_download_service_impl.h index 8bff3095..07497e6 100644 --- a/components/download/internal/background_service/ios/background_download_service_impl.h +++ b/components/download/internal/background_service/ios/background_download_service_impl.h
@@ -66,6 +66,10 @@ bool success, const base::FilePath& file_path); + void OnDownloadUpdated(DownloadClient download_client, + const std::string& guid, + int64_t bytes_downloaded); + std::unique_ptr<Configuration> config_; ServiceConfigImpl service_config_; // TODO(xingliu): Ping clients for all events.
diff --git a/components/download/internal/background_service/ios/background_download_service_impl_unittest.cc b/components/download/internal/background_service/ios/background_download_service_impl_unittest.cc index 83a1b38..5c28b33 100644 --- a/components/download/internal/background_service/ios/background_download_service_impl_unittest.cc +++ b/components/download/internal/background_service/ios/background_download_service_impl_unittest.cc
@@ -17,6 +17,7 @@ #include "testing/platform_test.h" using ::base::test::RunCallback; +using ::base::test::RunOnceCallback; using ::testing::_; using ::testing::NiceMock; using ServiceStatus = download::BackgroundDownloadService::ServiceStatus; @@ -43,7 +44,8 @@ (const std::string& guid, const RequestParams&, const SchedulingParams&, - CompletionCallback), + CompletionCallback, + UpdateCallback), (override)); }; @@ -98,6 +100,7 @@ TEST_F(BackgroundDownloadServiceImplTest, InitFailure) { EXPECT_EQ(ServiceStatus::STARTING_UP, service()->GetStatus()); + EXPECT_CALL(*client_, OnServiceUnavailable()); store_->TriggerInit(/*success=*/false, empty_entries()); EXPECT_EQ(ServiceStatus::UNAVAILABLE, service()->GetStatus()); } @@ -115,8 +118,8 @@ TEST_F(BackgroundDownloadServiceImplTest, StartDownloadHelperFailure) { store_->TriggerInit(/*success=*/true, empty_entries()); EXPECT_CALL(start_callback_, Run(kGuid, StartResult::ACCEPTED)); - EXPECT_CALL(*download_helper_, StartDownload(_, _, _, _)) - .WillOnce(RunCallback<3>(/*success=*/false, base::FilePath())); + EXPECT_CALL(*download_helper_, StartDownload(_, _, _, _, _)) + .WillOnce(RunOnceCallback<3>(/*success=*/false, base::FilePath())); EXPECT_CALL(*client_, OnDownloadFailed(kGuid, CompletionInfoIs(base::FilePath()), download::Client::FailureReason::UNKNOWN)); @@ -130,8 +133,9 @@ TEST_F(BackgroundDownloadServiceImplTest, StartDownloadSuccess) { store_->TriggerInit(/*success=*/true, empty_entries()); EXPECT_CALL(start_callback_, Run(kGuid, StartResult::ACCEPTED)); - EXPECT_CALL(*download_helper_, StartDownload(_, _, _, _)) - .WillOnce(RunCallback<3>(/*success=*/true, base::FilePath(kFilePath))); + EXPECT_CALL(*download_helper_, StartDownload(_, _, _, _, _)) + .WillOnce( + RunOnceCallback<3>(/*success=*/true, base::FilePath(kFilePath))); EXPECT_CALL( *client_, OnDownloadSucceeded(kGuid, CompletionInfoIs(base::FilePath(kFilePath)))); @@ -142,5 +146,19 @@ task_environment_.RunUntilIdle(); } +// Verifies Client::OnDownloadUpdated() is called. +TEST_F(BackgroundDownloadServiceImplTest, OnDownloadUpdated) { + store_->TriggerInit(/*success=*/true, empty_entries()); + EXPECT_CALL(start_callback_, Run(kGuid, StartResult::ACCEPTED)); + EXPECT_CALL(*download_helper_, StartDownload(_, _, _, _, _)) + .WillOnce(RunCallback<4>(10u)); + EXPECT_CALL(*client_, OnDownloadUpdated(kGuid, 0u, 10u)); + auto download_params = CreateDownloadParams(kURL); + service()->StartDownload(std::move(download_params)); + store_->TriggerUpdate(/*success=*/true); + EXPECT_EQ(kGuid, store_->LastUpdatedEntry()->guid); + task_environment_.RunUntilIdle(); +} + } // namespace } // namespace download
diff --git a/components/download/internal/background_service/ios/background_download_task_helper.h b/components/download/internal/background_service/ios/background_download_task_helper.h index 62e2faf..46802a65 100644 --- a/components/download/internal/background_service/ios/background_download_task_helper.h +++ b/components/download/internal/background_service/ios/background_download_task_helper.h
@@ -28,7 +28,9 @@ // Callback with whether download is succeeded and the file path of the // succeeded download. using CompletionCallback = - base::RepeatingCallback<void(bool, const base::FilePath&)>; + base::OnceCallback<void(bool, const base::FilePath&)>; + // Callback with number of bytes downloaded. + using UpdateCallback = base::RepeatingCallback<void(int64_t)>; static std::unique_ptr<BackgroundDownloadTaskHelper> Create( const base::FilePath& download_dir); @@ -42,7 +44,8 @@ virtual void StartDownload(const std::string& guid, const RequestParams& request_params, const SchedulingParams& scheduling_params, - CompletionCallback completion_callback) = 0; + CompletionCallback completion_callback, + UpdateCallback update_callback) = 0; }; } // namespace download
diff --git a/components/download/internal/background_service/ios/background_download_task_helper.mm b/components/download/internal/background_service/ios/background_download_task_helper.mm index 11ecce9..d562cc1 100644 --- a/components/download/internal/background_service/ios/background_download_task_helper.mm +++ b/components/download/internal/background_service/ios/background_download_task_helper.mm
@@ -22,25 +22,39 @@ using CompletionCallback = download::BackgroundDownloadTaskHelper::CompletionCallback; +using UpdateCallback = download::BackgroundDownloadTaskHelper::UpdateCallback; @interface BackgroundDownloadDelegate : NSObject <NSURLSessionDownloadDelegate> - (instancetype)initWithDownloadDirectory:(base::FilePath)downloadDir - completionHandler:(CompletionCallback)completionHandler; + guid:(std::string)guid + completionHandler:(CompletionCallback)completionHandler + updateHandler:(UpdateCallback)updateHandler; @end @implementation BackgroundDownloadDelegate { base::FilePath _downloadDir; + std::string _guid; CompletionCallback _completionCallback; + UpdateCallback _updateCallback; } - (instancetype)initWithDownloadDirectory:(base::FilePath)downloadDir - completionHandler: - (CompletionCallback)completionHandler { + guid:(std::string)guid + completionHandler:(CompletionCallback)completionHandler + updateHandler:(UpdateCallback)updateHandler { _downloadDir = downloadDir; - _completionCallback = completionHandler; + _guid = guid; + _completionCallback = std::move(completionHandler); + _updateCallback = updateHandler; return self; } +- (void)invokeCompletionHandler:(bool)success + filePath:(base::FilePath)filePath { + if (_completionCallback) + std::move(_completionCallback).Run(success, filePath); +} + #pragma mark - NSURLSessionDownloadDelegate - (void)URLSession:(NSURLSession*)session @@ -60,7 +74,8 @@ DVLOG(1) << __func__ << ",byte written: " << bytesWritten << ", totalBytesWritten:" << totalBytesWritten << ", totalBytesExpectedToWrite:" << totalBytesExpectedToWrite; - NOTIMPLEMENTED(); + if (_updateCallback) + _updateCallback.Run(totalBytesWritten); } - (void)URLSession:(NSURLSession*)session @@ -68,14 +83,14 @@ didFinishDownloadingToURL:(NSURL*)location { DVLOG(1) << __func__; if (!location) { - _completionCallback.Run(/*success=*/false, base::FilePath()); + [self invokeCompletionHandler:/*success=*/false filePath:base::FilePath()]; return; } // Make sure the target directory exists. if (!base::CreateDirectory(_downloadDir)) { LOG(ERROR) << "Failed to create dir:" << _downloadDir; - _completionCallback.Run(/*success=*/false, base::FilePath()); + [self invokeCompletionHandler:/*success=*/false filePath:base::FilePath()]; return; } @@ -83,16 +98,14 @@ // service's target directory. const base::FilePath tempPath = base::mac::NSStringToFilePath([location path]); - // TODO(xingliu): Rename the file to use the guid of the download. - base::FilePath newFile = _downloadDir.Append(base::NumberToString( - base::Time::Now().ToDeltaSinceWindowsEpoch().InMilliseconds())); + base::FilePath newFile = _downloadDir.AppendASCII(_guid); if (!base::Move(tempPath, newFile)) { LOG(ERROR) << "Failed to move file from:" << tempPath << ", to:" << _downloadDir; - _completionCallback.Run(/*success=*/false, base::FilePath()); + [self invokeCompletionHandler:/*success=*/false filePath:base::FilePath()]; return; } - _completionCallback.Run(/*success=*/true, newFile); + [self invokeCompletionHandler:/*success=*/true filePath:newFile]; } #pragma mark - NSURLSessionDelegate @@ -103,7 +116,6 @@ VLOG(1) << __func__; // TODO(xingliu): Check whether we can resume for a few times if the user // terminated the app in multitask window or failed downloads. - NOTIMPLEMENTED(); } @end @@ -121,7 +133,8 @@ void StartDownload(const std::string& guid, const RequestParams& request_params, const SchedulingParams& scheduling_params, - CompletionCallback completion_callback) override { + CompletionCallback completion_callback, + UpdateCallback update_callback) override { // TODO(xingliu): Implement handleEventsForBackgroundURLSession and invoke // the callback passed from it. NSURLSessionConfiguration* configuration = [NSURLSessionConfiguration @@ -135,7 +148,9 @@ SchedulingParams::BatteryRequirements::BATTERY_INSENSITIVE; BackgroundDownloadDelegate* delegate = [[BackgroundDownloadDelegate alloc] initWithDownloadDirectory:download_dir_ - completionHandler:completion_callback]; + guid:guid + completionHandler:std::move(completion_callback) + updateHandler:update_callback]; NSURLSession* session = [NSURLSession sessionWithConfiguration:configuration delegate:delegate delegateQueue:nil];
diff --git a/components/download/internal/background_service/ios/background_download_task_helper_unittest.mm b/components/download/internal/background_service/ios/background_download_task_helper_unittest.mm index 5dc4c78..dda06a4 100644 --- a/components/download/internal/background_service/ios/background_download_task_helper_unittest.mm +++ b/components/download/internal/background_service/ios/background_download_task_helper_unittest.mm
@@ -11,6 +11,7 @@ #import "base/files/scoped_temp_dir.h" #import "base/run_loop.h" #import "base/test/bind.h" +#import "base/test/gmock_callback_support.h" #import "base/test/task_environment.h" #import "components/download/public/background_service/download_params.h" #import "net/test/embedded_test_server/embedded_test_server.h" @@ -60,7 +61,8 @@ ASSERT_TRUE(base::ReadFileToString(file_path, &content)); EXPECT_EQ(kDefaultResponseContent, content); loop.Quit(); - })); + }), + base::DoNothing()); loop.Run(); DCHECK(request_sent_); auto it = request_sent_->headers.find(net::HttpRequestHeaders::kIfMatch); @@ -69,6 +71,7 @@ } const HttpRequest* request_sent() const { return request_sent_.get(); } + const base::ScopedTempDir& dir() const { return dir_; } private: std::unique_ptr<HttpResponse> DefaultResponse(const HttpRequest& request) { @@ -91,6 +94,7 @@ // Verifies download can be finished. TEST_F(BackgroundDownloadTaskHelperTest, DownloadComplete) { Download("/test"); + EXPECT_TRUE(base::PathExists(dir().GetPath().AppendASCII(kGuid))); } } // namespace download
diff --git a/components/favicon/core/favicon_database.cc b/components/favicon/core/favicon_database.cc index 940014c..fda4982 100644 --- a/components/favicon/core/favicon_database.cc +++ b/components/favicon/core/favicon_database.cc
@@ -1061,7 +1061,9 @@ // Clear databases which are too old to process. DCHECK_LT(kDeprecatedVersionNumber, kCurrentVersionNumber); - sql::MetaTable::RazeIfDeprecated(&db_, kDeprecatedVersionNumber); + sql::MetaTable::RazeIfIncompatible( + &db_, /*lowest_supported_version=*/kDeprecatedVersionNumber + 1, + kCurrentVersionNumber); // TODO(shess): Sqlite.Version.Thumbnail shows versions 22, 23, and // 25. Future versions are not destroyed because that could lead to
diff --git a/components/full_restore/full_restore_read_and_save_unittest.cc b/components/full_restore/full_restore_read_and_save_unittest.cc index ccc967b1..be23021 100644 --- a/components/full_restore/full_restore_read_and_save_unittest.cc +++ b/components/full_restore/full_restore_read_and_save_unittest.cc
@@ -86,6 +86,10 @@ return arc_read_handler->task_id_to_window_id_; } + void ClearRestoreData() { + read_handler_->profile_path_to_restore_data_.clear(); + } + private: FullRestoreReadHandler* read_handler_; }; @@ -176,6 +180,8 @@ void ReadFromFile(const base::FilePath& file_path) { FullRestoreReadHandler* read_handler = FullRestoreReadHandler::GetInstance(); + FullRestoreReadHandlerTestApi(read_handler).ClearRestoreData(); + base::RunLoop run_loop; read_handler->ReadFromFile(
diff --git a/components/full_restore/full_restore_read_handler.cc b/components/full_restore/full_restore_read_handler.cc index bb814568..9bcc62d 100644 --- a/components/full_restore/full_restore_read_handler.cc +++ b/components/full_restore/full_restore_read_handler.cc
@@ -102,6 +102,23 @@ void FullRestoreReadHandler::ReadFromFile(const base::FilePath& profile_path, Callback callback) { + auto it = profile_path_to_restore_data_.find(profile_path); + if (it != profile_path_to_restore_data_.end()) { + // If the restore data has been read from the file, just use it, and don't + // need to read it again. + // + // We must use post task here, because FullRestoreAppLaunchHandler calls + // ReadFromFile in FullRestoreService construct function, and the callback + // in FullRestoreAppLaunchHandler calls the init function of + // FullRestoreService. If we don't use post task, and call the callback + // function directly, it could cause deadloop. + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::BindOnce(std::move(callback), + (it->second ? it->second->Clone() : nullptr))); + return; + } + auto file_handler = base::MakeRefCounted<FullRestoreFileHandler>(profile_path); file_handler->owning_task_runner()->PostTaskAndReplyWithResult( @@ -377,6 +394,8 @@ } } } + } else { + profile_path_to_restore_data_[profile_path] = nullptr; } std::move(callback).Run(std::move(restore_data));
diff --git a/components/full_restore/full_restore_read_handler.h b/components/full_restore/full_restore_read_handler.h index bf83b710..d4f1dd2e 100644 --- a/components/full_restore/full_restore_read_handler.h +++ b/components/full_restore/full_restore_read_handler.h
@@ -26,6 +26,8 @@ namespace chromeos { namespace full_restore { class FullRestoreAppLaunchHandlerBrowserTest; +class FullRestoreAppLaunchHandlerSystemWebAppsBrowserTest; +class FullRestoreServiceTestHavingFullRestoreFile; } } @@ -142,6 +144,10 @@ private: friend class ArcReadHandler; friend class ::chromeos::full_restore::FullRestoreAppLaunchHandlerBrowserTest; + friend class ::chromeos::full_restore:: + FullRestoreAppLaunchHandlerSystemWebAppsBrowserTest; + friend class ::chromeos::full_restore:: + FullRestoreServiceTestHavingFullRestoreFile; friend class FullRestoreReadHandlerTestApi; // Gets the app launch information from `profile_path` for `app_id` and
diff --git a/components/full_restore/full_restore_save_handler.cc b/components/full_restore/full_restore_save_handler.cc index 02b51b8c..2b21b17 100644 --- a/components/full_restore/full_restore_save_handler.cc +++ b/components/full_restore/full_restore_save_handler.cc
@@ -6,6 +6,7 @@ #include "ash/constants/app_types.h" #include "base/bind.h" +#include "base/callback_helpers.h" #include "base/files/file_path.h" #include "base/no_destructor.h" #include "base/sequenced_task_runner.h" @@ -13,6 +14,7 @@ #include "components/full_restore/app_launch_info.h" #include "components/full_restore/full_restore_file_handler.h" #include "components/full_restore/full_restore_info.h" +#include "components/full_restore/full_restore_read_handler.h" #include "components/full_restore/full_restore_utils.h" #include "components/full_restore/restore_data.h" #include "components/full_restore/window_info.h" @@ -271,7 +273,7 @@ pending_save_profile_paths_.insert(profile_path); - MaybeStartSaveTimer(); + MaybeStartSaveTimer(profile_path); } void FullRestoreSaveHandler::ModifyWindowId(const base::FilePath& profile_path, @@ -287,7 +289,7 @@ pending_save_profile_paths_.insert(profile_path); - MaybeStartSaveTimer(); + MaybeStartSaveTimer(profile_path); } void FullRestoreSaveHandler::ModifyWindowInfo( @@ -304,7 +306,7 @@ pending_save_profile_paths_.insert(profile_path); - MaybeStartSaveTimer(); + MaybeStartSaveTimer(profile_path); } void FullRestoreSaveHandler::ModifyThemeColor( @@ -322,7 +324,7 @@ pending_save_profile_paths_.insert(profile_path); - MaybeStartSaveTimer(); + MaybeStartSaveTimer(profile_path); } void FullRestoreSaveHandler::RemoveApp(const base::FilePath& profile_path, @@ -335,7 +337,7 @@ pending_save_profile_paths_.insert(profile_path); - MaybeStartSaveTimer(); + MaybeStartSaveTimer(profile_path); } void FullRestoreSaveHandler::RemoveAppRestoreData( @@ -350,7 +352,7 @@ pending_save_profile_paths_.insert(profile_path); - MaybeStartSaveTimer(); + MaybeStartSaveTimer(profile_path); } void FullRestoreSaveHandler::RemoveWindowInfo( @@ -365,14 +367,14 @@ pending_save_profile_paths_.insert(profile_path); - MaybeStartSaveTimer(); + MaybeStartSaveTimer(profile_path); } void FullRestoreSaveHandler::ClearRestoreData( const base::FilePath& profile_path) { pending_save_profile_paths_.insert(profile_path); - MaybeStartSaveTimer(); + MaybeStartSaveTimer(profile_path); } int32_t FullRestoreSaveHandler::GetArcSessionId() { @@ -401,7 +403,19 @@ app_id_to_app_launch_infos_.clear(); } -void FullRestoreSaveHandler::MaybeStartSaveTimer() { +void FullRestoreSaveHandler::MaybeStartSaveTimer( + const base::FilePath& profile_path) { + if (!base::Contains(been_read_profile_paths_, profile_path)) { + // FullRestoreSaveHandler might be called to save the help app before + // FullRestoreAppLaunchHandler reads the full restore data from the full + // restore file during the system startup phase, e.g. when a new user login. + // So call FullRestoreReadHandler to read the file before saving the new + // data. + FullRestoreReadHandler::GetInstance()->ReadFromFile(profile_path, + base::DoNothing()); + been_read_profile_paths_.insert(profile_path); + } + if (!save_timer_.IsRunning() && save_running_.empty()) { save_timer_.Start(FROM_HERE, kSaveDelay, base::BindOnce(&FullRestoreSaveHandler::Save,
diff --git a/components/full_restore/full_restore_save_handler.h b/components/full_restore/full_restore_save_handler.h index e14992f..864e21f 100644 --- a/components/full_restore/full_restore_save_handler.h +++ b/components/full_restore/full_restore_save_handler.h
@@ -158,7 +158,7 @@ using AppLaunchInfos = std::map<base::FilePath, std::list<AppLaunchInfoPtr>>; // Starts the timer that invokes Save (if timer isn't already running). - void MaybeStartSaveTimer(); + void MaybeStartSaveTimer(const base::FilePath& profile_path); // Passes |profile_path_to_restore_data_| to the backend for saving. void Save(); @@ -177,6 +177,14 @@ // Removes AppRestoreData for |window_id|. void RemoveAppRestoreData(int window_id); + // FullRestoreSaveHandler might be called to save the help app before + // FullRestoreAppLaunchHandler reads the full restore data from the full + // restore file during the system startup phase, e.g. when a new user login. + // So call FullRestoreReadHandler to read the file before saving the new data. + // `been_read_profile_paths_` is used to save the profile paths, whose full + // restore file has been read by FullRestoreReadHandler. + std::set<base::FilePath> been_read_profile_paths_; + // Records whether there are new updates for saving between each saving delay. // |pending_save_profile_paths_| is cleared when Save is invoked. std::set<base::FilePath> pending_save_profile_paths_;
diff --git a/components/grpc_support/bidirectional_stream_unittest.cc b/components/grpc_support/bidirectional_stream_unittest.cc index 5a56113a..63ef5ca 100644 --- a/components/grpc_support/bidirectional_stream_unittest.cc +++ b/components/grpc_support/bidirectional_stream_unittest.cc
@@ -712,7 +712,9 @@ ASSERT_EQ(TestBidirectionalStreamCallback::ON_FAILED, test.response_step); ASSERT_TRUE(test.net_error == net::ERR_QUIC_PROTOCOL_ERROR || test.net_error == net::ERR_QUIC_HANDSHAKE_FAILED || - test.net_error == net::ERR_CONNECTION_REFUSED); + test.net_error == net::ERR_CONNECTION_REFUSED || + test.net_error == net::ERR_QUIC_GOAWAY_REQUEST_CAN_BE_RETRIED) + << net::ErrorToString(test.net_error); bidirectional_stream_destroy(test.stream); }
diff --git a/components/history/core/browser/top_sites_database.cc b/components/history/core/browser/top_sites_database.cc index cc2d038d..bd3324f 100644 --- a/components/history/core/browser/top_sites_database.cc +++ b/components/history/core/browser/top_sites_database.cc
@@ -322,7 +322,9 @@ // Clear databases which are too old to process. DCHECK_LT(kDeprecatedVersionNumber, kVersionNumber); - sql::MetaTable::RazeIfDeprecated(db_.get(), kDeprecatedVersionNumber); + sql::MetaTable::RazeIfIncompatible( + db_.get(), /*lowest_supported_version=*/kDeprecatedVersionNumber + 1, + kVersionNumber); // Scope initialization in a transaction so we can't be partially // initialized.
diff --git a/components/nacl/broker/nacl_broker_listener.cc b/components/nacl/broker/nacl_broker_listener.cc index ddbe1ff..9c4e7c6a 100644 --- a/components/nacl/broker/nacl_broker_listener.cc +++ b/components/nacl/broker/nacl_broker_listener.cc
@@ -30,6 +30,8 @@ #include "mojo/public/cpp/system/message_pipe.h" #include "sandbox/win/src/sandbox_policy.h" +#include <windows.h> + namespace { void SendReply(IPC::Channel* channel, int32_t pid, bool result) {
diff --git a/components/neterror/resources/offline.js b/components/neterror/resources/offline.js index 895cd76..e6c6791 100644 --- a/components/neterror/resources/offline.js +++ b/components/neterror/resources/offline.js
@@ -1856,7 +1856,7 @@ this.canvasCtx.save(); if (IS_RTL) { - this.canvasCtx.translate(this.canvas.width / 2, 0); + this.canvasCtx.translate(this.canvasDimensions.WIDTH, 0); this.canvasCtx.scale(-1, 1); } @@ -1916,7 +1916,7 @@ this.canvasCtx.save(); if (IS_RTL) { - this.canvasCtx.translate(this.canvas.width / 2, 0); + this.canvasCtx.translate(this.canvasDimensions.WIDTH, 0); this.canvasCtx.scale(-1, 1); } @@ -2908,6 +2908,7 @@ this.config = DistanceMeter.config; this.maxScoreUnits = this.config.MAX_DISTANCE_UNITS; + this.canvasWidth = canvasWidth; this.init(canvasWidth); } @@ -3015,12 +3016,12 @@ if (IS_RTL) { if (opt_highScore) { this.canvasCtx.translate( - (this.canvas.width / 2) - + this.canvasWidth - (DistanceMeter.dimensions.WIDTH * (this.maxScoreUnits + 3)), this.y); } else { this.canvasCtx.translate( - this.canvas.width / 2 - DistanceMeter.dimensions.WIDTH, this.y); + this.canvasWidth - DistanceMeter.dimensions.WIDTH, this.y); } this.canvasCtx.scale(-1, 1); } else {
diff --git a/components/omnibox/browser/omnibox_field_trial.cc b/components/omnibox/browser/omnibox_field_trial.cc index f95c3ec..e2f9c6b 100644 --- a/components/omnibox/browser/omnibox_field_trial.cc +++ b/components/omnibox/browser/omnibox_field_trial.cc
@@ -656,8 +656,13 @@ const base::Feature* feature = is_incognito ? &omnibox::kOnDeviceHeadProviderIncognito : &omnibox::kOnDeviceHeadProviderNonIncognito; - return base::GetFieldTrialParamValueByFeature( + std::string constraint = base::GetFieldTrialParamValueByFeature( *feature, kOnDeviceHeadModelLocaleConstraint); +#if !defined(OS_ANDROID) && !defined(OS_IOS) + if (constraint.empty()) + constraint = "500000"; +#endif // !defined(OS_ANDROID) && !defined(OS_IOS) + return constraint; } int OmniboxFieldTrial::OnDeviceHeadSuggestMaxScoreForNonUrlInput(
diff --git a/components/password_manager/core/browser/form_fetcher_impl.cc b/components/password_manager/core/browser/form_fetcher_impl.cc index a52454cf..84c41351 100644 --- a/components/password_manager/core/browser/form_fetcher_impl.cc +++ b/components/password_manager/core/browser/form_fetcher_impl.cc
@@ -121,7 +121,9 @@ // processor cycles. #if !defined(OS_IOS) && !defined(OS_ANDROID) // The statistics is needed for the "Save password?" bubble. - password_store->GetSiteStats(form_digest_.url.GetOrigin(), this); + password_manager::SmartBubbleStatsStore* stats_store = + password_store->GetSmartBubbleStatsStore(); + stats_store->GetSiteStats(form_digest_.url.GetOrigin(), this); // The desktop bubble needs this information. password_store->GetMatchingInsecureCredentials(form_digest_.signon_realm,
diff --git a/components/password_manager/core/browser/mock_password_store.h b/components/password_manager/core/browser/mock_password_store.h index 92ae4927..1c81c289 100644 --- a/components/password_manager/core/browser/mock_password_store.h +++ b/components/password_manager/core/browser/mock_password_store.h
@@ -28,6 +28,14 @@ MOCK_METHOD(void, RemoveLogin, (const PasswordForm&), (override)); MOCK_METHOD(void, + RemoveLoginsByURLAndTime, + (const base::RepeatingCallback<bool(const GURL&)>&, + base::Time, + base::Time, + base::OnceClosure, + base::OnceCallback<void(bool)>), + (override)); + MOCK_METHOD(void, Unblocklist, (const PasswordFormDigest&, base::OnceClosure), (override)); @@ -90,10 +98,20 @@ (const std::u16string&), (override)); MOCK_METHOD(DatabaseCleanupResult, DeleteUndecryptableLogins, (), (override)); + void SetUnsyncedCredentialsDeletionNotifier( + std::unique_ptr<UnsyncedCredentialsDeletionNotifier> deletion_notifier) + override { + NOTIMPLEMENTED(); + } MOCK_METHOD(void, NotifyLoginsChanged, (const PasswordStoreChangeList&), (override)); + void NotifyDeletionsHaveSynced(bool) override { NOTIMPLEMENTED(); } + void NotifyUnsyncedCredentialsWillBeDeleted( + std::vector<PasswordForm>) override { + NOTIMPLEMENTED(); + } MOCK_METHOD(std::vector<InteractionsStats>, GetSiteStatsImpl, (const GURL& origin_domain),
diff --git a/components/password_manager/core/browser/mock_password_store_interface.h b/components/password_manager/core/browser/mock_password_store_interface.h index 8d4fa45..e4ce95cb 100644 --- a/components/password_manager/core/browser/mock_password_store_interface.h +++ b/components/password_manager/core/browser/mock_password_store_interface.h
@@ -32,7 +32,7 @@ (override)); MOCK_METHOD(void, RemoveLoginsCreatedBetween, - (base::Time, base::Time, base::OnceClosure), + (base::Time, base::Time, base::OnceCallback<void(bool)>), (override)); MOCK_METHOD(void, DisableAutoSignInForOrigins,
diff --git a/components/password_manager/core/browser/password_store.cc b/components/password_manager/core/browser/password_store.cc index 28bb77f8..4ee2bce 100644 --- a/components/password_manager/core/browser/password_store.cc +++ b/components/password_manager/core/browser/password_store.cc
@@ -129,15 +129,18 @@ base::OnceClosure completion, base::OnceCallback<void(bool)> sync_completion) { DCHECK(main_task_runner_->RunsTasksInCurrentSequence()); - ScheduleTask(base::BindOnce(&PasswordStore::RemoveLoginsByURLAndTimeInternal, - this, url_filter, delete_begin, delete_end, - std::move(completion), - std::move(sync_completion))); + // TODO(crbug.com/1226042): Pass NotifyLoginsChanged as a callback since + // PasswordStoreImpl won't call PasswordStore::NotifyLoginsChanged directly + // after it inherits PasswordStoreSync. + backend_->RemoveLoginsByURLAndTimeAsync( + base::NullCallback(), url_filter, delete_begin, delete_end, + std::move(completion), std::move(sync_completion)); } -void PasswordStore::RemoveLoginsCreatedBetween(base::Time delete_begin, - base::Time delete_end, - base::OnceClosure completion) { +void PasswordStore::RemoveLoginsCreatedBetween( + base::Time delete_begin, + base::Time delete_end, + base::OnceCallback<void(bool)> completion) { DCHECK(main_task_runner_->RunsTasksInCurrentSequence()); ScheduleTask( base::BindOnce(&PasswordStore::RemoveLoginsCreatedBetweenInternal, this, @@ -231,36 +234,6 @@ return this; } -void PasswordStore::AddSiteStats(const InteractionsStats& stats) { - DCHECK(main_task_runner_->RunsTasksInCurrentSequence()); - ScheduleTask(base::BindOnce(&PasswordStore::AddSiteStatsImpl, this, stats)); -} - -void PasswordStore::RemoveSiteStats(const GURL& origin_domain) { - DCHECK(main_task_runner_->RunsTasksInCurrentSequence()); - ScheduleTask( - base::BindOnce(&PasswordStore::RemoveSiteStatsImpl, this, origin_domain)); -} - -void PasswordStore::GetSiteStats(const GURL& origin_domain, - PasswordStoreConsumer* consumer) { - DCHECK(main_task_runner_->RunsTasksInCurrentSequence()); - PostStatsTaskAndReplyToConsumerWithResult( - consumer, - base::BindOnce(&PasswordStore::GetSiteStatsImpl, this, origin_domain)); -} - -void PasswordStore::RemoveStatisticsByOriginAndTime( - const base::RepeatingCallback<bool(const GURL&)>& origin_filter, - base::Time delete_begin, - base::Time delete_end, - base::OnceClosure completion) { - DCHECK(main_task_runner_->RunsTasksInCurrentSequence()); - ScheduleTask(base::BindOnce( - &PasswordStore::RemoveStatisticsByOriginAndTimeInternal, this, - origin_filter, delete_begin, delete_end, std::move(completion))); -} - void PasswordStore::ReportMetrics(const std::string& sync_username, bool custom_passphrase_sync_enabled, bool is_under_advanced_protection) { @@ -350,12 +323,6 @@ std::move(completion))); } -void PasswordStore::ClearStore(base::OnceCallback<void(bool)> completion) { - DCHECK(main_task_runner_->RunsTasksInCurrentSequence()); - ScheduleTask(base::BindOnce(&PasswordStore::ClearStoreInternal, this, - std::move(completion))); -} - void PasswordStore::AddObserver(Observer* observer) { observers_->AddObserver(observer); } @@ -394,22 +361,40 @@ base::Unretained(this))); } -void PasswordStore::SetUnsyncedCredentialsDeletionNotifier( - std::unique_ptr<PasswordStore::UnsyncedCredentialsDeletionNotifier> - notifier) { - DCHECK(!deletion_notifier_); - DCHECK(notifier); - deletion_notifier_ = std::move(notifier); -} - -void PasswordStore::SetSyncTaskTimeoutForTest(base::TimeDelta timeout) { - sync_task_timeout_ = timeout; -} - PasswordStore::~PasswordStore() { DCHECK(shutdown_called_); } +void PasswordStore::AddSiteStats(const InteractionsStats& stats) { + DCHECK(main_task_runner_->RunsTasksInCurrentSequence()); + ScheduleTask(base::BindOnce(&PasswordStore::AddSiteStatsImpl, this, stats)); +} + +void PasswordStore::RemoveSiteStats(const GURL& origin_domain) { + DCHECK(main_task_runner_->RunsTasksInCurrentSequence()); + ScheduleTask( + base::BindOnce(&PasswordStore::RemoveSiteStatsImpl, this, origin_domain)); +} + +void PasswordStore::GetSiteStats(const GURL& origin_domain, + PasswordStoreConsumer* consumer) { + DCHECK(main_task_runner_->RunsTasksInCurrentSequence()); + PostStatsTaskAndReplyToConsumerWithResult( + consumer, + base::BindOnce(&PasswordStore::GetSiteStatsImpl, this, origin_domain)); +} + +void PasswordStore::RemoveStatisticsByOriginAndTime( + const base::RepeatingCallback<bool(const GURL&)>& origin_filter, + base::Time delete_begin, + base::Time delete_end, + base::OnceClosure completion) { + DCHECK(main_task_runner_->RunsTasksInCurrentSequence()); + ScheduleTask(base::BindOnce( + &PasswordStore::RemoveStatisticsByOriginAndTimeInternal, this, + origin_filter, delete_begin, delete_end, std::move(completion))); +} + scoped_refptr<base::SequencedTaskRunner> PasswordStore::CreateBackgroundTaskRunner() const { return base::ThreadPool::CreateSequencedTaskRunner( @@ -425,41 +410,12 @@ } } -void PasswordStore::NotifyDeletionsHaveSynced(bool success) { - DCHECK(background_task_runner_->RunsTasksInCurrentSequence()); - // Either all deletions have been committed to the Sync server, or Sync is - // telling us that it won't commit them (because Sync was turned off - // permanently). In either case, run the corresponding callbacks now (on the - // main task runner). - DCHECK(!success || !GetMetadataStore()->HasUnsyncedDeletions()); - for (auto& callback : deletions_have_synced_callbacks_) { - main_task_runner_->PostTask(FROM_HERE, - base::BindOnce(std::move(callback), success)); - } - deletions_have_synced_timeout_.Cancel(); - deletions_have_synced_callbacks_.clear(); -} - void PasswordStore::InvokeAndNotifyAboutInsecureCredentialsChange( base::OnceCallback<PasswordStoreChangeList()> callback) { DCHECK(background_task_runner_->RunsTasksInCurrentSequence()); NotifyLoginsChanged(std::move(callback).Run()); } -void PasswordStore::NotifyUnsyncedCredentialsWillBeDeleted( - std::vector<PasswordForm> unsynced_credentials) { - DCHECK(background_task_runner_->RunsTasksInCurrentSequence()); - DCHECK(IsAccountStore()); - // |deletion_notifier_| only gets set for desktop. - if (deletion_notifier_) { - main_task_runner_->PostTask( - FROM_HERE, - base::BindOnce( - &PasswordStore::UnsyncedCredentialsDeletionNotifier::Notify, - deletion_notifier_->GetWeakPtr(), std::move(unsynced_credentials))); - } -} - void PasswordStore::OnInitCompleted(bool success) { DCHECK(main_task_runner_->RunsTasksInCurrentSequence()); init_status_ = success ? InitStatus::kSuccess : InitStatus::kFailure; @@ -566,47 +522,10 @@ CommitTransaction(); } -void PasswordStore::RemoveLoginsByURLAndTimeInternal( - const base::RepeatingCallback<bool(const GURL&)>& url_filter, - base::Time delete_begin, - base::Time delete_end, - base::OnceClosure completion, - base::OnceCallback<void(bool)> sync_completion) { - DCHECK(background_task_runner_->RunsTasksInCurrentSequence()); - TRACE_EVENT0("passwords", "PasswordStore::RemoveLoginsByURLAndTimeInternal"); - BeginTransaction(); - PasswordStoreChangeList changes = - RemoveLoginsByURLAndTimeImpl(url_filter, delete_begin, delete_end); - NotifyLoginsChanged(changes); - // Sync metadata get updated in NotifyLoginsChanged(). Therefore, - // CommitTransaction() must be called after NotifyLoginsChanged(), because - // sync codebase needs to update metadata atomically together with the login - // data. - CommitTransaction(); - - if (completion) - main_task_runner_->PostTask(FROM_HERE, std::move(completion)); - - if (sync_completion) { - deletions_have_synced_callbacks_.push_back(std::move(sync_completion)); - // Start a timeout for sync, or restart it if it was already running. - deletions_have_synced_timeout_.Reset(base::BindOnce( - &PasswordStore::NotifyDeletionsHaveSynced, this, /*success=*/false)); - background_task_runner_->PostDelayedTask( - FROM_HERE, deletions_have_synced_timeout_.callback(), - sync_task_timeout_); - - // Do an immediate check for the case where there are already no unsynced - // deletions. - if (!GetMetadataStore()->HasUnsyncedDeletions()) - NotifyDeletionsHaveSynced(/*success=*/true); - } -} - void PasswordStore::RemoveLoginsCreatedBetweenInternal( base::Time delete_begin, base::Time delete_end, - base::OnceClosure completion) { + base::OnceCallback<void(bool)> completion) { DCHECK(background_task_runner_->RunsTasksInCurrentSequence()); TRACE_EVENT0("passwords", "PasswordStore::RemoveLoginsCreatedBetweenInternal"); @@ -619,8 +538,10 @@ // sync codebase needs to update metadata atomically together with the login // data. CommitTransaction(); - if (completion) - main_task_runner_->PostTask(FROM_HERE, std::move(completion)); + if (completion) { + main_task_runner_->PostTask( + FROM_HERE, base::BindOnce(std::move(completion), !changes.empty())); + } } void PasswordStore::RemoveStatisticsByOriginAndTimeInternal( @@ -672,18 +593,6 @@ main_task_runner_->PostTask(FROM_HERE, std::move(completion)); } -void PasswordStore::ClearStoreInternal( - base::OnceCallback<void(bool)> completion) { - DCHECK(background_task_runner_->RunsTasksInCurrentSequence()); - bool should_clear = !IsEmpty(); - if (should_clear) - DeleteAndRecreateDatabaseFile(); - if (completion) { - main_task_runner_->PostTask( - FROM_HERE, base::BindOnce(std::move(completion), should_clear)); - } -} - std::vector<std::unique_ptr<PasswordForm>> PasswordStore::GetLoginsImpl( const PasswordFormDigest& form) { DCHECK(background_task_runner_->RunsTasksInCurrentSequence());
diff --git a/components/password_manager/core/browser/password_store.h b/components/password_manager/core/browser/password_store.h index 98c5c01..dfec5c7 100644 --- a/components/password_manager/core/browser/password_store.h +++ b/components/password_manager/core/browser/password_store.h
@@ -60,7 +60,7 @@ // TODO(crbug.com/1217071): Move PasswordStoreSync to local backend. class PasswordStore : protected PasswordStoreSync, public PasswordStoreInterface, - public SmartBubbleStatsStore { + protected SmartBubbleStatsStore { public: // Used to notify that unsynced credentials are about to be deleted. class UnsyncedCredentialsDeletionNotifier { @@ -108,9 +108,10 @@ base::OnceClosure completion, base::OnceCallback<void(bool)> sync_completion = base::NullCallback()) override; - void RemoveLoginsCreatedBetween(base::Time delete_begin, - base::Time delete_end, - base::OnceClosure completion) override; + void RemoveLoginsCreatedBetween( + base::Time delete_begin, + base::Time delete_end, + base::OnceCallback<void(bool)> completion) override; void DisableAutoSignInForOrigins( const base::RepeatingCallback<bool(const GURL&)>& origin_filter, base::OnceClosure completion) override; @@ -128,16 +129,6 @@ void RemoveObserver(Observer* observer) override; SmartBubbleStatsStore* GetSmartBubbleStatsStore() override; - // SmartBubbleStatsStore: - void AddSiteStats(const InteractionsStats& stats) override; - void RemoveSiteStats(const GURL& origin_domain) override; - void GetSiteStats(const GURL& origin_domain, - PasswordStoreConsumer* consumer) override; - void RemoveStatisticsByOriginAndTime( - const base::RepeatingCallback<bool(const GURL&)>& origin_filter, - base::Time delete_begin, - base::Time delete_end, - base::OnceClosure completion) override; // Reports usage metrics for the database. |sync_username|, and // |custom_passphrase_sync_enabled|, and |is_under_advanced_protection| @@ -182,12 +173,6 @@ base::Time remove_end, base::OnceClosure completion); - // Deletes and re-creates the whole PasswordStore, unless it is already empty - // anyway. If |completion| is not null, it will be posted to the - // |main_task_runner_| once the process is complete. The bool parameter - // indicates whether any data was actually cleared. - void ClearStore(base::OnceCallback<void(bool)> completion); - // Schedules the given |task| to be run on the PasswordStore's TaskRunner. bool ScheduleTask(base::OnceClosure task); @@ -197,10 +182,9 @@ CreateSyncControllerDelegate(); // Sets |deletion_notifier_|. Must not pass a nullptr. - void SetUnsyncedCredentialsDeletionNotifier( - std::unique_ptr<UnsyncedCredentialsDeletionNotifier> deletion_notifier); - - void SetSyncTaskTimeoutForTest(base::TimeDelta timeout); + virtual void SetUnsyncedCredentialsDeletionNotifier( + std::unique_ptr<UnsyncedCredentialsDeletionNotifier> + deletion_notifier) = 0; protected: using LoginsTask = base::OnceCallback<LoginsResult()>; @@ -224,6 +208,17 @@ ~PasswordStore() override; + // SmartBubbleStatsStore: + void AddSiteStats(const InteractionsStats& stats) override; + void RemoveSiteStats(const GURL& origin_domain) override; + void GetSiteStats(const GURL& origin_domain, + PasswordStoreConsumer* consumer) override; + void RemoveStatisticsByOriginAndTime( + const base::RepeatingCallback<bool(const GURL&)>& origin_filter, + base::Time delete_begin, + base::Time delete_end, + base::OnceClosure completion) override; + // Create a TaskRunner to be saved in |background_task_runner_|. virtual scoped_refptr<base::SequencedTaskRunner> CreateBackgroundTaskRunner() const; @@ -322,11 +317,6 @@ // been changed. void NotifyLoginsChanged(const PasswordStoreChangeList& changes) override; - void NotifyDeletionsHaveSynced(bool success) override; - - void NotifyUnsyncedCredentialsWillBeDeleted( - std::vector<PasswordForm> unsynced_credentials) override; - // Invokes callback and notifies observers if there was a change to the list // of insecure passwords. It also informs Sync about the updated password // forms to sync up the changes about insecure credentials. @@ -396,15 +386,10 @@ void RemoveLoginInternal(const PasswordForm& form); void UpdateLoginWithPrimaryKeyInternal(const PasswordForm& new_form, const PasswordForm& old_primary_key); - void RemoveLoginsByURLAndTimeInternal( - const base::RepeatingCallback<bool(const GURL&)>& url_filter, + void RemoveLoginsCreatedBetweenInternal( base::Time delete_begin, base::Time delete_end, - base::OnceClosure completion, - base::OnceCallback<void(bool)> sync_completion); - void RemoveLoginsCreatedBetweenInternal(base::Time delete_begin, - base::Time delete_end, - base::OnceClosure completion); + base::OnceCallback<void(bool)> completion); void RemoveStatisticsByOriginAndTimeInternal( const base::RepeatingCallback<bool(const GURL&)>& origin_filter, base::Time delete_begin, @@ -425,8 +410,6 @@ base::Time remove_end, base::OnceClosure completion); - void ClearStoreInternal(base::OnceCallback<void(bool)> completion); - // Finds all PasswordForms with a signon_realm that is equal to, or is a // PSL-match to that of |form|, and takes care of notifying the consumer with // the results when done. @@ -504,22 +487,10 @@ PrefService* prefs_ = nullptr; - std::unique_ptr<UnsyncedCredentialsDeletionNotifier> deletion_notifier_; - - // A list of callbacks that should be run once all pending deletions have been - // sent to the Sync server. Note that the vector itself lives on the - // background thread, but the callbacks must be run on the main thread! - std::vector<base::OnceCallback<void(bool)>> deletions_have_synced_callbacks_; - // Timeout closure that runs if sync takes too long to propagate deletions. - base::CancelableOnceClosure deletions_have_synced_timeout_; - bool shutdown_called_ = false; InitStatus init_status_ = InitStatus::kUnknown; - // This is usually constant, only changed in tests. - base::TimeDelta sync_task_timeout_ = base::TimeDelta::FromSeconds(30); - DISALLOW_COPY_AND_ASSIGN(PasswordStore); };
diff --git a/components/password_manager/core/browser/password_store_backend.h b/components/password_manager/core/browser/password_store_backend.h index 349d3336..2a41ddbb 100644 --- a/components/password_manager/core/browser/password_store_backend.h +++ b/components/password_manager/core/browser/password_store_backend.h
@@ -77,7 +77,9 @@ OptionalStoreChangeListReply callback, const base::RepeatingCallback<bool(const GURL&)>& url_filter, base::Time delete_begin, - base::Time delete_end) {} + base::Time delete_end, + base::OnceClosure completion, + base::OnceCallback<void(bool)> sync_completion) = 0; virtual void RemoveLoginsCreatedBetweenAsync( OptionalStoreChangeListReply callback, base::Time delete_begin,
diff --git a/components/password_manager/core/browser/password_store_impl.cc b/components/password_manager/core/browser/password_store_impl.cc index 55ecfcf..f2a79d11 100644 --- a/components/password_manager/core/browser/password_store_impl.cc +++ b/components/password_manager/core/browser/password_store_impl.cc
@@ -19,6 +19,8 @@ namespace { +constexpr base::TimeDelta kSyncTaskTimeout = base::TimeDelta::FromSeconds(30); + // Generates PasswordStoreChangeList for affected forms during // InsecureCredentials update. PasswordStoreChangeList BuildPasswordChangeListForInsecureCredentialsUpdate( @@ -47,6 +49,14 @@ base::BindOnce(&PasswordStoreImpl::DestroyOnBackgroundSequence, this)); } +void PasswordStoreImpl::SetUnsyncedCredentialsDeletionNotifier( + std::unique_ptr<PasswordStore::UnsyncedCredentialsDeletionNotifier> + notifier) { + DCHECK(!deletion_notifier_); + DCHECK(notifier); + deletion_notifier_ = std::move(notifier); +} + void PasswordStoreImpl::ReportMetricsImpl(const std::string& sync_username, bool custom_passphrase_sync_enabled, BulkCheckDone bulk_check_done) { @@ -343,6 +353,35 @@ sync_bridge_->ActOnPasswordStoreChanges(changes); } +void PasswordStoreImpl::NotifyDeletionsHaveSynced(bool success) { + DCHECK(background_task_runner()->RunsTasksInCurrentSequence()); + // Either all deletions have been committed to the Sync server, or Sync is + // telling us that it won't commit them (because Sync was turned off + // permanently). In either case, run the corresponding callbacks now (on the + // main task runner). + DCHECK(!success || !GetMetadataStore()->HasUnsyncedDeletions()); + for (auto& callback : deletions_have_synced_callbacks_) { + main_task_runner()->PostTask(FROM_HERE, + base::BindOnce(std::move(callback), success)); + } + deletions_have_synced_timeout_.Cancel(); + deletions_have_synced_callbacks_.clear(); +} + +void PasswordStoreImpl::NotifyUnsyncedCredentialsWillBeDeleted( + std::vector<PasswordForm> unsynced_credentials) { + DCHECK(background_task_runner()->RunsTasksInCurrentSequence()); + DCHECK(IsAccountStore()); + // |deletion_notifier_| only gets set for desktop. + if (deletion_notifier_) { + main_task_runner()->PostTask( + FROM_HERE, + base::BindOnce( + &PasswordStoreImpl::UnsyncedCredentialsDeletionNotifier::Notify, + deletion_notifier_->GetWeakPtr(), std::move(unsynced_credentials))); + } +} + bool PasswordStoreImpl::BeginTransaction() { if (login_db_) return login_db_->BeginTransaction(); @@ -459,6 +498,23 @@ std::move(callback)); } +void PasswordStoreImpl::RemoveLoginsByURLAndTimeAsync( + OptionalStoreChangeListReply callback, + const base::RepeatingCallback<bool(const GURL&)>& url_filter, + base::Time delete_begin, + base::Time delete_end, + base::OnceClosure completion, + base::OnceCallback<void(bool)> sync_completion) { + // TODO(crbug.com/1226042): Use PostTaskAndReplyWithResult instead of + // PostTask. + background_task_runner()->PostTask( + FROM_HERE, + base::BindOnce( + IgnoreResult(&PasswordStoreImpl::RemoveLoginsByURLAndTimeInternal), + this, url_filter, delete_begin, delete_end, std::move(completion), + std::move(sync_completion))); +} + bool PasswordStoreImpl::InitOnBackgroundSequence( base::RepeatingClosure sync_enabled_or_disabled_cb) { DCHECK(background_task_runner()->RunsTasksInCurrentSequence()); @@ -573,4 +629,40 @@ return changes; } +PasswordStoreChangeList PasswordStoreImpl::RemoveLoginsByURLAndTimeInternal( + const base::RepeatingCallback<bool(const GURL&)>& url_filter, + base::Time delete_begin, + base::Time delete_end, + base::OnceClosure completion, + base::OnceCallback<void(bool)> sync_completion) { + BeginTransaction(); + PasswordStoreChangeList changes = + RemoveLoginsByURLAndTimeImpl(url_filter, delete_begin, delete_end); + NotifyLoginsChanged(changes); + // Sync metadata get updated in NotifyLoginsChanged(). Therefore, + // CommitTransaction() must be called after NotifyLoginsChanged(), because + // sync codebase needs to update metadata atomically together with the login + // data. + CommitTransaction(); + + if (completion) + main_task_runner()->PostTask(FROM_HERE, std::move(completion)); + + if (sync_completion) { + deletions_have_synced_callbacks_.push_back(std::move(sync_completion)); + // Start a timeout for sync, or restart it if it was already running. + deletions_have_synced_timeout_.Reset( + base::BindOnce(&PasswordStoreImpl::NotifyDeletionsHaveSynced, this, + /*success=*/false)); + background_task_runner()->PostDelayedTask( + FROM_HERE, deletions_have_synced_timeout_.callback(), kSyncTaskTimeout); + + // Do an immediate check for the case where there are already no unsynced + // deletions. + if (!GetMetadataStore()->HasUnsyncedDeletions()) + NotifyDeletionsHaveSynced(/*success=*/true); + } + return changes; +} + } // namespace password_manager
diff --git a/components/password_manager/core/browser/password_store_impl.h b/components/password_manager/core/browser/password_store_impl.h index 65c19d4..4d52f00 100644 --- a/components/password_manager/core/browser/password_store_impl.h +++ b/components/password_manager/core/browser/password_store_impl.h
@@ -37,6 +37,9 @@ ~PasswordStoreImpl() override; // Implements PasswordStore interface. + void SetUnsyncedCredentialsDeletionNotifier( + std::unique_ptr<UnsyncedCredentialsDeletionNotifier> deletion_notifier) + override; void ReportMetricsImpl(const std::string& sync_username, bool custom_passphrase_sync_enabled, BulkCheckDone bulk_check_done) override; @@ -98,6 +101,9 @@ base::span<const InsecureCredential> credentials) override; PasswordStoreChangeList RemoveLoginSync(const PasswordForm& form) override; void NotifyLoginsChanged(const PasswordStoreChangeList& changes) override; + void NotifyDeletionsHaveSynced(bool success) override; + void NotifyUnsyncedCredentialsWillBeDeleted( + std::vector<PasswordForm> unsynced_credentials) override; bool BeginTransaction() override; void RollbackTransaction() override; bool CommitTransaction() override; @@ -131,6 +137,13 @@ const PasswordForm& form) override; void RemoveLoginAsync(OptionalStoreChangeListReply callback, const PasswordForm& form) override; + void RemoveLoginsByURLAndTimeAsync( + OptionalStoreChangeListReply callback, + const base::RepeatingCallback<bool(const GURL&)>& url_filter, + base::Time delete_begin, + base::Time delete_end, + base::OnceClosure completion, + base::OnceCallback<void(bool)> sync_completion) override; // Opens |login_db_| and creates |sync_bridge_| on the background sequence. bool InitOnBackgroundSequence( @@ -152,6 +165,12 @@ PasswordStoreChangeList AddLoginInternal(const PasswordForm& form); PasswordStoreChangeList UpdateLoginInternal(const PasswordForm& form); PasswordStoreChangeList RemoveLoginInternal(const PasswordForm& form); + PasswordStoreChangeList RemoveLoginsByURLAndTimeInternal( + const base::RepeatingCallback<bool(const GURL&)>& url_filter, + base::Time delete_begin, + base::Time delete_end, + base::OnceClosure completion, + base::OnceCallback<void(bool)> sync_completion); // The login SQL database. The LoginDatabase instance is received via the // in an uninitialized state, so as to allow injecting mocks, then Init() is @@ -161,6 +180,15 @@ std::unique_ptr<PasswordSyncBridge> sync_bridge_; + std::unique_ptr<UnsyncedCredentialsDeletionNotifier> deletion_notifier_; + + // A list of callbacks that should be run once all pending deletions have been + // sent to the Sync server. Note that the vector itself lives on the + // background thread, but the callbacks must be run on the main thread! + std::vector<base::OnceCallback<void(bool)>> deletions_have_synced_callbacks_; + // Timeout closure that runs if sync takes too long to propagate deletions. + base::CancelableOnceClosure deletions_have_synced_timeout_; + DISALLOW_COPY_AND_ASSIGN(PasswordStoreImpl); };
diff --git a/components/password_manager/core/browser/password_store_interface.h b/components/password_manager/core/browser/password_store_interface.h index 20146da9..d0e8808 100644 --- a/components/password_manager/core/browser/password_store_interface.h +++ b/components/password_manager/core/browser/password_store_interface.h
@@ -91,10 +91,12 @@ // Removes all logins created in the given date range. If `completion` is not // null, it will be run after deletions have been completed and notification - // have been sent out. - virtual void RemoveLoginsCreatedBetween(base::Time delete_begin, - base::Time delete_end, - base::OnceClosure completion) = 0; + // have been sent out. If any logins were removed 'true' will be passed to a + // completion, 'false' otherwise. + virtual void RemoveLoginsCreatedBetween( + base::Time delete_begin, + base::Time delete_end, + base::OnceCallback<void(bool)> completion) = 0; // Sets the 'skip_zero_click' flag for all credentials that match // `origin_filter`. `completion` will be run after these modifications are
diff --git a/components/password_manager/core/browser/password_store_unittest.cc b/components/password_manager/core/browser/password_store_unittest.cc index 1428129..c6038c8 100644 --- a/components/password_manager/core/browser/password_store_unittest.cc +++ b/components/password_manager/core/browser/password_store_unittest.cc
@@ -14,6 +14,7 @@ #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "base/synchronization/waitable_event.h" +#include "base/test/bind.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" @@ -346,9 +347,9 @@ EXPECT_CALL(mock_observer, OnLoginsChanged(_, testing::SizeIs(1u))); base::RunLoop run_loop; - store->RemoveLoginsCreatedBetween(base::Time::FromDoubleT(0), - base::Time::FromDoubleT(2), - run_loop.QuitClosure()); + store->RemoveLoginsCreatedBetween( + base::Time::FromDoubleT(0), base::Time::FromDoubleT(2), + base::BindLambdaForTesting([&run_loop](bool) { run_loop.Quit(); })); run_loop.Run(); testing::Mock::VerifyAndClearExpectations(&mock_observer); @@ -384,9 +385,9 @@ MockInsecureCredentialsConsumer consumer; base::RunLoop run_loop; - store->RemoveLoginsCreatedBetween(base::Time::FromDoubleT(0), - base::Time::FromDoubleT(2), - run_loop.QuitClosure()); + store->RemoveLoginsCreatedBetween( + base::Time::FromDoubleT(0), base::Time::FromDoubleT(2), + base::BindLambdaForTesting([&run_loop](bool) { run_loop.Quit(); })); run_loop.Run(); EXPECT_CALL(consumer, OnGetInsecureCredentials(testing::IsEmpty()));
diff --git a/components/password_manager/core/browser/sync/password_model_type_controller.cc b/components/password_manager/core/browser/sync/password_model_type_controller.cc index 099e571a..64b47bfb 100644 --- a/components/password_manager/core/browser/sync/password_model_type_controller.cc +++ b/components/password_manager/core/browser/sync/password_model_type_controller.cc
@@ -210,7 +210,8 @@ if (features_util::IsOptedInForAccountStorage(pref_service_, sync_service_)) { RecordClearedOnStartup(ClearedOnStartup::kOptedInSoNoNeedToClear); } else { - account_password_store_for_cleanup->ClearStore( + account_password_store_for_cleanup->RemoveLoginsCreatedBetween( + base::Time(), base::Time::Max(), base::BindOnce(&PasswordStoreClearDone)); } }
diff --git a/components/password_manager/core/browser/test_password_store.cc b/components/password_manager/core/browser/test_password_store.cc index 094b803..22ec549 100644 --- a/components/password_manager/core/browser/test_password_store.cc +++ b/components/password_manager/core/browser/test_password_store.cc
@@ -210,6 +210,16 @@ std::move(callback)); } +void TestPasswordStore::RemoveLoginsByURLAndTimeAsync( + OptionalStoreChangeListReply callback, + const base::RepeatingCallback<bool(const GURL&)>& url_filter, + base::Time delete_begin, + base::Time delete_end, + base::OnceClosure completion, + base::OnceCallback<void(bool)> sync_completion) { + NOTIMPLEMENTED(); +} + PasswordStoreChangeList TestPasswordStore::AddLoginImpl( const PasswordForm& form, AddLoginError* error) { @@ -447,6 +457,11 @@ NOTIMPLEMENTED(); } +void TestPasswordStore::SetUnsyncedCredentialsDeletionNotifier( + std::unique_ptr<UnsyncedCredentialsDeletionNotifier> deletion_notifier) { + NOTIMPLEMENTED(); +} + PasswordStoreChangeList TestPasswordStore::AddLoginSync( const PasswordForm& form, AddLoginError* error) { @@ -480,6 +495,15 @@ return {}; } +void TestPasswordStore::NotifyDeletionsHaveSynced(bool success) { + NOTIMPLEMENTED(); +} + +void TestPasswordStore::NotifyUnsyncedCredentialsWillBeDeleted( + std::vector<PasswordForm> unsynced_credentials) { + NOTIMPLEMENTED(); +} + bool TestPasswordStore::BeginTransaction() { return true; }
diff --git a/components/password_manager/core/browser/test_password_store.h b/components/password_manager/core/browser/test_password_store.h index 5a44298..2b73922 100644 --- a/components/password_manager/core/browser/test_password_store.h +++ b/components/password_manager/core/browser/test_password_store.h
@@ -96,6 +96,13 @@ const PasswordForm& form) override; void RemoveLoginAsync(OptionalStoreChangeListReply callback, const PasswordForm& form) override; + void RemoveLoginsByURLAndTimeAsync( + OptionalStoreChangeListReply callback, + const base::RepeatingCallback<bool(const GURL&)>& url_filter, + base::Time delete_begin, + base::Time delete_end, + base::OnceClosure completion, + base::OnceCallback<void(bool)> sync_completion) override; // PasswordStore interface PasswordStoreChangeList AddLoginImpl(const PasswordForm& form, AddLoginError* error) override; @@ -142,7 +149,9 @@ std::vector<FieldInfo> GetAllFieldInfoImpl() override; void RemoveFieldInfoByTimeImpl(base::Time remove_begin, base::Time remove_end) override; - + void SetUnsyncedCredentialsDeletionNotifier( + std::unique_ptr<UnsyncedCredentialsDeletionNotifier> deletion_notifier) + override; // PasswordStoreSync interface. // TODO(crbug.bom/1226042): Remove this after PasswordStore no longer // inherits PasswordStoreSync. @@ -156,6 +165,9 @@ const PasswordForm& form, base::span<const InsecureCredential> credentials) override; PasswordStoreChangeList RemoveLoginSync(const PasswordForm& form) override; + void NotifyDeletionsHaveSynced(bool success) override; + void NotifyUnsyncedCredentialsWillBeDeleted( + std::vector<PasswordForm> unsynced_credentials) override; bool BeginTransaction() override; void RollbackTransaction() override; bool CommitTransaction() override;
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index 6f53c3bf..5527550 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -15083,35 +15083,25 @@ For detailed information on valid input patterns, please see https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns. <ph name="WILDCARD_VALUE">*</ph> is not an accepted value for this policy. This policy only matches based on origin, so any path in the URL pattern is ignored.''', }, { - 'name': 'ManagedWebAppsAccessToDeviceAttributesAllowed', + 'name': 'DeviceAttributesAllowedForOrigins', 'owners': ['file://components/policy/resources/OWNERS', 'anqing@chromium.org'], - 'type': 'main', - 'schema': { 'type': 'boolean' }, + 'type': 'list', + 'schema': { + 'type': 'array', + 'items': { 'type': 'string' }, + }, 'supported_on': ['chrome_os:93-'], 'features': { 'dynamic_refresh': True, 'per_profile': True, }, - 'items': [ - { - 'value': True, - 'caption': 'Allow force-installed web applications to query for device attributes.', - }, - { - 'value': False, - 'caption': 'Prevent force-installed web applications from querying for device attributes.', - }, - ], - 'example_value': True, - 'default': True, + 'example_value': ['https://www.google.com', 'https://www.example.com'], 'id': 865, - 'caption': '''Allow force-installed web applications to query for device attributes.''', + 'caption': '''Allow origins to query for device attributes''', 'tags': [], - 'desc': '''Setting the policy to allow force-installed web applications to get device attributes (e.g. serial number, hostname) by using Device Attributes web API. + 'desc': '''Setting the policy to allow some origins of force-installed web applications to get device attributes (e.g. serial number, hostname) by using Device Attributes API. - If this policy is set to true or not configured, the Device Attributes web API will be allowed to force-installed web applications. - - If this policy is set to false, the Device Attributes web API will be disallowed.''', + Device Attributes API is a list of web APIs, please see https://wicg.github.io/WebApiDevice/device_attributes. They are only available to origins which correspond to force-installed web applications via <ph name="WEB_APP_INSTALL_FORCE_LIST_POLICY_NAME">WebAppInstallForceList</ph> or the one configured in the Kiosk session.''' }, { 'name': 'QuicAllowed', @@ -20820,7 +20810,7 @@ 'caption': '''Default behavior for LBS.''', }, { - 'name': 'Strict', + 'name': 'IESiteListMode', 'value': 1, 'caption': '''More compatible with Microsoft IE/Edge enterprise mode sitelists.''', }, @@ -20836,15 +20826,17 @@ 'tags': [], 'desc': '''This policy controls how <ph name="PRODUCT_NAME">Google Chrome</ph> interprets sitelist/greylist policies for the Legacy Browser Support feature. It affects the following policies: <ph name="URL_LIST_POLICY_NAME">BrowserSwitcherUrlList</ph>, <ph name="URL_GREYLIST_POLICY_NAME">BrowserSwitcherUrlGreylist</ph>, <ph name="USE_IE_SITELIST_POLICY_NAME">BrowserSwitcherUseIeSitelist</ph>, <ph name="EXTERNAL_SITELIST_POLICY_NAME">BrowserSwitcherExternalSitelistUrl</ph>, and <ph name="EXTERNAL_GREYLIST_POLICY_NAME">BrowserSwitcherExternalGreylistUrl</ph>. - If 'Default' (0) or unset, URL matching is less strict. Rules that do not contain "/" look for a substring anywhere in the URL's hostname. + If 'Default' (0) or unset, URL matching is less strict. Rules that do not contain "/" look for a substring anywhere in the URL's hostname. Matching the path component of a URL is case-sensitive. - If 'Strict' (1), URL matching is more strict. Rules that do not contain "/" only match at the end of the hostname. They must also be at a domain name boundary. This is more compatible with <ph name="MS_IE_PRODUCT_NAME">Microsoft® Internet Explorer®</ph> and <ph name="MS_EDGE_PRODUCT_NAME">Microsoft® Edge®</ph>. + If 'IESiteListMode' (1), URL matching is more strict. Rules that do not contain "/" only match at the end of the hostname. They must also be at a domain name boundary. Matching the path component of a URL is case-insensitive. This is more compatible with <ph name="MS_IE_PRODUCT_NAME">Microsoft® Internet Explorer®</ph> and <ph name="MS_EDGE_PRODUCT_NAME">Microsoft® Edge®</ph>. - For example, with the rule "example.com": + For example, with the rules "example.com" and "acme.com/abc": - "http://example.com/" and "http://subdomain.example.com/" match regardless of parsing mode. + "http://example.com/", "http://subdomain.example.com/" and "http://acme.com/abc" match regardless of parsing mode. - "http://notexample.com/", "http://example.com.invalid.com/" and "http://example.comabc/" only match in 'Default' mode.''', + "http://notexample.com/", "http://example.com.invalid.com/", "http://example.comabc/" only match in 'Default' mode. + + "http://acme.com/ABC" only matches in 'IESiteListMode'.''', }, { 'id': 519,
diff --git a/components/previous_session_info/previous_session_info.h b/components/previous_session_info/previous_session_info.h index 47a78a2..d39326102 100644 --- a/components/previous_session_info/previous_session_info.h +++ b/components/previous_session_info/previous_session_info.h
@@ -11,6 +11,10 @@ #include "url/gurl.h" +namespace base { +class TimeDelta; +} + namespace previous_session_info_constants { // - The (Integer) representing UIApplicationState. extern NSString* const kPreviousSessionInfoApplicationState;
diff --git a/components/previous_session_info/previous_session_info.mm b/components/previous_session_info/previous_session_info.mm index 6f3ef6a..fab250bb 100644 --- a/components/previous_session_info/previous_session_info.mm +++ b/components/previous_session_info/previous_session_info.mm
@@ -11,6 +11,7 @@ #include "base/ios/ios_util.h" #include "base/strings/sys_string_conversions.h" #include "base/system/sys_info.h" +#include "base/time/time.h" #include "base/timer/timer.h" #import "components/previous_session_info/previous_session_info_private.h" #include "components/version_info/version_info.h"
diff --git a/components/safe_browsing/content/browser/base_blocking_page.h b/components/safe_browsing/content/browser/base_blocking_page.h index 2129e3d..1f820c97 100644 --- a/components/safe_browsing/content/browser/base_blocking_page.h +++ b/components/safe_browsing/content/browser/base_blocking_page.h
@@ -49,6 +49,10 @@ // Checks the threat type to decide if we should report ThreatDetails. static bool ShouldReportThreatDetails(SBThreatType threat_type); + // Populates the report details for |unsafe_resources|. + static security_interstitials::MetricsHelper::ReportDetails GetReportingInfo( + const UnsafeResourceList& unsafe_resources); + protected: // Don't instantiate this class directly, use ShowBlockingPage instead. BaseBlockingPage( @@ -102,9 +106,6 @@ void set_proceeded(bool proceeded); - static security_interstitials::MetricsHelper::ReportDetails GetReportingInfo( - const UnsafeResourceList& unsafe_resources); - void SetThreatDetailsProceedDelayForTesting(int64_t delay); static std::unique_ptr<
diff --git a/components/shared_highlighting/core/common/disabled_sites.cc b/components/shared_highlighting/core/common/disabled_sites.cc index bb1d2944..dcc278656 100644 --- a/components/shared_highlighting/core/common/disabled_sites.cc +++ b/components/shared_highlighting/core/common/disabled_sites.cc
@@ -39,6 +39,11 @@ domain = domain.substr(7); } + if (base::FeatureList::IsEnabled(kSharedHighlightingAmp) && + domain.compare("google.com") == 0) { + return true; + } + auto* it = kBlocklist.find(domain); if (it != kBlocklist.end()) { return !re2::RE2::FullMatch(url.path(), it->second.data());
diff --git a/components/shared_highlighting/core/common/disabled_sites_unittest.cc b/components/shared_highlighting/core/common/disabled_sites_unittest.cc index 9cd99242..8833025 100644 --- a/components/shared_highlighting/core/common/disabled_sites_unittest.cc +++ b/components/shared_highlighting/core/common/disabled_sites_unittest.cc
@@ -22,6 +22,9 @@ } TEST(DisabledSitesTest, SpecificPages) { + base::test::ScopedFeatureList feature; + feature.InitAndDisableFeature(kSharedHighlightingAmp); + // Paths starting with /amp/ are disabled. EXPECT_FALSE(ShouldOfferLinkToText(GURL("https://www.google.com/amp/"))); EXPECT_FALSE(ShouldOfferLinkToText(GURL("https://www.google.com/amp/foo"))); @@ -47,10 +50,21 @@ base::test::ScopedFeatureList feature; feature.InitAndDisableFeature(kSharedHighlightingUseBlocklist); - EXPECT_TRUE(ShouldOfferLinkToText(GURL("https://www.youtube.com"))); EXPECT_TRUE(ShouldOfferLinkToText(GURL("https://www.google.com/amp/"))); + EXPECT_TRUE(ShouldOfferLinkToText(GURL("https://www.youtube.com"))); EXPECT_TRUE(ShouldOfferLinkToText(GURL("https://www.example.com"))); } +TEST(DisabledSitesTest, AmpFeatureEnabled) { + base::test::ScopedFeatureList feature; + feature.InitWithFeatures( + {kSharedHighlightingUseBlocklist, kSharedHighlightingAmp}, {}); + + EXPECT_TRUE(ShouldOfferLinkToText(GURL("https://www.google.com/amp/"))); + EXPECT_TRUE(ShouldOfferLinkToText(GURL("https://www.google.com/amp/foo"))); + EXPECT_TRUE(ShouldOfferLinkToText(GURL("https://google.com/amp/"))); + EXPECT_TRUE(ShouldOfferLinkToText(GURL("https://google.com/amp/foo"))); +} + } // namespace } // namespace shared_highlighting
diff --git a/components/site_engagement/content/site_engagement_score.cc b/components/site_engagement/content/site_engagement_score.cc index fb9c170d..4440733 100644 --- a/components/site_engagement/content/site_engagement_score.cc +++ b/components/site_engagement/content/site_engagement_score.cc
@@ -321,17 +321,14 @@ } bool SiteEngagementScore::UpdateScoreDict(base::DictionaryValue* score_dict) { - double raw_score_orig = 0; - double points_added_today_orig = 0; - double last_engagement_time_internal_orig = 0; - double last_shortcut_launch_time_internal_orig = 0; + double raw_score_orig = score_dict->FindDoubleKey(kRawScoreKey).value_or(0); + double points_added_today_orig = + score_dict->FindDoubleKey(kPointsAddedTodayKey).value_or(0); + double last_engagement_time_internal_orig = + score_dict->FindDoubleKey(kLastEngagementTimeKey).value_or(0); + double last_shortcut_launch_time_internal_orig = + score_dict->FindDoubleKey(kLastShortcutLaunchTimeKey).value_or(0); - score_dict->GetDouble(kRawScoreKey, &raw_score_orig); - score_dict->GetDouble(kPointsAddedTodayKey, &points_added_today_orig); - score_dict->GetDouble(kLastEngagementTimeKey, - &last_engagement_time_internal_orig); - score_dict->GetDouble(kLastShortcutLaunchTimeKey, - &last_shortcut_launch_time_internal_orig); bool changed = DoublesConsideredDifferent(raw_score_orig, raw_score_, kScoreDelta) || DoublesConsideredDifferent(points_added_today_orig, points_added_today_, @@ -371,14 +368,21 @@ if (!score_dict_) return; - score_dict_->GetDouble(kRawScoreKey, &raw_score_); - score_dict_->GetDouble(kPointsAddedTodayKey, &points_added_today_); + raw_score_ = score_dict_->FindDoubleKey(kRawScoreKey).value_or(0); + points_added_today_ = + score_dict_->FindDoubleKey(kPointsAddedTodayKey).value_or(0); - double internal_time; - if (score_dict_->GetDouble(kLastEngagementTimeKey, &internal_time)) - last_engagement_time_ = base::Time::FromInternalValue(internal_time); - if (score_dict_->GetDouble(kLastShortcutLaunchTimeKey, &internal_time)) - last_shortcut_launch_time_ = base::Time::FromInternalValue(internal_time); + absl::optional<double> maybe_last_engagement_time = + score_dict_->FindDoubleKey(kLastEngagementTimeKey); + if (maybe_last_engagement_time.has_value()) + last_engagement_time_ = + base::Time::FromInternalValue(maybe_last_engagement_time.value()); + + absl::optional<double> maybe_last_shortcut_launch_time = + score_dict_->FindDoubleKey(kLastShortcutLaunchTimeKey); + if (maybe_last_shortcut_launch_time.has_value()) + last_shortcut_launch_time_ = + base::Time::FromInternalValue(maybe_last_shortcut_launch_time.value()); } double SiteEngagementScore::DecayedScore() const {
diff --git a/components/sync/driver/glue/sync_engine_impl.cc b/components/sync/driver/glue/sync_engine_impl.cc index dfa96bb..8b6ef2c 100644 --- a/components/sync/driver/glue/sync_engine_impl.cc +++ b/components/sync/driver/glue/sync_engine_impl.cc
@@ -8,6 +8,7 @@ #include "base/base64.h" #include "base/bind.h" +#include "base/callback_forward.h" #include "base/callback_helpers.h" #include "base/command_line.h" #include "base/feature_list.h"
diff --git a/components/sync/driver/sync_service_impl.cc b/components/sync/driver/sync_service_impl.cc index 6bfcba51..a7d8b3c52 100644 --- a/components/sync/driver/sync_service_impl.cc +++ b/components/sync/driver/sync_service_impl.cc
@@ -36,6 +36,7 @@ #include "components/sync/driver/sync_auth_manager.h" #include "components/sync/driver/sync_driver_switches.h" #include "components/sync/driver/sync_type_preference_provider.h" +#include "components/sync/engine/configure_reason.h" #include "components/sync/engine/engine_components_factory_impl.h" #include "components/sync/engine/net/http_bridge.h" #include "components/sync/engine/net/http_post_provider_factory.h" @@ -221,6 +222,13 @@ sync_client_->GetSyncInvalidationsService(); if (sync_invalidations_service) { sync_invalidations_service->SetActive(IsSignedIn()); + // Trigger a refresh when additional data types get enabled for + // invalidations. This is needed to get the latest data after subscribing + // for the updates. + sync_invalidations_service + ->SetCommittedAdditionalInterestedDataTypesCallback( + base::BindRepeating(&SyncServiceImpl::TriggerRefresh, + weak_factory_.GetWeakPtr())); } } @@ -1282,9 +1290,7 @@ switches::kUseSyncInvalidationsForWalletAndOffer))) { types.RemoveAll({AUTOFILL_WALLET_DATA, AUTOFILL_WALLET_OFFER}); } - invalidations_service->SetInterestedDataTypes( - types, base::BindRepeating(&SyncServiceImpl::TriggerRefresh, - sync_enabled_weak_factory_.GetWeakPtr())); + invalidations_service->SetInterestedDataTypes(types); } SyncCycleSnapshot SyncServiceImpl::GetLastCycleSnapshotForDebugging() const {
diff --git a/components/sync/driver/sync_service_impl_unittest.cc b/components/sync/driver/sync_service_impl_unittest.cc index 335d7363..279dddf 100644 --- a/components/sync/driver/sync_service_impl_unittest.cc +++ b/components/sync/driver/sync_service_impl_unittest.cc
@@ -1182,10 +1182,10 @@ InitializeForNthSync(); EXPECT_CALL(*sync_invalidations_service(), - SetInterestedDataTypes(ContainsSessions(), _)); + SetInterestedDataTypes(ContainsSessions())); service()->SetInvalidationsForSessionsEnabled(true); EXPECT_CALL(*sync_invalidations_service(), - SetInterestedDataTypes(Not(ContainsSessions()), _)); + SetInterestedDataTypes(Not(ContainsSessions()))); service()->SetInvalidationsForSessionsEnabled(false); }
diff --git a/components/sync/driver/sync_service_utils.cc b/components/sync/driver/sync_service_utils.cc index 324e6903..bd1f2d86 100644 --- a/components/sync/driver/sync_service_utils.cc +++ b/components/sync/driver/sync_service_utils.cc
@@ -96,6 +96,14 @@ return false; } + const ModelTypeSet encrypted_types = + service->GetUserSettings()->GetEncryptedDataTypes(); + if (Intersection(service->GetActiveDataTypes(), encrypted_types).Empty()) { + // No point in offering the user a new encryption method if they are not + // syncing any encrypted types. + return false; + } + switch (service->GetUserSettings()->GetPassphraseType()) { case PassphraseType::kImplicitPassphrase: case PassphraseType::kFrozenImplicitPassphrase:
diff --git a/components/sync/engine/cycle/data_type_tracker.cc b/components/sync/engine/cycle/data_type_tracker.cc index 57cc7189..e27fc27 100644 --- a/components/sync/engine/cycle/data_type_tracker.cc +++ b/components/sync/engine/cycle/data_type_tracker.cc
@@ -25,6 +25,9 @@ base::TimeDelta::FromMilliseconds(2000); constexpr base::TimeDelta kVeryBigLocalChangeNudgeDelay = kDefaultPollInterval; +constexpr base::TimeDelta kDefaultLocalChangeNudgeDelayForSessions = + base::TimeDelta::FromSeconds(11); + const size_t kDefaultMaxPayloadsPerType = 10; base::TimeDelta GetDefaultLocalChangeNudgeDelay(ModelType model_type) { @@ -34,9 +37,13 @@ // Accompany types rely on nudges from other types, and hence have long // nudge delays. return kVeryBigLocalChangeNudgeDelay; + case SESSIONS: + // Sessions is the type that causes the most commit traffic. It gets a + // custom nudge delay, tuned for a reasonable trade-off between traffic + // and freshness. + return kDefaultLocalChangeNudgeDelayForSessions; case BOOKMARKS: case PREFERENCES: - case SESSIONS: // Types with sometimes automatic changes get longer delays to allow more // coalescing. return kBigLocalChangeNudgeDelay;
diff --git a/components/sync/engine/cycle/nudge_tracker_unittest.cc b/components/sync/engine/cycle/nudge_tracker_unittest.cc index 6b34fc8..2ddcadf 100644 --- a/components/sync/engine/cycle/nudge_tracker_unittest.cc +++ b/components/sync/engine/cycle/nudge_tracker_unittest.cc
@@ -813,17 +813,26 @@ EXPECT_EQ(nudge_tracker_.RecordLocalChange(TYPED_URLS), nudge_tracker_.RecordLocalChange(EXTENSIONS)); - // Bookmarks, preferences and sessions have bigger delays. + // Bookmarks and preferences sometimes have automatic changes (not directly + // caused by a user actions), so they have bigger delays. EXPECT_GT(nudge_tracker_.RecordLocalChange(BOOKMARKS), nudge_tracker_.RecordLocalChange(TYPED_URLS)); EXPECT_EQ(nudge_tracker_.RecordLocalChange(BOOKMARKS), nudge_tracker_.RecordLocalChange(PREFERENCES)); - EXPECT_EQ(nudge_tracker_.RecordLocalChange(BOOKMARKS), - nudge_tracker_.RecordLocalChange(SESSIONS)); - // Autofill has the longer delay of all. - EXPECT_GT(nudge_tracker_.RecordLocalChange(AUTOFILL), + // Sessions has an even bigger delay. + EXPECT_GT(nudge_tracker_.RecordLocalChange(SESSIONS), nudge_tracker_.RecordLocalChange(BOOKMARKS)); + + // Autofill and UserEvents are "accompany types" that rely on nudges from + // other types. They have the longest delay of all, which really only acts as + // a last-resort fallback. + EXPECT_GT(nudge_tracker_.RecordLocalChange(AUTOFILL), + nudge_tracker_.RecordLocalChange(SESSIONS)); + EXPECT_GT(nudge_tracker_.RecordLocalChange(AUTOFILL), + base::TimeDelta::FromHours(1)); + EXPECT_EQ(nudge_tracker_.RecordLocalChange(AUTOFILL), + nudge_tracker_.RecordLocalChange(USER_EVENTS)); } // Test that custom nudge delays are used over the defaults.
diff --git a/components/sync/invalidations/interested_data_types_handler.h b/components/sync/invalidations/interested_data_types_handler.h index 3bcc8660a..d50c990 100644 --- a/components/sync/invalidations/interested_data_types_handler.h +++ b/components/sync/invalidations/interested_data_types_handler.h
@@ -6,6 +6,7 @@ #define COMPONENTS_SYNC_INVALIDATIONS_INTERESTED_DATA_TYPES_HANDLER_H_ #include "base/callback.h" +#include "components/sync/base/model_type.h" namespace syncer { @@ -17,7 +18,12 @@ virtual ~InterestedDataTypesHandler() = default; // Called on each change of interested data types. - virtual void OnInterestedDataTypesChanged(base::OnceClosure callback) = 0; + virtual void OnInterestedDataTypesChanged() = 0; + + // Called to provide an interface to invoke GetUpdates after any additional + // interested data types get committed. + virtual void SetCommittedAdditionalInterestedDataTypesCallback( + base::RepeatingCallback<void(const ModelTypeSet&)> callback) = 0; }; } // namespace syncer
diff --git a/components/sync/invalidations/interested_data_types_manager.cc b/components/sync/invalidations/interested_data_types_manager.cc index 259cbc6..98f8274 100644 --- a/components/sync/invalidations/interested_data_types_manager.cc +++ b/components/sync/invalidations/interested_data_types_manager.cc
@@ -6,8 +6,6 @@ #include <utility> -#include "base/bind.h" -#include "base/callback_helpers.h" #include "base/feature_list.h" #include "components/sync/base/model_type.h" #include "components/sync/invalidations/interested_data_types_handler.h" @@ -18,33 +16,44 @@ InterestedDataTypesManager::InterestedDataTypesManager() = default; InterestedDataTypesManager::~InterestedDataTypesManager() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!interested_data_types_handler_); } void InterestedDataTypesManager::SetInterestedDataTypesHandler( InterestedDataTypesHandler* handler) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!interested_data_types_handler_ || !handler); interested_data_types_handler_ = handler; } absl::optional<ModelTypeSet> InterestedDataTypesManager::GetInterestedDataTypes() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return data_types_; } void InterestedDataTypesManager::SetInterestedDataTypes( - const ModelTypeSet& data_types, - SyncInvalidationsService::InterestedDataTypesAppliedCallback callback) { - ModelTypeSet new_data_types = - Difference(data_types, data_types_.value_or(ModelTypeSet())); + const ModelTypeSet& data_types) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(interested_data_types_handler_); + data_types_ = data_types; - if (interested_data_types_handler_) { - // Do not send an additional GetUpdates request when invalidations are - // disabled. - interested_data_types_handler_->OnInterestedDataTypesChanged( - base::FeatureList::IsEnabled(switches::kUseSyncInvalidations) - ? base::BindOnce(std::move(callback), new_data_types) - : base::DoNothing()); + interested_data_types_handler_->OnInterestedDataTypesChanged(); +} + +void InterestedDataTypesManager:: + SetCommittedAdditionalInterestedDataTypesCallback( + SyncInvalidationsService::InterestedDataTypesAppliedCallback callback) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(interested_data_types_handler_); + + // Do not send an additional GetUpdates request when invalidations are + // disabled. + if (base::FeatureList::IsEnabled(switches::kUseSyncInvalidations)) { + interested_data_types_handler_ + ->SetCommittedAdditionalInterestedDataTypesCallback( + std::move(callback)); } }
diff --git a/components/sync/invalidations/interested_data_types_manager.h b/components/sync/invalidations/interested_data_types_manager.h index 0d340e7..60203dee 100644 --- a/components/sync/invalidations/interested_data_types_manager.h +++ b/components/sync/invalidations/interested_data_types_manager.h
@@ -7,6 +7,7 @@ #include "third_party/abseil-cpp/absl/types/optional.h" +#include "base/sequence_checker.h" #include "components/sync/base/model_type.h" #include "components/sync/invalidations/sync_invalidations_service.h" @@ -32,11 +33,13 @@ // Set interested data types. The first call of the method initializes this // object. - void SetInterestedDataTypes( - const ModelTypeSet& data_types, + void SetInterestedDataTypes(const ModelTypeSet& data_types); + + void SetCommittedAdditionalInterestedDataTypesCallback( SyncInvalidationsService::InterestedDataTypesAppliedCallback callback); private: + SEQUENCE_CHECKER(sequence_checker_); InterestedDataTypesHandler* interested_data_types_handler_ = nullptr; absl::optional<ModelTypeSet> data_types_;
diff --git a/components/sync/invalidations/interested_data_types_manager_unittest.cc b/components/sync/invalidations/interested_data_types_manager_unittest.cc index c75d667..f694cdc 100644 --- a/components/sync/invalidations/interested_data_types_manager_unittest.cc +++ b/components/sync/invalidations/interested_data_types_manager_unittest.cc
@@ -16,45 +16,48 @@ class MockDataTypesHandler : public InterestedDataTypesHandler { public: + MOCK_METHOD(void, OnInterestedDataTypesChanged, (), (override)); MOCK_METHOD(void, - OnInterestedDataTypesChanged, - (base::OnceClosure callback), + SetCommittedAdditionalInterestedDataTypesCallback, + (base::RepeatingCallback<void(const ModelTypeSet&)> callback), (override)); }; class InterestedDataTypesManagerTest : public testing::Test { + public: + InterestedDataTypesManagerTest() { + manager_.SetInterestedDataTypesHandler(&handler_); + } + + ~InterestedDataTypesManagerTest() override { + manager_.SetInterestedDataTypesHandler(nullptr); + } + protected: + testing::NiceMock<MockDataTypesHandler> handler_; InterestedDataTypesManager manager_; }; TEST_F(InterestedDataTypesManagerTest, ShouldReturnGivenDataTypes) { - manager_.SetInterestedDataTypes(ModelTypeSet(BOOKMARKS, PREFERENCES), - base::DoNothing()); + manager_.SetInterestedDataTypes(ModelTypeSet(BOOKMARKS, PREFERENCES)); EXPECT_EQ(ModelTypeSet(BOOKMARKS, PREFERENCES), manager_.GetInterestedDataTypes()); - manager_.SetInterestedDataTypes(ModelTypeSet(PREFERENCES, PASSWORDS), - base::DoNothing()); + manager_.SetInterestedDataTypes(ModelTypeSet(PREFERENCES, PASSWORDS)); EXPECT_EQ(ModelTypeSet(PREFERENCES, PASSWORDS), manager_.GetInterestedDataTypes()); } TEST_F(InterestedDataTypesManagerTest, ShouldNotifyOnChange) { - testing::NiceMock<MockDataTypesHandler> handler; - manager_.SetInterestedDataTypesHandler(&handler); - EXPECT_CALL(handler, OnInterestedDataTypesChanged); - manager_.SetInterestedDataTypes(ModelTypeSet(PASSWORDS, AUTOFILL), - base::DoNothing()); - manager_.SetInterestedDataTypesHandler(nullptr); + EXPECT_CALL(handler_, OnInterestedDataTypesChanged); + manager_.SetInterestedDataTypes(ModelTypeSet(PASSWORDS, AUTOFILL)); } TEST_F(InterestedDataTypesManagerTest, ShouldInitializeOnFirstSetInterestedDataTypes) { EXPECT_FALSE(manager_.GetInterestedDataTypes().has_value()); - manager_.SetInterestedDataTypes(ModelTypeSet(BOOKMARKS, PREFERENCES), - base::DoNothing()); + manager_.SetInterestedDataTypes(ModelTypeSet(BOOKMARKS, PREFERENCES)); EXPECT_TRUE(manager_.GetInterestedDataTypes().has_value()); - manager_.SetInterestedDataTypes(ModelTypeSet(BOOKMARKS, PREFERENCES, NIGORI), - base::DoNothing()); + manager_.SetInterestedDataTypes(ModelTypeSet(BOOKMARKS, PREFERENCES, NIGORI)); EXPECT_TRUE(manager_.GetInterestedDataTypes().has_value()); }
diff --git a/components/sync/invalidations/mock_sync_invalidations_service.h b/components/sync/invalidations/mock_sync_invalidations_service.h index ccf556d..ef0cb86b 100644 --- a/components/sync/invalidations/mock_sync_invalidations_service.h +++ b/components/sync/invalidations/mock_sync_invalidations_service.h
@@ -37,10 +37,10 @@ GetInterestedDataTypes, (), (const)); + MOCK_METHOD(void, SetInterestedDataTypes, (const ModelTypeSet& data_types)); MOCK_METHOD(void, - SetInterestedDataTypes, - (const ModelTypeSet& data_types, - InterestedDataTypesAppliedCallback callback)); + SetCommittedAdditionalInterestedDataTypesCallback, + (InterestedDataTypesAppliedCallback callback)); }; } // namespace syncer
diff --git a/components/sync/invalidations/sync_invalidations_service.h b/components/sync/invalidations/sync_invalidations_service.h index 69b56664..2e11947 100644 --- a/components/sync/invalidations/sync_invalidations_service.h +++ b/components/sync/invalidations/sync_invalidations_service.h
@@ -27,7 +27,7 @@ // Data types which are newly marked as interesting will be passed to the // callback. using InterestedDataTypesAppliedCallback = - base::OnceCallback<void(const ModelTypeSet&)>; + base::RepeatingCallback<void(const ModelTypeSet&)>; // Start or stop listening to invalidations. virtual void SetActive(bool active) = 0; @@ -56,8 +56,8 @@ // GetInterestedDataTypes() will return base::nullptr until // SetInterestedDataTypes() has been called at least once. virtual absl::optional<ModelTypeSet> GetInterestedDataTypes() const = 0; - virtual void SetInterestedDataTypes( - const ModelTypeSet& data_types, + virtual void SetInterestedDataTypes(const ModelTypeSet& data_types) = 0; + virtual void SetCommittedAdditionalInterestedDataTypesCallback( InterestedDataTypesAppliedCallback callback) = 0; };
diff --git a/components/sync/invalidations/sync_invalidations_service_impl.cc b/components/sync/invalidations/sync_invalidations_service_impl.cc index 56ab5107..7461fea 100644 --- a/components/sync/invalidations/sync_invalidations_service_impl.cc +++ b/components/sync/invalidations/sync_invalidations_service_impl.cc
@@ -80,9 +80,15 @@ } void SyncInvalidationsServiceImpl::SetInterestedDataTypes( - const ModelTypeSet& data_types, - InterestedDataTypesAppliedCallback callback) { - data_types_manager_.SetInterestedDataTypes(data_types, std::move(callback)); + const ModelTypeSet& data_types) { + data_types_manager_.SetInterestedDataTypes(data_types); +} + +void SyncInvalidationsServiceImpl:: + SetCommittedAdditionalInterestedDataTypesCallback( + InterestedDataTypesAppliedCallback callback) { + data_types_manager_.SetCommittedAdditionalInterestedDataTypesCallback( + std::move(callback)); } void SyncInvalidationsServiceImpl::Shutdown() {
diff --git a/components/sync/invalidations/sync_invalidations_service_impl.h b/components/sync/invalidations/sync_invalidations_service_impl.h index 0df1f70..aab9e33 100644 --- a/components/sync/invalidations/sync_invalidations_service_impl.h +++ b/components/sync/invalidations/sync_invalidations_service_impl.h
@@ -41,8 +41,8 @@ void SetInterestedDataTypesHandler( InterestedDataTypesHandler* handler) override; absl::optional<ModelTypeSet> GetInterestedDataTypes() const override; - void SetInterestedDataTypes( - const ModelTypeSet& data_types, + void SetInterestedDataTypes(const ModelTypeSet& data_types) override; + void SetCommittedAdditionalInterestedDataTypesCallback( InterestedDataTypesAppliedCallback callback) override; // KeyedService overrides.
diff --git a/components/sync/test/fake_server/fake_server.cc b/components/sync/test/fake_server/fake_server.cc index 714ede8..9286004 100644 --- a/components/sync/test/fake_server/fake_server.cc +++ b/components/sync/test/fake_server/fake_server.cc
@@ -329,6 +329,12 @@ response->error_code() == sync_pb::SyncEnums::SUCCESS) { DCHECK(!response->has_client_command()); *response->mutable_client_command() = client_command_; + + if (message.has_get_updates()) { + for (Observer& observer : observers_) { + observer.OnSuccessfulGetUpdates(); + } + } } return http_status_code;
diff --git a/components/sync/test/fake_server/fake_server.h b/components/sync/test/fake_server/fake_server.h index 25d79dd..36c8ccd 100644 --- a/components/sync/test/fake_server/fake_server.h +++ b/components/sync/test/fake_server/fake_server.h
@@ -56,12 +56,15 @@ public: class Observer { public: - virtual ~Observer() {} + virtual ~Observer() = default; // Called after FakeServer has processed a successful commit. The types // updated as part of the commit are passed in |committed_model_types|. virtual void OnCommit(const std::string& committer_invalidator_client_id, - syncer::ModelTypeSet committed_model_types) = 0; + syncer::ModelTypeSet committed_model_types) {} + + // Called after FakeServer has processed a successful get updates request. + virtual void OnSuccessfulGetUpdates() {} }; FakeServer();
diff --git a/components/sync_device_info/device_info_sync_bridge.cc b/components/sync_device_info/device_info_sync_bridge.cc index 15a264d..ba8bcf1b 100644 --- a/components/sync_device_info/device_info_sync_bridge.cc +++ b/components/sync_device_info/device_info_sync_bridge.cc
@@ -338,23 +338,19 @@ return local_device_info_provider_.get(); } -void DeviceInfoSyncBridge::RefreshLocalDeviceInfoIfNeeded( - base::OnceClosure callback) { +void DeviceInfoSyncBridge::RefreshLocalDeviceInfoIfNeeded() { // Device info cannot be synced if the provider is not initialized. When it // gets initialized, local device info will be sent. if (!local_device_info_provider_->GetLocalDeviceInfo()) { - if (!callback.is_null()) { - device_info_synced_callback_list_.push_back(std::move(callback)); - } return; } - if (ReconcileLocalAndStored()) { - // The device info has been changed. - if (!callback.is_null()) { - device_info_synced_callback_list_.push_back(std::move(callback)); - } - } + ReconcileLocalAndStored(); +} + +void DeviceInfoSyncBridge::SetCommittedAdditionalInterestedDataTypesCallback( + base::RepeatingCallback<void(const ModelTypeSet&)> callback) { + new_interested_data_types_callback_ = std::move(callback); } void DeviceInfoSyncBridge::OnSyncStarting( @@ -762,8 +758,9 @@ DCHECK(iter != all_data_.end()); // Convert |iter->second| to a DeviceInfo for comparison. - if (StoredDeviceInfoStillAccurate(SpecificsToModel(*iter->second).get(), - current_info)) { + std::unique_ptr<DeviceInfo> previous_device_info = + SpecificsToModel(*iter->second); + if (StoredDeviceInfoStillAccurate(previous_device_info.get(), current_info)) { if (pulse_timer_.IsRunning()) { // No need to update the |pulse_timer| since nothing has changed. return false; @@ -779,6 +776,16 @@ } } + // Initiate an additional GetUpdates request if there are new data types + // enabled (on successful commit). + const ModelTypeSet new_data_types = + Difference(current_info->interested_data_types(), + previous_device_info->interested_data_types()); + if (new_interested_data_types_callback_ && !new_data_types.Empty()) { + device_info_synced_callback_list_.push_back( + base::BindOnce(new_interested_data_types_callback_, new_data_types)); + } + // Either the local data was updated, or it's time for a pulse update. SendLocalData(); return true;
diff --git a/components/sync_device_info/device_info_sync_bridge.h b/components/sync_device_info/device_info_sync_bridge.h index d2dcb4e8..ec9104082 100644 --- a/components/sync_device_info/device_info_sync_bridge.h +++ b/components/sync_device_info/device_info_sync_bridge.h
@@ -10,6 +10,7 @@ #include <string> #include <vector> +#include "base/callback_list.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/observer_list.h" @@ -51,11 +52,17 @@ // Refresh local copy of device info in memory, and informs sync of the // change. Used when the caller knows a property of local device info has // changed (e.g. SharingInfo), and must be sync-ed to other devices as soon as - // possible, without waiting for the periodic commits. |callback| will be - // called when device info is synced. The device info will be compared with - // the local copy. If the data has been updated, then it will be committed. - // Otherwise nothing happens and the |callback| will be never called. - void RefreshLocalDeviceInfoIfNeeded(base::OnceClosure callback); + // possible, without waiting for the periodic commits. The device info will be + // compared with the local copy. If the data has been updated, then it will be + // committed. Otherwise nothing happens. + void RefreshLocalDeviceInfoIfNeeded(); + + // The |callback| will be invoked on each successful commit with newly enabled + // data types list. This is needed to invoke an additional GetUpdates request + // for the data types which have been just enabled and subscribed for new + // invalidations. + void SetCommittedAdditionalInterestedDataTypesCallback( + base::RepeatingCallback<void(const ModelTypeSet&)> callback); // ModelTypeSyncBridge implementation. void OnSyncStarting(const DataTypeActivationRequest& request) override; @@ -175,6 +182,11 @@ std::vector<base::OnceClosure> device_info_synced_callback_list_; + // Called when a new interested data type list has been committed. Only newly + // enabled data types will be passed. May be empty. + base::RepeatingCallback<void(const ModelTypeSet&)> + new_interested_data_types_callback_; + const std::unique_ptr<DeviceInfoPrefs> device_info_prefs_; base::WeakPtrFactory<DeviceInfoSyncBridge> weak_ptr_factory_{this};
diff --git a/components/sync_device_info/device_info_sync_bridge_unittest.cc b/components/sync_device_info/device_info_sync_bridge_unittest.cc index cc7293b7..8dcfea8 100644 --- a/components/sync_device_info/device_info_sync_bridge_unittest.cc +++ b/components/sync_device_info/device_info_sync_bridge_unittest.cc
@@ -567,9 +567,7 @@ void ForcePulse() { bridge()->ForcePulseForTest(); } - void RefreshLocalDeviceInfo() { - bridge()->RefreshLocalDeviceInfoIfNeeded(base::DoNothing()); - } + void RefreshLocalDeviceInfo() { bridge()->RefreshLocalDeviceInfoIfNeeded(); } void CommitToStoreAndWait(std::unique_ptr<WriteBatch> batch) { base::RunLoop loop; @@ -1455,37 +1453,43 @@ EnableSyncAndMergeInitialData(SyncMode::kFull); } -TEST_F(DeviceInfoSyncBridgeTest, ShouldNotifyWhenDeviceInfoIsSynced) { - InitializeAndMergeInitialData(SyncMode::kFull); +TEST_F(DeviceInfoSyncBridgeTest, + ShouldNotifyWhenAdditionalInterestedDataTypesSynced) { + InitializeAndPump(); + local_device()->UpdateInterestedDataTypes({syncer::BOOKMARKS}); + EnableSyncAndMergeInitialData(SyncMode::kFull); - base::MockOnceClosure callback; - ASSERT_THAT(local_device()->GetLocalDeviceInfo()->fcm_registration_token(), - IsEmpty()); - local_device()->UpdateFCMRegistrationToken( - SyncInvalidationsInstanceIdTokenForSuffix(kLocalSuffix)); - bridge()->RefreshLocalDeviceInfoIfNeeded(callback.Get()); + base::MockRepeatingCallback<void(const ModelTypeSet&)> callback; + bridge()->SetCommittedAdditionalInterestedDataTypesCallback(callback.Get()); + local_device()->UpdateInterestedDataTypes( + {syncer::BOOKMARKS, syncer::SESSIONS}); - std::string guid = local_device()->GetLocalDeviceInfo()->guid(); - EXPECT_CALL(*processor(), IsEntityUnsynced(guid)).WillOnce(Return(true)); - EXPECT_CALL(callback, Run()).Times(0); - bridge()->ApplySyncChanges(bridge()->CreateMetadataChangeList(), - EntityChangeList()); + bridge()->RefreshLocalDeviceInfoIfNeeded(); + const std::string guid = local_device()->GetLocalDeviceInfo()->guid(); EXPECT_CALL(*processor(), IsEntityUnsynced(guid)).WillOnce(Return(false)); - EXPECT_CALL(callback, Run()); + + EXPECT_CALL(callback, Run(ModelTypeSet(syncer::SESSIONS))); bridge()->ApplySyncChanges(bridge()->CreateMetadataChangeList(), EntityChangeList()); } -TEST_F(DeviceInfoSyncBridgeTest, ShouldNotNotifyWhenDeviceInfoIsUnchanged) { - InitializeAndMergeInitialData(SyncMode::kFull); +TEST_F(DeviceInfoSyncBridgeTest, + ShouldNotNotifyWithoutAdditionalInterestedDataTypes) { + InitializeAndPump(); + local_device()->UpdateInterestedDataTypes( + {syncer::BOOKMARKS, syncer::SESSIONS}); + EnableSyncAndMergeInitialData(SyncMode::kFull); - base::MockOnceClosure callback; - bridge()->RefreshLocalDeviceInfoIfNeeded(callback.Get()); + base::MockRepeatingCallback<void(const ModelTypeSet&)> callback; + bridge()->SetCommittedAdditionalInterestedDataTypesCallback(callback.Get()); + local_device()->UpdateInterestedDataTypes({syncer::BOOKMARKS}); + + bridge()->RefreshLocalDeviceInfoIfNeeded(); std::string guid = local_device()->GetLocalDeviceInfo()->guid(); EXPECT_CALL(*processor(), IsEntityUnsynced(guid)).WillOnce(Return(false)); - EXPECT_CALL(callback, Run()).Times(0); + EXPECT_CALL(callback, Run).Times(0); bridge()->ApplySyncChanges(bridge()->CreateMetadataChangeList(), EntityChangeList()); }
diff --git a/components/sync_device_info/device_info_sync_service.h b/components/sync_device_info/device_info_sync_service.h index f77a3baa..4a54d2c0 100644 --- a/components/sync_device_info/device_info_sync_service.h +++ b/components/sync_device_info/device_info_sync_service.h
@@ -38,11 +38,8 @@ // has changed (e.g. SharingInfo), and must be sync-ed to other devices as // soon as possible, without waiting for the periodic commits. The device info // will be compared to the local copy. If the device info has been actually - // changed, then it will be committed and the |callback| will be called when - // device info is synced. Otherwise nothing happens and the |callback| will - // never be called. - virtual void RefreshLocalDeviceInfo( - base::OnceClosure callback = base::DoNothing()) = 0; + // changed, then it will be committed. Otherwise nothing happens. + virtual void RefreshLocalDeviceInfo() = 0; }; } // namespace syncer
diff --git a/components/sync_device_info/device_info_sync_service_impl.cc b/components/sync_device_info/device_info_sync_service_impl.cc index 3693e3e..ce55a57 100644 --- a/components/sync_device_info/device_info_sync_service_impl.cc +++ b/components/sync_device_info/device_info_sync_service_impl.cc
@@ -50,13 +50,20 @@ } } -DeviceInfoSyncServiceImpl::~DeviceInfoSyncServiceImpl() {} +DeviceInfoSyncServiceImpl::~DeviceInfoSyncServiceImpl() = default; LocalDeviceInfoProvider* DeviceInfoSyncServiceImpl::GetLocalDeviceInfoProvider() { return bridge_->GetLocalDeviceInfoProvider(); } +void DeviceInfoSyncServiceImpl:: + SetCommittedAdditionalInterestedDataTypesCallback( + base::RepeatingCallback<void(const ModelTypeSet&)> callback) { + bridge_->SetCommittedAdditionalInterestedDataTypesCallback( + std::move(callback)); +} + DeviceInfoTracker* DeviceInfoSyncServiceImpl::GetDeviceInfoTracker() { return bridge_.get(); } @@ -66,18 +73,16 @@ return bridge_->change_processor()->GetControllerDelegate(); } -void DeviceInfoSyncServiceImpl::RefreshLocalDeviceInfo( - base::OnceClosure callback) { - bridge_->RefreshLocalDeviceInfoIfNeeded(std::move(callback)); +void DeviceInfoSyncServiceImpl::RefreshLocalDeviceInfo() { + bridge_->RefreshLocalDeviceInfoIfNeeded(); } void DeviceInfoSyncServiceImpl::OnFCMRegistrationTokenChanged() { RefreshLocalDeviceInfo(); } -void DeviceInfoSyncServiceImpl::OnInterestedDataTypesChanged( - base::OnceClosure callback) { - RefreshLocalDeviceInfo(std::move(callback)); +void DeviceInfoSyncServiceImpl::OnInterestedDataTypesChanged() { + RefreshLocalDeviceInfo(); } void DeviceInfoSyncServiceImpl::Shutdown() {
diff --git a/components/sync_device_info/device_info_sync_service_impl.h b/components/sync_device_info/device_info_sync_service_impl.h index 7be70a9c..13ee00e 100644 --- a/components/sync_device_info/device_info_sync_service_impl.h +++ b/components/sync_device_info/device_info_sync_service_impl.h
@@ -43,14 +43,15 @@ LocalDeviceInfoProvider* GetLocalDeviceInfoProvider() override; DeviceInfoTracker* GetDeviceInfoTracker() override; base::WeakPtr<ModelTypeControllerDelegate> GetControllerDelegate() override; - void RefreshLocalDeviceInfo( - base::OnceClosure callback = base::DoNothing()) override; + void RefreshLocalDeviceInfo() override; // FCMRegistrationTokenObserver implementation. void OnFCMRegistrationTokenChanged() override; // InterestedDataTypesHandler implementation. - void OnInterestedDataTypesChanged(base::OnceClosure callback) override; + void OnInterestedDataTypesChanged() override; + void SetCommittedAdditionalInterestedDataTypesCallback( + base::RepeatingCallback<void(const ModelTypeSet&)> callback) override; // KeyedService overrides. void Shutdown() override;
diff --git a/components/sync_device_info/fake_device_info_sync_service.cc b/components/sync_device_info/fake_device_info_sync_service.cc index 5c1cbb1..c0abede 100644 --- a/components/sync_device_info/fake_device_info_sync_service.cc +++ b/components/sync_device_info/fake_device_info_sync_service.cc
@@ -25,12 +25,8 @@ return fake_model_type_controller_delegate_.GetWeakPtr(); } -void FakeDeviceInfoSyncService::RefreshLocalDeviceInfo( - base::OnceClosure callback) { +void FakeDeviceInfoSyncService::RefreshLocalDeviceInfo() { refresh_local_device_info_count_++; - if (!callback.is_null()) { - std::move(callback).Run(); - } } int FakeDeviceInfoSyncService::RefreshLocalDeviceInfoCount() {
diff --git a/components/sync_device_info/fake_device_info_sync_service.h b/components/sync_device_info/fake_device_info_sync_service.h index f1a51b5..a1e827a6 100644 --- a/components/sync_device_info/fake_device_info_sync_service.h +++ b/components/sync_device_info/fake_device_info_sync_service.h
@@ -22,7 +22,7 @@ FakeLocalDeviceInfoProvider* GetLocalDeviceInfoProvider() override; FakeDeviceInfoTracker* GetDeviceInfoTracker() override; base::WeakPtr<ModelTypeControllerDelegate> GetControllerDelegate() override; - void RefreshLocalDeviceInfo(base::OnceClosure callback) override; + void RefreshLocalDeviceInfo() override; // Returns number of times RefreshLocalDeviceInfo() has been called. int RefreshLocalDeviceInfoCount();
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl.cc b/components/viz/service/display_embedder/skia_output_surface_impl.cc index c4e792b..34c992983 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl.cc +++ b/components/viz/service/display_embedder/skia_output_surface_impl.cc
@@ -490,10 +490,11 @@ frame.sub_buffer_rect ? *frame.sub_buffer_rect : gfx::Rect(size_); frame_buffer_damage_tracker_->SwappedWithDamage(damage_rect); } + pending_swaps_.push_back(current_buffer_modified_); current_buffer_modified_ = false; - pending_swaps_++; - if (AvailableBuffersLowerBound() > 0) { + int available_buffers_lower_bound = AvailableBuffersLowerBound(); + if (available_buffers_lower_bound > 0) { consecutive_frames_with_extra_buffer_++; } else { consecutive_frames_with_extra_buffer_ = 0; @@ -503,7 +504,7 @@ bool release_one_buffer = capabilities_.use_dynamic_frame_buffer_allocation && consecutive_frames_with_extra_buffer_ > kFreeBufferThreshold && - AvailableBuffersLowerBound() > 0; + available_buffers_lower_bound > 0; if (release_one_buffer) { consecutive_frames_with_extra_buffer_ = 0; num_allocated_buffers_--; @@ -974,8 +975,7 @@ frame_buffer_damage_tracker_->ReallocatedFrameBuffers(size_); } - DCHECK_GT(pending_swaps_, 0); - pending_swaps_--; + pending_swaps_.pop_front(); if (use_damage_area_from_skia_output_device_) { damage_of_current_buffer_ = params.frame_buffer_damage_area; @@ -1270,9 +1270,14 @@ } int SkiaOutputSurfaceImpl::AvailableBuffersLowerBound() const { - // Up to 1 buffer may be held for display, and each pending swap can use up - // to 1 buffer. Note the result can be negative. - return num_allocated_buffers_ - 1 - pending_swaps_; + // Up to 1 buffer may be held for display, and each pending swap with damage + // can use up to 1 buffer. Note the result can be negative. + int pending_swaps_with_damage = 0; + for (bool has_damage : pending_swaps_) { + if (has_damage) + pending_swaps_with_damage++; + } + return num_allocated_buffers_ - 1 - pending_swaps_with_damage; } bool SkiaOutputSurfaceImpl::ShouldCreateNewBufferForNextSwap() const {
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl.h b/components/viz/service/display_embedder/skia_output_surface_impl.h index bd8d8c3..487150f 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl.h +++ b/components/viz/service/display_embedder/skia_output_surface_impl.h
@@ -380,10 +380,11 @@ // This way, this class knows exactly the number of allocated (once all work // posted to GPU thread are done). int num_allocated_buffers_ = 0; - // Number of SwapBuffers that has yet been matched with a - // DidSwapBuffersComplete. This is used to compute a lower bound on the number - // of available buffers on the GPU thread. - int pending_swaps_ = 0; + // For each SwapBuffers that has yet been matched with a + // DidSwapBuffersComplete, store whether that swap has damage to the main + // buffer. DidSwapBuffersComplete. This is used to compute a lower bound on + // the number of available buffers on the GPU thread. + base::circular_deque<bool> pending_swaps_; // Consecutive number of swaps where there is an extra buffer allocated. Used // as part of heuristic to decide when to release extra frame buffers. int consecutive_frames_with_extra_buffer_ = 0;
diff --git a/components/webdata/common/web_database.cc b/components/webdata/common/web_database.cc index 410cd48..09fd36d 100644 --- a/components/webdata/common/web_database.cc +++ b/components/webdata/common/web_database.cc
@@ -98,7 +98,9 @@ // Clobber really old databases. static_assert(kDeprecatedVersionNumber < kCurrentVersionNumber, "Deprecation version must be less than current"); - sql::MetaTable::RazeIfDeprecated(&db_, kDeprecatedVersionNumber); + sql::MetaTable::RazeIfIncompatible( + &db_, /*lowest_supported_version=*/kDeprecatedVersionNumber + 1, + kCurrentVersionNumber); // Scope initialization in a transaction so we can't be partially // initialized.
diff --git a/content/browser/accessibility/accessibility_tree_formatter_mac_browsertest.mm b/content/browser/accessibility/accessibility_tree_formatter_mac_browsertest.mm index c562e7de..c4919c5 100644 --- a/content/browser/accessibility/accessibility_tree_formatter_mac_browsertest.mm +++ b/content/browser/accessibility/accessibility_tree_formatter_mac_browsertest.mm
@@ -262,7 +262,7 @@ SCRIPT}}, {{"*", "*"}}, R"~~(text_range={anchor: {:3, 0, down}, focus: {:3, 4, down}} - textbox.AXTextMarkerRangeForUnorderedTextMarkers([text_range.anchor, text_range.focus])={anchor: {:3, 0, down}, focus: {:3, 4, down}} +textbox.AXTextMarkerRangeForUnorderedTextMarkers([text_range.anchor, text_range.focus])={anchor: {:3, 0, down}, focus: {:3, 4, down}} )~~"); } @@ -440,7 +440,7 @@ {{"text:= p.AXChildren[0]", SCRIPT}, {"text.AXRole", SCRIPT}}, {{"*", "*"}}, R"~~(text=:3 - text.AXRole='AXStaticText' +text.AXRole='AXStaticText' )~~"); }
diff --git a/content/browser/accessibility/accessibility_win_browsertest.cc b/content/browser/accessibility/accessibility_win_browsertest.cc index fbf7fab3..0a01be8 100644 --- a/content/browser/accessibility/accessibility_win_browsertest.cc +++ b/content/browser/accessibility/accessibility_win_browsertest.cc
@@ -5169,7 +5169,19 @@ destroyed_watcher.Wait(); } -IN_PROC_BROWSER_TEST_F(AccessibilityWinUIABrowserTest, +class AccessibilityWinUIASelectivelyEnabledBrowserTest + : public AccessibilityWinUIABrowserTest { + protected: + void SetUp() override { + scoped_feature_list_.InitAndEnableFeature( + features::kSelectiveUIAEnablement); + + AccessibilityWinUIABrowserTest::SetUp(); + } + base::test::ScopedFeatureList scoped_feature_list_; +}; + +IN_PROC_BROWSER_TEST_F(AccessibilityWinUIASelectivelyEnabledBrowserTest, RequestingTopLevelElementEnablesWebAccessibility) { EXPECT_TRUE(NavigateToURL(shell(), GURL("about:blank"))); @@ -5190,10 +5202,44 @@ uia->ElementFromHandle(hwnd, &root); ASSERT_NE(nullptr, root.Get()); + // Native API support should now be enabled. + ui::AXMode expected_mode = ui::AXMode::kNativeAPIs; + EXPECT_EQ(expected_mode, content::BrowserAccessibilityStateImpl::GetInstance() + ->GetAccessibilityMode()); + + // Now get the fragment root's first (only) child. + Microsoft::WRL::ComPtr<IUIAutomationTreeWalker> tree_walker; + uia->get_RawViewWalker(&tree_walker); + Microsoft::WRL::ComPtr<IUIAutomationElement> first_child; + tree_walker->GetFirstChildElement(root.Get(), &first_child); + ASSERT_NE(nullptr, first_child.Get()); + + base::win::ScopedBstr name; + ASSERT_HRESULT_SUCCEEDED(first_child->get_CurrentName(name.Receive())); + // Web content accessibility support should now be enabled. - EXPECT_EQ(ui::kAXModeComplete, - content::BrowserAccessibilityStateImpl::GetInstance() - ->GetAccessibilityMode()); + expected_mode |= ui::AXMode::kWebContents; + EXPECT_EQ(expected_mode, content::BrowserAccessibilityStateImpl::GetInstance() + ->GetAccessibilityMode()); + + Microsoft::WRL::ComPtr<IUnknown> text_pattern_unknown; + ASSERT_HRESULT_SUCCEEDED( + first_child->GetCurrentPattern(UIA_TextPatternId, &text_pattern_unknown)); + EXPECT_EQ(nullptr, text_pattern_unknown.Get()); + + // Now check that inline text box support is enabled as well. + expected_mode |= ui::AXMode::kInlineTextBoxes; + EXPECT_EQ(expected_mode, content::BrowserAccessibilityStateImpl::GetInstance() + ->GetAccessibilityMode()); + + base::win::ScopedVariant variant; + ASSERT_HRESULT_SUCCEEDED(first_child->GetCurrentPropertyValue( + UIA_LabeledByPropertyId, variant.Receive())); + + // Now check that we have complete accessibility support enabled. + expected_mode |= ui::AXMode::kScreenReader; + EXPECT_EQ(expected_mode, content::BrowserAccessibilityStateImpl::GetInstance() + ->GetAccessibilityMode()); } IN_PROC_BROWSER_TEST_F(AccessibilityWinUIABrowserTest,
diff --git a/content/browser/accessibility/browser_accessibility_state_impl_win.cc b/content/browser/accessibility/browser_accessibility_state_impl_win.cc index 9c1ea74..a15418f 100644 --- a/content/browser/accessibility/browser_accessibility_state_impl_win.cc +++ b/content/browser/accessibility/browser_accessibility_state_impl_win.cc
@@ -74,18 +74,38 @@ BrowserAccessibilityStateImpl::GetInstance()->OnAccessibilityApiUsage(); } - void OnUIAutomationUsed() override { + void OnBasicUIAutomationUsed() override { + AddAXModeForUIA(ui::AXMode::kNativeAPIs); + } + + void OnAdvancedUIAutomationUsed() override { + AddAXModeForUIA(ui::AXMode::kWebContents); + } + + void OnProbableUIAutomationScreenReaderDetected() override { + // Same as kAXModeComplete but without kHTML as it is not needed for UIA. + AddAXModeForUIA(ui::kAXModeCompleteNoHTML); + } + + void OnTextPatternRequested() override { + AddAXModeForUIA(ui::AXMode::kInlineTextBoxes); + } + + void AddAXModeForUIA(ui::AXMode mode) { DCHECK(::switches::IsExperimentalAccessibilityPlatformUIAEnabled()); // Firing a UIA event can cause UIA to call back into our APIs, don't // consider this to be usage. if (firing_uia_events_) return; + // UI Automation insulates providers from knowing about the client(s) asking - // for information. When UI Automation is requested, assume the presence of - // a full-fledged accessibility technology and enable full support. + // for information. When IsSelectiveUIAEnablement is Enabled, we turn on + // various parts of accessibility depending on what APIs have been called. + if (!features::IsSelectiveUIAEnablementEnabled()) + mode = ui::kAXModeComplete; BrowserAccessibilityStateImpl::GetInstance()->AddAccessibilityModeFlags( - ui::kAXModeComplete); + mode); BrowserAccessibilityStateImpl::GetInstance()->OnAccessibilityApiUsage(); }
diff --git a/content/browser/aggregation_service/public_key_parsing_utils.cc b/content/browser/aggregation_service/public_key_parsing_utils.cc index ac2d309d..a401e87 100644 --- a/content/browser/aggregation_service/public_key_parsing_utils.cc +++ b/content/browser/aggregation_service/public_key_parsing_utils.cc
@@ -36,7 +36,7 @@ std::string latest_version; - for (const auto& kv : value.DictItems()) { + for (const auto kv : value.DictItems()) { const std::string& version = kv.first; if (version < latest_version) continue;
diff --git a/content/browser/browser_interface_binders.cc b/content/browser/browser_interface_binders.cc index 7c211b13..4673cf57 100644 --- a/content/browser/browser_interface_binders.cc +++ b/content/browser/browser_interface_binders.cc
@@ -429,6 +429,25 @@ base::Unretained(host), method); } +template <typename WorkerHost, typename Interface> +base::RepeatingCallback<void(mojo::PendingReceiver<Interface>)> +BindWorkerReceiverForStorageKey( + void (RenderProcessHostImpl::*method)(const blink::StorageKey&, + mojo::PendingReceiver<Interface>), + WorkerHost* host) { + return base::BindRepeating( + [](WorkerHost* host, + void (RenderProcessHostImpl::*method)( + const blink::StorageKey&, mojo::PendingReceiver<Interface>), + mojo::PendingReceiver<Interface> receiver) { + auto* process_host = + static_cast<RenderProcessHostImpl*>(host->GetProcessHost()); + if (process_host) + (process_host->*method)(host->GetStorageKey(), std::move(receiver)); + }, + base::Unretained(host), method); +} + template <typename... Args> void RunOrPostTaskToBindServiceWorkerReceiver( ServiceWorkerHost* host, @@ -506,6 +525,27 @@ }, base::Unretained(host), method); } + +template <typename Interface> +base::RepeatingCallback<void(const ServiceWorkerVersionBaseInfo&, + mojo::PendingReceiver<Interface>)> +BindServiceWorkerReceiverForStorageKey( + void (RenderProcessHostImpl::*method)(const blink::StorageKey&, + mojo::PendingReceiver<Interface>), + ServiceWorkerHost* host) { + return base::BindRepeating( + [](ServiceWorkerHost* host, + void (RenderProcessHostImpl::*method)( + const blink::StorageKey&, mojo::PendingReceiver<Interface>), + const ServiceWorkerVersionBaseInfo& info, + mojo::PendingReceiver<Interface> receiver) { + RunOrPostTaskToBindServiceWorkerReceiver< + const blink::StorageKey&, mojo::PendingReceiver<Interface>>( + host, method, info.storage_key, std::move(receiver)); + }, + base::Unretained(host), method); +} + template <typename Interface> void EmptyBinderForFrame(RenderFrameHost* host, mojo::PendingReceiver<Interface> receiver) { @@ -1038,6 +1078,9 @@ // render process host binders map->Add<media::mojom::VideoDecodePerfHistory>(BindWorkerReceiver( &RenderProcessHostImpl::BindVideoDecodePerfHistory, host)); + + map->Add<blink::mojom::IDBFactory>(BindWorkerReceiverForStorageKey( + &RenderProcessHostImpl::BindIndexedDB, host)); } void PopulateBinderMapWithContext( @@ -1054,8 +1097,6 @@ &RenderProcessHostImpl::BindFileSystemAccessManager, host)); map->Add<blink::mojom::NativeIOHost>(BindWorkerReceiverForOrigin( &RenderProcessHostImpl::BindNativeIOHost, host)); - map->Add<blink::mojom::IDBFactory>( - BindWorkerReceiverForOrigin(&RenderProcessHostImpl::BindIndexedDB, host)); map->Add<blink::mojom::BucketManagerHost>(BindWorkerReceiverForOrigin( &RenderProcessHostImpl::BindBucketManagerHost, host)); @@ -1128,6 +1169,8 @@ // render process host binders map->Add<media::mojom::VideoDecodePerfHistory>(BindWorkerReceiver( &RenderProcessHostImpl::BindVideoDecodePerfHistory, host)); + map->Add<blink::mojom::IDBFactory>(BindWorkerReceiverForStorageKey( + &RenderProcessHostImpl::BindIndexedDB, host)); } void PopulateBinderMapWithContext( @@ -1146,8 +1189,6 @@ &RenderProcessHostImpl::BindNativeIOHost, host)); map->Add<blink::mojom::WebSocketConnector>(BindWorkerReceiverForOrigin( &RenderProcessHostImpl::CreateWebSocketConnector, host)); - map->Add<blink::mojom::IDBFactory>( - BindWorkerReceiverForOrigin(&RenderProcessHostImpl::BindIndexedDB, host)); map->Add<blink::mojom::BucketManagerHost>(BindWorkerReceiverForOrigin( &RenderProcessHostImpl::BindBucketManagerHost, host)); @@ -1256,11 +1297,13 @@ BindServiceWorkerReceiverForOrigin( &RenderProcessHostImpl::BindRestrictedCookieManagerForServiceWorker, host)); - map->Add<blink::mojom::IDBFactory>(BindServiceWorkerReceiverForOrigin( - &RenderProcessHostImpl::BindIndexedDB, host)); map->Add<blink::mojom::BucketManagerHost>(BindServiceWorkerReceiverForOrigin( &RenderProcessHostImpl::BindBucketManagerHost, host)); + // render process host binders taking a storage key + map->Add<blink::mojom::IDBFactory>(BindServiceWorkerReceiverForStorageKey( + &RenderProcessHostImpl::BindIndexedDB, host)); + // render process host binders taking a frame id and an origin map->Add<blink::mojom::LockManager>( BindServiceWorkerReceiverForOriginAndFrameId(
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc index fe7a49d..4da6b81 100644 --- a/content/browser/renderer_host/render_frame_host_impl.cc +++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -9256,7 +9256,7 @@ void RenderFrameHostImpl::CreateIDBFactory( mojo::PendingReceiver<blink::mojom::IDBFactory> receiver) { - GetProcess()->BindIndexedDB(GetLastCommittedOrigin(), std::move(receiver)); + GetProcess()->BindIndexedDB(storage_key(), std::move(receiver)); } void RenderFrameHostImpl::CreateBucketManagerHost(
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 2bbf363..3f92d148 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -2151,20 +2151,18 @@ } void RenderProcessHostImpl::BindIndexedDB( - const url::Origin& origin, + const blink::StorageKey& storage_key, mojo::PendingReceiver<blink::mojom::IDBFactory> receiver) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - if (origin.opaque()) { + if (storage_key.origin().opaque()) { // Opaque origins aren't valid for IndexedDB access, so we won't bind // |receiver| to |indexed_db_factory_|. Return early here which // will cause |receiver| to be freed. When |receiver| is // freed, we expect the pipe on the client will be closed. return; } - // TODO(https://crbug.com/1199077): Pass the real StorageKey into this - // function directly. storage_partition_impl_->GetIndexedDBControl().BindIndexedDB( - blink::StorageKey(origin), std::move(receiver)); + storage_key, std::move(receiver)); } void RenderProcessHostImpl::BindBucketManagerHost(
diff --git a/content/browser/renderer_host/render_process_host_impl.h b/content/browser/renderer_host/render_process_host_impl.h index f0a01469..af612cd 100644 --- a/content/browser/renderer_host/render_process_host_impl.h +++ b/content/browser/renderer_host/render_process_host_impl.h
@@ -281,7 +281,7 @@ const blink::StorageKey& storage_key, mojo::PendingReceiver<blink::mojom::CacheStorage> receiver) override; void BindIndexedDB( - const url::Origin& origin, + const blink::StorageKey& storage_key, mojo::PendingReceiver<blink::mojom::IDBFactory> receiver) override; void BindBucketManagerHost( const url::Origin& origin,
diff --git a/content/browser/webid/federated_auth_request_impl.cc b/content/browser/webid/federated_auth_request_impl.cc index 40137119..35cd8ce26 100644 --- a/content/browser/webid/federated_auth_request_impl.cc +++ b/content/browser/webid/federated_auth_request_impl.cc
@@ -13,6 +13,7 @@ #include "content/public/browser/federated_identity_request_permission_context_delegate.h" #include "content/public/browser/federated_identity_sharing_permission_context_delegate.h" #include "content/public/common/content_client.h" +#include "third_party/abseil-cpp/absl/types/optional.h" #include "url/url_constants.h" using blink::mojom::LogoutStatus; @@ -22,6 +23,23 @@ namespace content { +namespace { +std::string FormatRequestParams(const std::string& client_id, + const std::string& nonce) { + std::string query; + // 'openid' scope is required for IdPs using OpenID Connect. We hope that IdPs + // using OAuth will ignore it, although some might return errors. + query += "scope=openid profile email"; + if (client_id.length() > 0) { + query += "&client_id=" + client_id; + } + if (nonce.length() > 0) { + query += "&nonce=" + nonce; + } + return query; +} +} // namespace + FederatedAuthRequestImpl::FederatedAuthRequestImpl( RenderFrameHost* host, mojo::PendingReceiver<blink::mojom::FederatedAuthRequest> receiver) @@ -57,7 +75,8 @@ } void FederatedAuthRequestImpl::RequestIdToken(const GURL& provider, - const std::string& id_request, + const std::string& client_id, + const std::string& nonce, RequestMode mode, RequestIdTokenCallback callback) { if (logout_callback_ || auth_request_callback_) { @@ -67,7 +86,8 @@ auth_request_callback_ = std::move(callback); provider_ = provider; - id_request_ = id_request; + client_id_ = client_id; + nonce_ = nonce; mode_ = mode; network_manager_ = CreateNetworkManager(provider); @@ -212,7 +232,7 @@ } network_manager_->SendSigninRequest( - endpoints_.idp, id_request_, + endpoints_.idp, FormatRequestParams(client_id_, nonce_), base::BindOnce(&FederatedAuthRequestImpl::OnSigninResponseReceived, weak_ptr_factory_.GetWeakPtr())); break; @@ -398,7 +418,7 @@ } network_manager_->SendTokenRequest( - endpoints_.token, account_id, id_request_, + endpoints_.token, account_id, FormatRequestParams(client_id_, nonce_), base::BindOnce(&FederatedAuthRequestImpl::OnTokenResponseReceived, weak_ptr_factory_.GetWeakPtr())); }
diff --git a/content/browser/webid/federated_auth_request_impl.h b/content/browser/webid/federated_auth_request_impl.h index f209d0b..0c6c0108 100644 --- a/content/browser/webid/federated_auth_request_impl.h +++ b/content/browser/webid/federated_auth_request_impl.h
@@ -50,7 +50,8 @@ // blink::mojom::FederatedAuthRequest: void RequestIdToken(const GURL& provider, - const std::string& id_request, + const std::string& client_id, + const std::string& nonce, blink::mojom::RequestMode mode, RequestIdTokenCallback) override; void Logout(const std::vector<std::string>& logout_endpoints, @@ -107,7 +108,8 @@ // Parameters of auth request. GURL provider_; - std::string id_request_; + std::string client_id_; + std::string nonce_; blink::mojom::RequestMode mode_; // Fetched from the IDP well-known configuration.
diff --git a/content/browser/webid/federated_auth_request_impl_unittest.cc b/content/browser/webid/federated_auth_request_impl_unittest.cc index 6b2882a..de0f0d8 100644 --- a/content/browser/webid/federated_auth_request_impl_unittest.cc +++ b/content/browser/webid/federated_auth_request_impl_unittest.cc
@@ -48,9 +48,10 @@ constexpr char kAccountsEndpoint[] = "https://idp.example/accounts"; constexpr char kTokenEndpoint[] = "https://idp.example/token"; constexpr char kSigninUrl[] = "https://idp.example/signin"; +constexpr char kClientId[] = "client_id_123"; +constexpr char kNonce[] = "nonce123"; // Values will be added here as token introspection is implemented. -constexpr char kAuthRequest[] = ""; constexpr char kToken[] = "[not a real token]"; constexpr char kEmptyToken[] = ""; @@ -65,7 +66,8 @@ // Parameters for a call to RequestIdToken. typedef struct { const char* provider; - const char* request; + const char* client_id; + const char* nonce; RequestMode mode; } RequestParameters; @@ -122,7 +124,7 @@ static const AuthRequestTestCase kPermissionTestCases[]{ {"Successful run with the IdP page loaded", - {kIdpTestOrigin, kAuthRequest, RequestMode::kPermission}, + {kIdpTestOrigin, kClientId, kNonce, RequestMode::kPermission}, {RequestIdTokenStatus::kSuccess, kToken}, {kToken, UserApproval::kApproved, @@ -134,7 +136,7 @@ kMediatedNoop}}, {"Successful run with a token response from the idp_endpoint", - {kIdpTestOrigin, kAuthRequest, RequestMode::kPermission}, + {kIdpTestOrigin, kClientId, kNonce, RequestMode::kPermission}, {RequestIdTokenStatus::kSuccess, kToken}, {kToken, UserApproval::kApproved, @@ -146,31 +148,31 @@ kMediatedNoop}}, {"Initial user permission denied", - {kIdpTestOrigin, kAuthRequest, RequestMode::kPermission}, + {kIdpTestOrigin, kClientId, kNonce, RequestMode::kPermission}, {RequestIdTokenStatus::kApprovalDeclined, kEmptyToken}, {kToken, UserApproval::kDenied, absl::nullopt, "", "", "", kPermissionNoop, kMediatedNoop}}, {"Wellknown file not found", - {kIdpTestOrigin, kAuthRequest, RequestMode::kPermission}, + {kIdpTestOrigin, kClientId, kNonce, RequestMode::kPermission}, {RequestIdTokenStatus::kErrorWebIdNotSupportedByProvider, kEmptyToken}, {kToken, UserApproval::kApproved, FetchStatus::kWebIdNotSupported, "", "", "", kPermissionNoop, kMediatedNoop}}, {"Wellknown fetch error", - {kIdpTestOrigin, kAuthRequest, RequestMode::kPermission}, + {kIdpTestOrigin, kClientId, kNonce, RequestMode::kPermission}, {RequestIdTokenStatus::kErrorFetchingWellKnown, kEmptyToken}, {kToken, UserApproval::kApproved, FetchStatus::kFetchError, "", "", "", kPermissionNoop, kMediatedNoop}}, {"Error parsing wellknown for Permission mode", - {kIdpTestOrigin, kAuthRequest, RequestMode::kPermission}, + {kIdpTestOrigin, kClientId, kNonce, RequestMode::kPermission}, {RequestIdTokenStatus::kErrorInvalidWellKnown, kEmptyToken}, {kToken, UserApproval::kApproved, FetchStatus::kInvalidResponseError, "", kAccountsEndpoint, kTokenEndpoint, kPermissionNoop, kMediatedNoop}}, {"Error reaching the idpendpoint", - {kIdpTestOrigin, kAuthRequest, RequestMode::kPermission}, + {kIdpTestOrigin, kClientId, kNonce, RequestMode::kPermission}, {RequestIdTokenStatus::kErrorFetchingSignin, kEmptyToken}, {kToken, UserApproval::kApproved, @@ -182,7 +184,7 @@ kMediatedNoop}}, {"Error parsing the idpendpoint response", - {kIdpTestOrigin, kAuthRequest, RequestMode::kPermission}, + {kIdpTestOrigin, kClientId, kNonce, RequestMode::kPermission}, {RequestIdTokenStatus::kErrorInvalidSigninResponse, kEmptyToken}, {kToken, UserApproval::kApproved, @@ -194,7 +196,7 @@ kMediatedNoop}}, {"IdP window closed before token provision", - {kIdpTestOrigin, kAuthRequest, RequestMode::kPermission}, + {kIdpTestOrigin, kClientId, kNonce, RequestMode::kPermission}, {RequestIdTokenStatus::kError, kEmptyToken}, {kEmptyToken, UserApproval::kApproved, @@ -206,7 +208,7 @@ kMediatedNoop}}, {"Token provision declined by user after IdP window closed", - {kIdpTestOrigin, kAuthRequest, RequestMode::kPermission}, + {kIdpTestOrigin, kClientId, kNonce, RequestMode::kPermission}, {RequestIdTokenStatus::kApprovalDeclined, kEmptyToken}, {kToken, UserApproval::kApproved, @@ -219,19 +221,19 @@ static const AuthRequestTestCase kMediatedTestCases[]{ {"Error parsing wellknown for Mediated mode missing token endpoint", - {kIdpTestOrigin, kAuthRequest, RequestMode::kMediated}, + {kIdpTestOrigin, kClientId, kNonce, RequestMode::kMediated}, {RequestIdTokenStatus::kErrorInvalidWellKnown, kEmptyToken}, {kToken, absl::nullopt, FetchStatus::kInvalidResponseError, kIdpEndpoint, kAccountsEndpoint, "", kPermissionNoop, kMediatedNoop}}, {"Error parsing wellknown for Mediated mode missing accounts endpoint", - {kIdpTestOrigin, kAuthRequest, RequestMode::kMediated}, + {kIdpTestOrigin, kClientId, kNonce, RequestMode::kMediated}, {RequestIdTokenStatus::kErrorInvalidWellKnown, kEmptyToken}, {kToken, absl::nullopt, FetchStatus::kInvalidResponseError, kIdpEndpoint, "", kTokenEndpoint, kPermissionNoop, kMediatedNoop}}, {"Error reaching Accounts endpoint", - {kIdpTestOrigin, kAuthRequest, RequestMode::kMediated}, + {kIdpTestOrigin, kClientId, kNonce, RequestMode::kMediated}, {RequestIdTokenStatus::kError, kEmptyToken}, {kEmptyToken, absl::nullopt, @@ -243,7 +245,7 @@ {AccountsResponse::kNetError, kAccounts, absl::nullopt}}}, {"Error parsing Accounts response", - {kIdpTestOrigin, kAuthRequest, RequestMode::kMediated}, + {kIdpTestOrigin, kClientId, kNonce, RequestMode::kMediated}, {RequestIdTokenStatus::kErrorInvalidAccountsResponse, kEmptyToken}, {kToken, absl::nullopt, @@ -255,7 +257,7 @@ {AccountsResponse::kInvalidResponseError, kAccounts, absl::nullopt}}}, {"Successful Mediated flow", - {kIdpTestOrigin, kAuthRequest, RequestMode::kMediated}, + {kIdpTestOrigin, kClientId, kNonce, RequestMode::kMediated}, {RequestIdTokenStatus::kSuccess, kToken}, {kToken, absl::nullopt, @@ -373,7 +375,8 @@ } std::pair<RequestIdTokenStatus, absl::optional<std::string>> - PerformAuthRequest(const std::string& request, + PerformAuthRequest(const std::string& client_id, + const std::string& nonce, blink::mojom::RequestMode mode) { auth_request_impl_->SetNetworkManagerForTests( std::move(mock_request_manager_)); @@ -381,7 +384,7 @@ std::move(mock_dialog_controller_)); AuthRequestCallbackHelper auth_helper; - request_remote_->RequestIdToken(provider_, request, mode, + request_remote_->RequestIdToken(provider_, client_id, nonce, mode, auth_helper.callback()); auth_helper.WaitForCallback(); return std::make_pair(auth_helper.status(), auth_helper.token()); @@ -595,7 +598,8 @@ CreateAuthRequest(GURL(test_case.inputs.provider)); SetMockExpectations(test_case); auto auth_response = - PerformAuthRequest(test_case.inputs.request, test_case.inputs.mode); + PerformAuthRequest(test_case.inputs.client_id, test_case.inputs.nonce, + test_case.inputs.mode); EXPECT_EQ(auth_response.first, test_case.expected.return_status); EXPECT_EQ(auth_response.second, test_case.expected.token); }
diff --git a/content/browser/webid/idp_network_request_manager.cc b/content/browser/webid/idp_network_request_manager.cc index d435277..34f34e86 100644 --- a/content/browser/webid/idp_network_request_manager.cc +++ b/content/browser/webid/idp_network_request_manager.cc
@@ -5,13 +5,13 @@ #include "content/browser/webid/idp_network_request_manager.h" #include "base/base64.h" -#include "base/base64url.h" #include "base/json/json_writer.h" #include "base/rand_util.h" #include "content/public/browser/identity_request_dialog_controller.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/storage_partition.h" #include "mojo/public/cpp/bindings/remote.h" +#include "net/base/escape.h" #include "net/base/isolation_info.h" #include "net/cookies/site_for_cookies.h" #include "net/http/http_request_headers.h" @@ -228,16 +228,9 @@ signin_request_callback_ = std::move(callback); - // TODO(kenrb): A straight URL encoding isn't right. Add proper parsing. - // https://crbug.com/1141125. - std::string encoded_request; - base::Base64UrlEncode(base::StringPiece(request), - base::Base64UrlEncodePolicy::INCLUDE_PADDING, - &encoded_request); + std::string escaped_request = net::EscapeUrlEncodedData(request, true); - // TODO: Should this be a POST, rather than a GET using query parameters? - // https://crbug.com/1141125. - GURL target_url = GURL(signin_url.spec() + "?" + encoded_request); + GURL target_url = GURL(signin_url.spec() + "?" + escaped_request); auto resource_request = CreateCredentialedResourceRequest(target_url, relying_party_origin_); auto traffic_annotation = CreateTrafficAnnotation();
diff --git a/content/browser/webid/webid_browsertest.cc b/content/browser/webid/webid_browsertest.cc index 55aeefac..e1492b63 100644 --- a/content/browser/webid/webid_browsertest.cc +++ b/content/browser/webid/webid_browsertest.cc
@@ -200,7 +200,8 @@ var x = (await navigator.id.get({ provider: ')" + BaseIdpUrl() + R"(', - request: '[not a real request]', + client_id: 'client_id_1', + nonce: '12345', })); return x; }) () @@ -305,7 +306,8 @@ var x = (await navigator.id.get({ provider: 'http://idp.example)" + base::NumberToString(https_server().port()) + R"(', - request: '[not a real request]', + client_id: 'client_id_1', + nonce: '12345', })); return x; }) ()
diff --git a/content/browser/worker_host/shared_worker_host.cc b/content/browser/worker_host/shared_worker_host.cc index 8da06a4..dccba89c 100644 --- a/content/browser/worker_host/shared_worker_host.cc +++ b/content/browser/worker_host/shared_worker_host.cc
@@ -350,7 +350,7 @@ network::mojom::URLLoaderFactoryParamsPtr SharedWorkerHost::CreateNetworkFactoryParamsForSubresources() { - url::Origin origin = instance().storage_key().origin(); + url::Origin origin = GetStorageKey().origin(); // TODO(https://crbug.com/1060832): Implement COEP reporter for shared // workers. @@ -432,9 +432,9 @@ mojo::PendingRemote<network::mojom::CrossOriginEmbedderPolicyReporter> coep_reporter; - GetProcessHost()->BindCacheStorage( - cross_origin_embedder_policy(), std::move(coep_reporter), - instance().storage_key(), std::move(receiver)); + GetProcessHost()->BindCacheStorage(cross_origin_embedder_policy(), + std::move(coep_reporter), GetStorageKey(), + std::move(receiver)); } void SharedWorkerHost::CreateCodeCacheHost( @@ -541,7 +541,11 @@ // top-level browsing context, which shouldn't be use for SharedWorkers used // in iframes. return net::NetworkIsolationKey::ToDoUseTopFrameOriginAsWell( - instance().storage_key().origin()); + GetStorageKey().origin()); +} + +const blink::StorageKey& SharedWorkerHost::GetStorageKey() const { + return instance().storage_key(); } void SharedWorkerHost::ReportNoBinderForInterface(const std::string& error) {
diff --git a/content/browser/worker_host/shared_worker_host.h b/content/browser/worker_host/shared_worker_host.h index 9154faf..864fb28 100644 --- a/content/browser/worker_host/shared_worker_host.h +++ b/content/browser/worker_host/shared_worker_host.h
@@ -50,6 +50,7 @@ namespace blink { class MessagePortChannel; class PendingURLLoaderFactoryBundle; +class StorageKey; } // namespace blink namespace content { @@ -176,6 +177,8 @@ net::NetworkIsolationKey GetNetworkIsolationKey() const; + const blink::StorageKey& GetStorageKey() const; + const base::UnguessableToken& GetReportingSource() const { return reporting_source_; }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/VideoFullscreenOrientationLockTest.java b/content/public/android/javatests/src/org/chromium/content/browser/VideoFullscreenOrientationLockTest.java index 73367178..5eb6aa1 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/VideoFullscreenOrientationLockTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/VideoFullscreenOrientationLockTest.java
@@ -23,6 +23,7 @@ import org.chromium.base.test.util.CriteriaNotSatisfiedException; import org.chromium.base.test.util.DisableIf; import org.chromium.base.test.util.DisabledTest; +import org.chromium.base.test.util.FlakyTest; import org.chromium.base.test.util.Restriction; import org.chromium.content_public.browser.test.ContentJUnit4ClassRunner; import org.chromium.content_public.browser.test.util.DOMUtils; @@ -194,6 +195,7 @@ @Test @MediumTest @Restriction({UiRestriction.RESTRICTION_TYPE_PHONE}) + @FlakyTest(message = "crbug.com/1228632") public void testExitFullscreenByRemovingVideo() throws Exception { // Start playback to guarantee it's properly loaded. Assert.assertTrue(DOMUtils.isMediaPaused(mActivityTestRule.getWebContents(), VIDEO_ID)); @@ -217,6 +219,7 @@ @Test @MediumTest @Restriction({UiRestriction.RESTRICTION_TYPE_PHONE}) + @FlakyTest(message = "crbug.com/1228632") public void testExitFullscreenWithNavigation() throws Exception { // Start playback to guarantee it's properly loaded. Assert.assertTrue(DOMUtils.isMediaPaused(mActivityTestRule.getWebContents(), VIDEO_ID));
diff --git a/content/public/browser/render_process_host.h b/content/public/browser/render_process_host.h index 65cf9ea..143c111 100644 --- a/content/public/browser/render_process_host.h +++ b/content/public/browser/render_process_host.h
@@ -491,7 +491,7 @@ // |render_frame_id| is the frame associated with |receiver|, or // MSG_ROUTING_NONE if |receiver| is associated with a worker. virtual void BindIndexedDB( - const url::Origin& origin, + const blink::StorageKey& storage_key, mojo::PendingReceiver<blink::mojom::IDBFactory> receiver) = 0; virtual void BindBucketManagerHost( const url::Origin& origin,
diff --git a/content/public/test/mock_render_process_host.cc b/content/public/test/mock_render_process_host.cc index b464b91a..60a2259a 100644 --- a/content/public/test/mock_render_process_host.cc +++ b/content/public/test/mock_render_process_host.cc
@@ -454,7 +454,7 @@ } void MockRenderProcessHost::BindIndexedDB( - const url::Origin& origin, + const blink::StorageKey& storage_key, mojo::PendingReceiver<blink::mojom::IDBFactory> receiver) { idb_factory_receiver_ = std::move(receiver); }
diff --git a/content/public/test/mock_render_process_host.h b/content/public/test/mock_render_process_host.h index 89eef11..743ec88 100644 --- a/content/public/test/mock_render_process_host.h +++ b/content/public/test/mock_render_process_host.h
@@ -180,7 +180,7 @@ mojo::PendingReceiver<blink::mojom::FileSystemAccessManager> receiver) override {} void BindIndexedDB( - const url::Origin& origin, + const blink::StorageKey& storage_key, mojo::PendingReceiver<blink::mojom::IDBFactory> receiver) override; void BindBucketManagerHost( const url::Origin& origin,
diff --git a/content/test/data/gpu/webgpu-import-video.html b/content/test/data/gpu/webgpu-import-video.html index 3134e5a4..98c642c 100644 --- a/content/test/data/gpu/webgpu-import-video.html +++ b/content/test/data/gpu/webgpu-import-video.html
@@ -6,6 +6,7 @@ video.src = './vc/teddy1_vp9_640x360_30fps.webm'; video.loop = true; video.muted = true; + await video.play(); // Test with two videos. The original implementation had a bug // where importing a second video would result in improper @@ -14,6 +15,7 @@ video2.src = './vc/teddy2_vp9_320x180_15fps.webm'; video2.loop = true; video2.muted = true; + await video2.play(); const adapter = navigator.gpu && await navigator.gpu.requestAdapter(); const device = await adapter.requestDevice(); @@ -27,7 +29,31 @@ format: swapChainFormat, }); + // TODO: Use getBindGroupLayout. We can't right now because SPIRV-Cross + // doesn't reflect external textures correctly. + const bindGroupLayout = device.createBindGroupLayout({ + entries: [ + { + binding: 0, + visibility: GPUShaderStage.FRAGMENT, + sampler: {type: "filtering"} + }, + { + binding: 1, + visibility: GPUShaderStage.FRAGMENT, + externalTexture: {} + },{ + binding: 2, + visibility: GPUShaderStage.FRAGMENT, + externalTexture: {} + } + ], + }); + + const pipelineLayout = device.createPipelineLayout({bindGroupLayouts: [bindGroupLayout]}); + const pipeline = device.createRenderPipeline({ + layout: pipelineLayout, vertex: { module: device.createShaderModule({ code: ` @@ -37,8 +63,8 @@ }; [[stage(vertex)]] -fn main([[builtin(vertex_index)]] VertexIndex : u32) -> VertexOutput { - let pos : array<vec3<f32>, 6> = array<vec3<f32>, 6>( +fn main([[builtin(vertex_index)]] idx : u32) -> VertexOutput { + var pos = array<vec3<f32>, 6>( vec3<f32>( 1.0, 1.0, 0.0), vec3<f32>( 1.0, -1.0, 0.0), vec3<f32>(-1.0, -1.0, 0.0), @@ -46,7 +72,7 @@ vec3<f32>(-1.0, -1.0, 0.0), vec3<f32>(-1.0, 1.0, 0.0) ); - let uv : array<vec2<f32>, 6> = array<vec2<f32>, 6>( + var uv = array<vec2<f32>, 6>( vec2<f32>(1.0, 0.0), vec2<f32>(1.0, 2.0), vec2<f32>(0.0, 2.0), @@ -56,8 +82,8 @@ ); var output : VertexOutput; - output.Position = vec4<f32>(pos[VertexIndex], 1.0); - output.fragUV = uv[VertexIndex]; + output.Position = vec4<f32>(pos[idx], 1.0); + output.fragUV = uv[idx]; return output; } `, @@ -68,17 +94,17 @@ module: device.createShaderModule({ code: ` [[binding(0), group(0)]] var mySampler: sampler; -[[binding(1), group(0)]] var myTexture: texture_2d<f32>; -[[binding(2), group(0)]] var myTexture2: texture_2d<f32>; +[[binding(1), group(0)]] var myTexture: texture_external; +[[binding(2), group(0)]] var myTexture2: texture_external; [[stage(fragment)]] fn main([[location(0)]] fragUV : vec2<f32>) -> [[location(0)]] vec4<f32> { var result : vec4<f32>; if (fragUV.y <= 1.0) { - result = textureSample(myTexture, mySampler, fragUV); + result = textureSampleLevel(myTexture, mySampler, fragUV); } else { var uv : vec2<f32> = vec2<f32>(fragUV.x, fragUV.y - 1.0); - result = textureSample(myTexture2, mySampler, uv); + result = textureSampleLevel(myTexture2, mySampler, uv); } return result; } @@ -94,15 +120,12 @@ }, }); - const linearSampler = device.createSampler({ - magFilter: 'linear', - minFilter: 'linear', - }); + const linearSampler = device.createSampler(); const renderPassDescriptor = { colorAttachments: [ { - attachment: undefined, // Assigned later + view: undefined, // Assigned later loadValue: { r: 0.0, g: 0.0, b: 0.0, a: 1.0 }, storeOp: 'store', }, @@ -110,18 +133,17 @@ }; function frame() { - renderPassDescriptor.colorAttachments[0].attachment = swapChain + renderPassDescriptor.colorAttachments[0].view = swapChain .getCurrentTexture() .createView(); - const videoTexture = device.experimentalImportTexture( - video, GPUTextureUsage.SAMPLED); - - const videoTexture2 = device.experimentalImportTexture( - video2, GPUTextureUsage.SAMPLED); + const externalTextureDescriptor = {source: video}; + const externalTextureDescriptor2 = {source: video2}; + const externalTexture = device.importExternalTexture(externalTextureDescriptor); + const externalTexture2 = device.importExternalTexture(externalTextureDescriptor2); const bindGroup = device.createBindGroup({ - layout: pipeline.getBindGroupLayout(0), + layout: bindGroupLayout, entries: [ { binding: 0, @@ -129,15 +151,14 @@ }, { binding: 1, - resource: videoTexture.createView(), + resource: externalTexture, }, { binding: 2, - resource: videoTexture2.createView(), - }, + resource: externalTexture2, + } ], }); - const commandEncoder = device.createCommandEncoder(); const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor); passEncoder.setPipeline(pipeline); @@ -146,15 +167,9 @@ passEncoder.endPass(); device.queue.submit([commandEncoder.finish()]); - // Destroy the texture after submit to promptly recycle resources. - videoTexture.destroy(); - videoTexture2.destroy(); - requestAnimationFrame(frame); } - await video.play(); - await video2.play(); requestAnimationFrame(frame); </script> </body>
diff --git a/extensions/browser/api/messaging/extension_message_port.cc b/extensions/browser/api/messaging/extension_message_port.cc index 6821512..d8cdee47 100644 --- a/extensions/browser/api/messaging/extension_message_port.cc +++ b/extensions/browser/api/messaging/extension_message_port.cc
@@ -170,6 +170,11 @@ CHECK(tab); frame_tracker_->TrackTabFrames(tab); if (include_child_frames) { + // TODO(https://crbug.com/1227787) We don't yet support MParch so make sure + // `include_child_frames` is only provided for primary pages. If `rfh` + // belongs to a non-primary page, then the ForEachFrame iteration below + // would actually correspond to a different page than `rfh`'s page. + CHECK(rfh->GetPage().IsPrimary()); tab->ForEachFrame(base::BindRepeating(&ExtensionMessagePort::RegisterFrame, base::Unretained(this))); } else {
diff --git a/fuchsia/engine/web_instance_host/web_instance_host.cc b/fuchsia/engine/web_instance_host/web_instance_host.cc index 07bda08f..df9b7e3 100644 --- a/fuchsia/engine/web_instance_host/web_instance_host.cc +++ b/fuchsia/engine/web_instance_host/web_instance_host.cc
@@ -373,7 +373,7 @@ switches::kWebglMSAASampleCount, }; - for (const auto& arg : args->DictItems()) { + for (const auto arg : args->DictItems()) { if (!base::Contains(kAllowedArgs, arg.first)) { // TODO(https://crbug.com/1032439): Increase severity and return false // once we have a mechanism for soft transitions of supported arguments.
diff --git a/gpu/command_buffer/service/raster_decoder.cc b/gpu/command_buffer/service/raster_decoder.cc index 0df7d28..2ada6fc 100644 --- a/gpu/command_buffer/service/raster_decoder.cc +++ b/gpu/command_buffer/service/raster_decoder.cc
@@ -2819,33 +2819,6 @@ return; } - std::vector<GrBackendSemaphore> begin_semaphores; - - std::unique_ptr<SharedImageRepresentationSkia::ScopedReadAccess> - source_scoped_access = source_shared_image->BeginScopedReadAccess( - &begin_semaphores, nullptr); - - if (!begin_semaphores.empty()) { - bool result = shared_context_state_->gr_context()->wait( - begin_semaphores.size(), begin_semaphores.data(), - /*deleteSemaphoresAfterWait=*/false); - DCHECK(result); - } - - if (!source_scoped_access) { - LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glReadbackImagePixels", - "Source shared image is not accessible"); - return; - } - - auto sk_image = - source_scoped_access->CreateSkImage(shared_context_state_->gr_context()); - if (!sk_image) { - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glReadbackImagePixels", - "Couldn't create SkImage for reading."); - return; - } - size_t byte_size = dst_info.computeByteSize(row_bytes); if (byte_size > UINT32_MAX) { LOCAL_SET_GL_ERROR( @@ -2871,6 +2844,47 @@ return; } + std::vector<GrBackendSemaphore> begin_semaphores; + std::vector<GrBackendSemaphore> end_semaphores; + + std::unique_ptr<SharedImageRepresentationSkia::ScopedReadAccess> + source_scoped_access = source_shared_image->BeginScopedReadAccess( + &begin_semaphores, &end_semaphores); + + if (!source_scoped_access) { + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glReadbackImagePixels", + "Source shared image is not accessible"); + return; + } + + if (!begin_semaphores.empty()) { + bool wait_result = shared_context_state_->gr_context()->wait( + begin_semaphores.size(), begin_semaphores.data(), + /*deleteSemaphoresAfterWait=*/false); + DCHECK(wait_result); + } + + if (!end_semaphores.empty()) { + // Ask skia to signal |end_semaphores| here, since we will synchronized + // read pixels from the shared image. + GrFlushInfo flush_info = { + .fNumSemaphores = end_semaphores.size(), + .fSignalSemaphores = end_semaphores.data(), + }; + AddVulkanCleanupTaskForSkiaFlush( + shared_context_state_->vk_context_provider(), &flush_info); + auto flush_result = shared_context_state_->gr_context()->flush(flush_info); + DCHECK(flush_result == GrSemaphoresSubmitted::kYes); + } + + auto sk_image = + source_scoped_access->CreateSkImage(shared_context_state_->gr_context()); + if (!sk_image) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glReadbackImagePixels", + "Couldn't create SkImage for reading."); + return; + } + bool success = sk_image->readPixels(dst_info, pixel_address, row_bytes, src_x, src_y); if (!success) {
diff --git a/headless/BUILD.gn b/headless/BUILD.gn index 2b5bd5a1..f9e3e8b 100644 --- a/headless/BUILD.gn +++ b/headless/BUILD.gn
@@ -264,8 +264,8 @@ # |headless_non_renderer| components. source_set("headless_shared_sources") { visibility = [ - "//headless:headless", - "//headless:headless_non_renderer", + ":headless", + ":headless_non_renderer", ] defines = [] @@ -309,10 +309,13 @@ ] if (!is_fuchsia) { - deps += [ "//components/crash/content/browser" ] + deps += [ + "//components/crash/content/browser", + "//components/crash/core/app", + ] } - if (is_component_build && is_win) { - deps += [ "//components/crash/core/app:crash_export_thunks" ] + if (is_win) { + deps += [ "//sandbox" ] } configs += [ ":inside_headless_component" ] @@ -434,16 +437,26 @@ ":headless_shared_sources", ":version_header", "//base:base_static", + "//build:branding_buildflags", "//build:chromeos_buildflags", "//components/cookie_config", + "//components/embedder_support", "//components/keyed_service/content", + "//components/policy:policy_code_generate", + "//components/policy/core/browser", + "//components/policy/core/common:common_constants", + "//components/pref_registry", + "//components/prefs", "//components/profile_metrics", "//components/security_state/core", + "//content/public/app", "//content/public/browser", "//content/public/common", + "//printing/buildflags", "//services/cert_verifier/public/mojom", "//services/device/public/cpp/geolocation", "//services/service_manager/public/cpp", + "//third_party/inspector_protocol:crdtp", "//ui/base", "//ui/base/clipboard", "//ui/compositor", @@ -454,7 +467,12 @@ ] if (enable_basic_printing) { - deps += [ "//components/printing/browser" ] + deps += [ + "//components/printing/browser", + "//components/printing/common:mojo_interfaces", + "//printing", + "//printing/mojom", + ] } if (is_component_build) { @@ -492,10 +510,10 @@ ] if (!is_fuchsia) { - deps += [ "//components/crash/content/browser" ] - } - if (is_win) { - deps += [ "//components/crash/core/app:crash_export_thunks" ] + deps += [ + "//components/crash/content/browser", + "//components/crash/core/app", + ] } if (enable_basic_printing) { @@ -507,8 +525,15 @@ ] } + if (headless_use_prefs) { + deps += [ "//components/os_crypt" ] + } + if (headless_use_policy) { - deps += [ "//components/policy/content" ] + deps += [ + "//components/policy/content", + "//components/user_prefs", + ] } } @@ -593,11 +618,24 @@ deps = [ ":headless", + "//build:chromeos_buildflags", "//components/crash/core/common", + "//components/security_state/content", + "//components/security_state/core", + "//content/public/app", + "//content/public/browser", + "//content/public/common", + "//content/public/renderer", + "//content/public/utility", + "//printing/buildflags", "//third_party/blink/public:blink_headers", "//ui/base", + "//ui/compositor", "//v8", ] + if (use_ozone) { + deps += [ "//ui/ozone" ] + } if (enable_basic_printing) { deps += [ "//components/printing/renderer", @@ -614,6 +652,10 @@ "$root_gen_dir/headless/embedded_resource_pak.h", ] } + + if (is_mac || is_win || is_linux || is_chromeos) { + deps += [ "//components/crash/core/app" ] + } } } else { # For component builds all dependencies are already included in the headless @@ -660,6 +702,8 @@ sources += [ "lib/browser/headless_printing_unittest.cc" ] deps += [ "//components/printing/browser", + "//printing", + "//printing/buildflags", "//third_party/blink/public:blink", ] } @@ -737,8 +781,12 @@ ":headless_shell_lib", "//base", "//cc:test_support", + "//components/policy/core/browser", "//components/security_state/content", + "//content/test:browsertest_support", "//content/test:test_support", + "//net:test_support", + "//printing/buildflags", "//services/network/public/mojom", "//testing/gmock", "//testing/gtest", @@ -753,6 +801,7 @@ deps += [ "//components/printing/browser", "//pdf", + "//printing", ] } @@ -777,12 +826,19 @@ deps = [ ":headless_non_renderer", "//build:branding_buildflags", + "//components/crash/core/app:run_as_crashpad_handler", + "//components/embedder_support", "//content:sandbox_helper_win", + "//content/public/app", "//content/public/browser", "//content/public/common", "//net", + "//printing/buildflags", "//sandbox", ] + if (headless_use_policy) { + deps += [ "//components/policy/content" ] + } configs += [ ":headless_defines_config" ] } } @@ -809,11 +865,15 @@ deps = [ ":headless_renderer", "//build:branding_buildflags", + "//components/embedder_support", "//components/security_state/content", + "//content", "//content/public/app", "//content/public/browser", "//content/public/child:child", "//content/public/common", + "//content/public/utility", + "//printing/buildflags", ] public_deps = [ "//base" ] @@ -843,7 +903,6 @@ defines = [ "HEADLESS_USE_CRASHPAD" ] deps += [ - "//components/crash/core/app:crash_export_thunks", "//components/crash/core/app:run_as_crashpad_handler", "//content:sandbox_helper_win", "//sandbox", @@ -854,6 +913,10 @@ deps += [ "//components/os_crypt" ] } + if (is_win || (is_posix && !is_mac)) { + deps += [ "//components/crash/core/app" ] + } + configs += [ ":headless_defines_config" ] } @@ -881,7 +944,10 @@ } if (is_win) { - deps += [ "//build/win:default_exe_manifest" ] + deps += [ + "//build/win:default_exe_manifest", + "//content/public/app", + ] } if (is_mac) { @@ -906,8 +972,15 @@ deps = [ ":headless_shell_lib", + "//content", + "//sandbox", "//skia", # we need this to override font render hinting in headless build + "//ui/gfx/geometry", ] + if (is_win) { + deps += [ "//content/public/app" ] + } + configs += [ ":headless_defines_config" ] }
diff --git a/headless/app/headless_shell.cc b/headless/app/headless_shell.cc index f15a5bd7..3cd013e 100644 --- a/headless/app/headless_shell.cc +++ b/headless/app/headless_shell.cc
@@ -52,13 +52,13 @@ #include "ui/gfx/geometry/size.h" #if defined(OS_WIN) -#include "components/crash/core/app/crash_switches.h" +#include "components/crash/core/app/crash_switches.h" // nogncheck #include "components/crash/core/app/run_as_crashpad_handler_win.h" #include "sandbox/win/src/sandbox_types.h" #endif #if defined(OS_MAC) -#include "components/os_crypt/os_crypt_switches.h" +#include "components/os_crypt/os_crypt_switches.h" // nogncheck #endif #if defined(HEADLESS_USE_POLICY)
diff --git a/headless/app/headless_shell_main.cc b/headless/app/headless_shell_main.cc index a51bc44..f2457fa 100644 --- a/headless/app/headless_shell_main.cc +++ b/headless/app/headless_shell_main.cc
@@ -7,7 +7,7 @@ #if defined(OS_WIN) #include "content/public/app/sandbox_helper_win.h" -#include "sandbox/win/src/sandbox_types.h" +#include "sandbox/win/src/sandbox_types.h" // nogncheck #elif defined(OS_MAC) #include "base/check.h" #include "sandbox/mac/seatbelt_exec.h"
diff --git a/headless/lib/browser/headless_browser_context_impl.cc b/headless/lib/browser/headless_browser_context_impl.cc index 86f66e5..d5cfa9e 100644 --- a/headless/lib/browser/headless_browser_context_impl.cc +++ b/headless/lib/browser/headless_browser_context_impl.cc
@@ -27,7 +27,7 @@ #include "ui/base/resource/resource_bundle.h" #if defined(HEADLESS_USE_POLICY) -#include "components/user_prefs/user_prefs.h" +#include "components/user_prefs/user_prefs.h" // nogncheck #endif namespace headless {
diff --git a/headless/lib/browser/headless_browser_main_parts.cc b/headless/lib/browser/headless_browser_main_parts.cc index b6d0091..e8d5d3e7c 100644 --- a/headless/lib/browser/headless_browser_main_parts.cc +++ b/headless/lib/browser/headless_browser_main_parts.cc
@@ -14,7 +14,7 @@ #include "headless/lib/browser/headless_screen.h" #if defined(HEADLESS_USE_PREFS) -#include "components/os_crypt/os_crypt.h" +#include "components/os_crypt/os_crypt.h" // nogncheck #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/in_memory_pref_store.h" #include "components/prefs/json_pref_store.h"
diff --git a/headless/lib/browser/headless_content_browser_client.cc b/headless/lib/browser/headless_content_browser_client.cc index a828ac9a..054f7a7 100644 --- a/headless/lib/browser/headless_content_browser_client.cc +++ b/headless/lib/browser/headless_content_browser_client.cc
@@ -53,7 +53,7 @@ #if defined(HEADLESS_USE_POLICY) #include "components/policy/content/policy_blocklist_navigation_throttle.h" -#include "components/policy/core/common/policy_service.h" +#include "components/policy/core/common/policy_service.h" // nogncheck http://crbug.com/1227148 #include "content/public/browser/navigation_handle.h" #include "content/public/browser/navigation_throttle.h" #endif // defined(HEADLESS_USE_POLICY)
diff --git a/headless/lib/browser/headless_request_context_manager.cc b/headless/lib/browser/headless_request_context_manager.cc index 3b54e857..fa0e7e7 100644 --- a/headless/lib/browser/headless_request_context_manager.cc +++ b/headless/lib/browser/headless_request_context_manager.cc
@@ -26,7 +26,7 @@ #include "services/network/url_request_context_builder_mojo.h" #if defined(HEADLESS_USE_PREFS) -#include "components/os_crypt/os_crypt.h" +#include "components/os_crypt/os_crypt.h" // nogncheck #include "content/public/common/network_service_util.h" #endif
diff --git a/headless/lib/browser/policy/headless_browser_policy_connector.cc b/headless/lib/browser/policy/headless_browser_policy_connector.cc index e36021a5..ee63ed99 100644 --- a/headless/lib/browser/policy/headless_browser_policy_connector.cc +++ b/headless/lib/browser/policy/headless_browser_policy_connector.cc
@@ -14,9 +14,9 @@ #include "base/task/thread_pool.h" #include "build/branding_buildflags.h" #include "build/build_config.h" -#include "components/policy/core/browser/configuration_policy_handler.h" -#include "components/policy/core/browser/url_blocklist_policy_handler.h" -#include "components/policy/core/common/async_policy_provider.h" +#include "components/policy/core/browser/configuration_policy_handler.h" // nogncheck http://crbug.com/1227148 +#include "components/policy/core/browser/url_blocklist_policy_handler.h" // nogncheck http://crbug.com/1227148 +#include "components/policy/core/common/async_policy_provider.h" // nogncheck http://crbug.com/1227148 #include "components/policy/core/common/policy_pref_names.h" #include "components/policy/policy_constants.h" #include "headless/lib/browser/headless_pref_names.h" @@ -33,7 +33,7 @@ #include "components/policy/core/common/policy_loader_mac.h" #include "components/policy/core/common/preferences_mac.h" #elif defined(OS_POSIX) && !defined(OS_ANDROID) -#include "components/policy/core/common/config_dir_policy_loader.h" +#include "components/policy/core/common/config_dir_policy_loader.h" // nogncheck http://crbug.com/1227148 #endif namespace policy {
diff --git a/headless/lib/browser/policy/headless_browser_policy_connector.h b/headless/lib/browser/policy/headless_browser_policy_connector.h index b067c01..e15bba06 100644 --- a/headless/lib/browser/policy/headless_browser_policy_connector.h +++ b/headless/lib/browser/policy/headless_browser_policy_connector.h
@@ -6,8 +6,8 @@ #define HEADLESS_LIB_BROWSER_POLICY_HEADLESS_BROWSER_POLICY_CONNECTOR_H_ #include "base/memory/ref_counted.h" -#include "components/policy/core/browser/browser_policy_connector.h" -#include "components/policy/core/browser/configuration_policy_pref_store.h" +#include "components/policy/core/browser/browser_policy_connector.h" // nogncheck http://crbug.com/1227148 +#include "components/policy/core/browser/configuration_policy_pref_store.h" // nogncheck http://crbug.com/1227148 #include "services/network/public/cpp/shared_url_loader_factory.h" namespace policy {
diff --git a/headless/lib/browser/policy/headless_mode_policy.h b/headless/lib/browser/policy/headless_mode_policy.h index da2c8896..f73b04a 100644 --- a/headless/lib/browser/policy/headless_mode_policy.h +++ b/headless/lib/browser/policy/headless_mode_policy.h
@@ -5,7 +5,7 @@ #ifndef HEADLESS_LIB_BROWSER_POLICY_HEADLESS_MODE_POLICY_H_ #define HEADLESS_LIB_BROWSER_POLICY_HEADLESS_MODE_POLICY_H_ -#include "components/policy/core/browser/configuration_policy_handler.h" +#include "components/policy/core/browser/configuration_policy_handler.h" // nogncheck http://crbug.com/1227148 #include "headless/public/headless_export.h" class PrefService;
diff --git a/headless/lib/browser/policy/headless_policies.cc b/headless/lib/browser/policy/headless_policies.cc index f0edc59..b48ac82 100644 --- a/headless/lib/browser/policy/headless_policies.cc +++ b/headless/lib/browser/policy/headless_policies.cc
@@ -5,7 +5,7 @@ #include "headless/lib/browser/policy/headless_policies.h" #include "base/check.h" -#include "components/policy/core/browser/url_blocklist_manager.h" +#include "components/policy/core/browser/url_blocklist_manager.h" // nogncheck http://crbug.com/1227148 #include "components/policy/policy_constants.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/pref_service.h"
diff --git a/headless/lib/browser/protocol/headless_handler.cc b/headless/lib/browser/protocol/headless_handler.cc index 77d3f934..bdc42f0 100644 --- a/headless/lib/browser/protocol/headless_handler.cc +++ b/headless/lib/browser/protocol/headless_handler.cc
@@ -14,7 +14,7 @@ #include "components/viz/common/switches.h" #include "content/public/common/content_switches.h" #include "headless/lib/browser/headless_browser_impl.h" -#include "headless/lib/browser/headless_web_contents_impl.h" +#include "headless/lib/browser/headless_web_contents_impl.h" // nogncheck http://crbug.com/1227378 #include "third_party/skia/include/core/SkBitmap.h" #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/codec/jpeg_codec.h"
diff --git a/headless/public/headless_browser.h b/headless/public/headless_browser.h index dfd6be4..9e2b6f5b 100644 --- a/headless/public/headless_browser.h +++ b/headless/public/headless_browser.h
@@ -15,6 +15,7 @@ #include "base/files/file_path.h" #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "build/build_config.h" #include "headless/public/headless_browser_context.h" #include "headless/public/headless_devtools_channel.h" #include "headless/public/headless_export.h"
diff --git a/headless/test/headless_browser_browsertest.cc b/headless/test/headless_browser_browsertest.cc index f7f76a6..083f1de 100644 --- a/headless/test/headless_browser_browsertest.cc +++ b/headless/test/headless_browser_browsertest.cc
@@ -52,7 +52,7 @@ #include "ui/gfx/geometry/size.h" #if defined(OS_MAC) -#include "third_party/crashpad/crashpad/client/crash_report_database.h" +#include "third_party/crashpad/crashpad/client/crash_report_database.h" // nogncheck #endif using testing::UnorderedElementsAre;
diff --git a/infra/config/generated/cr-buildbucket.cfg b/infra/config/generated/cr-buildbucket.cfg index 96ee2dc5..bff277c3 100644 --- a/infra/config/generated/cr-buildbucket.cfg +++ b/infra/config/generated/cr-buildbucket.cfg
@@ -28911,6 +28911,74 @@ } } builders { + name: "linux-exp-code-coverage" + swarming_host: "chromium-swarm.appspot.com" + swarming_tags: "vpython:native-python-wrapper" + dimensions: "builderless:1" + dimensions: "cores:32" + dimensions: "cpu:x86-64" + dimensions: "os:Ubuntu-18.04" + dimensions: "pool:luci.chromium.ci" + dimensions: "ssd:1" + exe { + cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" + cipd_version: "refs/heads/master" + cmd: "luciexe" + } + properties: "{\"$build/code_coverage\":{\"coverage_reference_commit\":\"c942891373445199f69afd905965ad1e89cdee09\",\"coverage_test_types\":[\"overall\"],\"use_clang_coverage\":true},\"$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\"},\"$recipe_engine/resultdb/test_presentation\":{\"column_keys\":[],\"grouping_keys\":[\"status\",\"v.test_suite\"]},\"builder_group\":\"chromium.fyi\",\"recipe\":\"chromium\"}" + execution_timeout_secs: 72000 + 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/.+" + } + } + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "blink_web_tests_ci_test_results" + test_results { + predicate { + test_id_regexp: "ninja://[^/]*blink_web_tests/.+" + } + } + } + history_options { + use_invocation_timestamp: true + } + } + } + builders { name: "linux-extended-tracing-rel" 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 a04a116..486374a 100644 --- a/infra/config/generated/luci-milo.cfg +++ b/infra/config/generated/luci-milo.cfg
@@ -6005,6 +6005,11 @@ short_name: "lnx" } builders { + name: "buildbucket/luci.chromium.ci/linux-exp-code-coverage" + category: "code_coverage" + short_name: "lnx" + } + builders { name: "buildbucket/luci.chromium.ci/linux-chromeos-code-coverage" category: "code_coverage" short_name: "lcr"
diff --git a/infra/config/generated/luci-scheduler.cfg b/infra/config/generated/luci-scheduler.cfg index 3a54a84..fc00de38 100644 --- a/infra/config/generated/luci-scheduler.cfg +++ b/infra/config/generated/luci-scheduler.cfg
@@ -5725,6 +5725,17 @@ } } job { + id: "linux-exp-code-coverage" + realm: "ci" + schedule: "triggered" + acl_sets: "ci" + buildbucket { + server: "cr-buildbucket.appspot.com" + bucket: "luci.chromium.ci" + builder: "linux-exp-code-coverage" + } +} +job { id: "linux-extended-tracing-rel" realm: "ci" acl_sets: "ci"
diff --git a/infra/config/subprojects/chromium/ci.star b/infra/config/subprojects/chromium/ci.star index a97dc6e..0df96ce 100644 --- a/infra/config/subprojects/chromium/ci.star +++ b/infra/config/subprojects/chromium/ci.star
@@ -4248,6 +4248,19 @@ ) ci.fyi_coverage_builder( + name = "linux-exp-code-coverage", + console_view_entry = consoles.console_view_entry( + category = "code_coverage", + short_name = "lnx", + ), + use_clang_coverage = True, + coverage_test_types = ["overall"], + schedule = "triggered", + coverage_reference_commit = "c942891373445199f69afd905965ad1e89cdee09", + triggered_by = [], +) + +ci.fyi_coverage_builder( name = "linux-lacros-code-coverage", console_view_entry = consoles.console_view_entry( category = "code_coverage",
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd index 7110d44..2b2194f 100644 --- a/ios/chrome/app/strings/ios_strings.grd +++ b/ios/chrome/app/strings/ios_strings.grd
@@ -336,8 +336,8 @@ <message name="IDS_IOS_AUTOFILL_SAVE_CARD_BADGE_HINT" desc="Accessibility Hint for the Save Card button which presents the current options to Save a Card. This is spoken by VoiceOver. [Length:Unlimited] [iOS only]"> Options to Save Card </message> - <message name="IDS_IOS_AUTOFILL_HONORIFIC_PREFIX" desc="Title of the field of a profile address representing the title that can be auto-filled by Chrome. [iOS only]" meaning="A 'Title' field in a web form could be a prefix like Ms., Mx., or Dr. or a position held, like Captain or Rabbi. [Length: 15em]"> - Title + <message name="IDS_IOS_AUTOFILL_HONORIFIC_PREFIX" desc="Title of the field of a profile address representing the title that can be auto-filled by Chrome. A 'Title' field in a web form could be a prefix like Ms., Mx., or Dr. or a position held, like Captain or Rabbi. [Length: 15em] [iOS only]" meaning="Honorific"> + Title </message> <message name="IDS_IOS_AUTOFILL_FULLNAME" desc="Title of the field of a profile address representing the full name of the addressee. [Length: 15em] [iOS only]"> Full Name
diff --git a/ios/chrome/browser/browsing_data/browsing_data_remover_impl.mm b/ios/chrome/browser/browsing_data/browsing_data_remover_impl.mm index ae8bc27..d8f6e13 100644 --- a/ios/chrome/browser/browsing_data/browsing_data_remover_impl.mm +++ b/ios/chrome/browser/browsing_data/browsing_data_remover_impl.mm
@@ -422,8 +422,11 @@ .get(); if (password_store) { + // It doesn't matter whether any logins were removed so bool argument can + // be omitted. password_store->RemoveLoginsCreatedBetween( - delete_begin, delete_end, CreatePendingTaskCompletionClosure()); + delete_begin, delete_end, + IgnoreArgument<bool>(CreatePendingTaskCompletionClosure())); } }
diff --git a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/autofill_address_profile/save_address_profile_infobar_modal_interaction_handler.h b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/autofill_address_profile/save_address_profile_infobar_modal_interaction_handler.h index 2d48ff45..ace6325f 100644 --- a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/autofill_address_profile/save_address_profile_infobar_modal_interaction_handler.h +++ b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/autofill_address_profile/save_address_profile_infobar_modal_interaction_handler.h
@@ -5,6 +5,8 @@ #ifndef IOS_CHROME_BROWSER_INFOBARS_OVERLAYS_BROWSER_AGENT_INTERACTION_HANDLERS_AUTOFILL_ADDRESS_PROFILE_SAVE_ADDRESS_PROFILE_INFOBAR_MODAL_INTERACTION_HANDLER_H_ #define IOS_CHROME_BROWSER_INFOBARS_OVERLAYS_BROWSER_AGENT_INTERACTION_HANDLERS_AUTOFILL_ADDRESS_PROFILE_SAVE_ADDRESS_PROFILE_INFOBAR_MODAL_INTERACTION_HANDLER_H_ +#include <CoreFoundation/CoreFoundation.h> + #import "ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/common/infobar_modal_interaction_handler.h" class InfoBarIOS;
diff --git a/ios/chrome/browser/main/browser_impl.h b/ios/chrome/browser/main/browser_impl.h index c0455af..a8a37d7b 100644 --- a/ios/chrome/browser/main/browser_impl.h +++ b/ios/chrome/browser/main/browser_impl.h
@@ -5,11 +5,12 @@ #ifndef IOS_CHROME_BROWSER_MAIN_BROWSER_IMPL_H_ #define IOS_CHROME_BROWSER_MAIN_BROWSER_IMPL_H_ -#import "ios/chrome/browser/main/browser.h" +#include <CoreFoundation/CoreFoundation.h> #include "base/gtest_prod_util.h" #include "base/macros.h" #include "base/observer_list.h" +#import "ios/chrome/browser/main/browser.h" class ChromeBrowserState; @class SceneState;
diff --git a/ios/chrome/browser/main/browser_observer_bridge.h b/ios/chrome/browser/main/browser_observer_bridge.h index d5c62333e..c0547a3b 100644 --- a/ios/chrome/browser/main/browser_observer_bridge.h +++ b/ios/chrome/browser/main/browser_observer_bridge.h
@@ -5,6 +5,8 @@ #ifndef IOS_CHROME_BROWSER_MAIN_BROWSER_OBSERVER_BRIDGE_H_ #define IOS_CHROME_BROWSER_MAIN_BROWSER_OBSERVER_BRIDGE_H_ +#include <CoreFoundation/CoreFoundation.h> + #include "base/scoped_observation.h" #import "ios/chrome/browser/main/browser.h" #import "ios/chrome/browser/main/browser_observer.h"
diff --git a/ios/chrome/browser/main/browser_observer_bridge.mm b/ios/chrome/browser/main/browser_observer_bridge.mm index f9f3094..0e7036b 100644 --- a/ios/chrome/browser/main/browser_observer_bridge.mm +++ b/ios/chrome/browser/main/browser_observer_bridge.mm
@@ -4,6 +4,8 @@ #import "ios/chrome/browser/main/browser_observer_bridge.h" +#include <CoreFoundation/CoreFoundation.h> + #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." #endif
diff --git a/ios/chrome/browser/main/test_browser.h b/ios/chrome/browser/main/test_browser.h index 53575f5..8e9ee24 100644 --- a/ios/chrome/browser/main/test_browser.h +++ b/ios/chrome/browser/main/test_browser.h
@@ -7,6 +7,8 @@ #include "ios/chrome/browser/main/browser.h" +#include <CoreFoundation/CoreFoundation.h> + #include "base/macros.h" #include "base/observer_list.h" #import "ios/chrome/browser/web_state_list/fake_web_state_list_delegate.h"
diff --git a/ios/chrome/browser/notification_promo_unittest.cc b/ios/chrome/browser/notification_promo_unittest.cc index 67a55cf..f24d3e5 100644 --- a/ios/chrome/browser/notification_promo_unittest.cc +++ b/ios/chrome/browser/notification_promo_unittest.cc
@@ -102,7 +102,7 @@ ASSERT_TRUE(payload); ASSERT_TRUE(payload->is_dict()); - for (const auto& pair : payload->DictItems()) { + for (const auto pair : payload->DictItems()) { field_trial_params[pair.first] = pair.second.is_string() ? pair.second.GetString() : std::string(); }
diff --git a/ios/chrome/browser/overlays/public/infobar_banner/add_to_reading_list_infobar_banner_overlay_request_config.h b/ios/chrome/browser/overlays/public/infobar_banner/add_to_reading_list_infobar_banner_overlay_request_config.h index e668a83..b8cb1dc 100644 --- a/ios/chrome/browser/overlays/public/infobar_banner/add_to_reading_list_infobar_banner_overlay_request_config.h +++ b/ios/chrome/browser/overlays/public/infobar_banner/add_to_reading_list_infobar_banner_overlay_request_config.h
@@ -5,6 +5,8 @@ #ifndef IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_INFOBAR_BANNER_ADD_TO_READING_LIST_INFOBAR_BANNER_OVERLAY_REQUEST_CONFIG_H_ #define IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_INFOBAR_BANNER_ADD_TO_READING_LIST_INFOBAR_BANNER_OVERLAY_REQUEST_CONFIG_H_ +#include <CoreFoundation/CoreFoundation.h> + #include "ios/chrome/browser/overlays/public/overlay_request_config.h" #include "ios/chrome/browser/overlays/public/overlay_user_data.h"
diff --git a/ios/chrome/browser/overlays/public/infobar_banner/save_address_profile_infobar_banner_overlay_request_config.h b/ios/chrome/browser/overlays/public/infobar_banner/save_address_profile_infobar_banner_overlay_request_config.h index cd66a60..1cbf0ef9 100644 --- a/ios/chrome/browser/overlays/public/infobar_banner/save_address_profile_infobar_banner_overlay_request_config.h +++ b/ios/chrome/browser/overlays/public/infobar_banner/save_address_profile_infobar_banner_overlay_request_config.h
@@ -5,6 +5,8 @@ #ifndef IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_INFOBAR_BANNER_SAVE_ADDRESS_PROFILE_INFOBAR_BANNER_OVERLAY_REQUEST_CONFIG_H_ #define IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_INFOBAR_BANNER_SAVE_ADDRESS_PROFILE_INFOBAR_BANNER_OVERLAY_REQUEST_CONFIG_H_ +#include <CoreFoundation/CoreFoundation.h> + #include <string> #include "ios/chrome/browser/overlays/public/overlay_request_config.h"
diff --git a/ios/chrome/browser/overlays/public/infobar_banner/save_card_infobar_banner_overlay_request_config.h b/ios/chrome/browser/overlays/public/infobar_banner/save_card_infobar_banner_overlay_request_config.h index f74c333..f290b5ca5 100644 --- a/ios/chrome/browser/overlays/public/infobar_banner/save_card_infobar_banner_overlay_request_config.h +++ b/ios/chrome/browser/overlays/public/infobar_banner/save_card_infobar_banner_overlay_request_config.h
@@ -5,6 +5,8 @@ #ifndef IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_INFOBAR_BANNER_SAVE_CARD_INFOBAR_BANNER_OVERLAY_REQUEST_CONFIG_H_ #define IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_INFOBAR_BANNER_SAVE_CARD_INFOBAR_BANNER_OVERLAY_REQUEST_CONFIG_H_ +#include <CoreFoundation/CoreFoundation.h> + #include <string> #include "ios/chrome/browser/overlays/public/overlay_request_config.h"
diff --git a/ios/chrome/browser/overlays/public/infobar_banner/save_password_infobar_banner_overlay.h b/ios/chrome/browser/overlays/public/infobar_banner/save_password_infobar_banner_overlay.h index 51167e1d..2a8e024 100644 --- a/ios/chrome/browser/overlays/public/infobar_banner/save_password_infobar_banner_overlay.h +++ b/ios/chrome/browser/overlays/public/infobar_banner/save_password_infobar_banner_overlay.h
@@ -5,6 +5,8 @@ #ifndef IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_INFOBAR_BANNER_SAVE_PASSWORD_INFOBAR_BANNER_OVERLAY_H_ #define IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_INFOBAR_BANNER_SAVE_PASSWORD_INFOBAR_BANNER_OVERLAY_H_ +#include <CoreFoundation/CoreFoundation.h> + #include "ios/chrome/browser/overlays/public/overlay_request_config.h" #include "ios/chrome/browser/overlays/public/overlay_user_data.h"
diff --git a/ios/chrome/browser/overlays/public/infobar_banner/translate_infobar_banner_overlay_request_config.h b/ios/chrome/browser/overlays/public/infobar_banner/translate_infobar_banner_overlay_request_config.h index 616ad25..4c4a387 100644 --- a/ios/chrome/browser/overlays/public/infobar_banner/translate_infobar_banner_overlay_request_config.h +++ b/ios/chrome/browser/overlays/public/infobar_banner/translate_infobar_banner_overlay_request_config.h
@@ -5,6 +5,8 @@ #ifndef IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_INFOBAR_BANNER_TRANSLATE_INFOBAR_BANNER_OVERLAY_REQUEST_CONFIG_H_ #define IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_INFOBAR_BANNER_TRANSLATE_INFOBAR_BANNER_OVERLAY_REQUEST_CONFIG_H_ +#include <CoreFoundation/CoreFoundation.h> + #include "components/translate/core/browser/translate_step.h" #include "ios/chrome/browser/overlays/public/overlay_request_config.h" #include "ios/chrome/browser/overlays/public/overlay_user_data.h"
diff --git a/ios/chrome/browser/overlays/public/infobar_banner/update_password_infobar_banner_overlay.h b/ios/chrome/browser/overlays/public/infobar_banner/update_password_infobar_banner_overlay.h index 40e9bf3..41a3f59 100644 --- a/ios/chrome/browser/overlays/public/infobar_banner/update_password_infobar_banner_overlay.h +++ b/ios/chrome/browser/overlays/public/infobar_banner/update_password_infobar_banner_overlay.h
@@ -5,6 +5,8 @@ #ifndef IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_INFOBAR_BANNER_UPDATE_PASSWORD_INFOBAR_BANNER_OVERLAY_H_ #define IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_INFOBAR_BANNER_UPDATE_PASSWORD_INFOBAR_BANNER_OVERLAY_H_ +#include <CoreFoundation/CoreFoundation.h> + #include "ios/chrome/browser/overlays/public/overlay_request_config.h" #include "ios/chrome/browser/overlays/public/overlay_user_data.h"
diff --git a/ios/chrome/browser/overlays/public/infobar_modal/password_infobar_modal_overlay_request_config.h b/ios/chrome/browser/overlays/public/infobar_modal/password_infobar_modal_overlay_request_config.h index a39d68f..53118a3 100644 --- a/ios/chrome/browser/overlays/public/infobar_modal/password_infobar_modal_overlay_request_config.h +++ b/ios/chrome/browser/overlays/public/infobar_modal/password_infobar_modal_overlay_request_config.h
@@ -5,6 +5,8 @@ #ifndef IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_INFOBAR_MODAL_PASSWORD_INFOBAR_MODAL_OVERLAY_REQUEST_CONFIG_H_ #define IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_INFOBAR_MODAL_PASSWORD_INFOBAR_MODAL_OVERLAY_REQUEST_CONFIG_H_ +#include <CoreFoundation/CoreFoundation.h> + #include "ios/chrome/browser/overlays/public/overlay_request_config.h" class InfoBarIOS;
diff --git a/ios/chrome/browser/passwords/password_manager_app_interface.mm b/ios/chrome/browser/passwords/password_manager_app_interface.mm index c687870..edd69e8 100644 --- a/ios/chrome/browser/passwords/password_manager_app_interface.mm +++ b/ios/chrome/browser/passwords/password_manager_app_interface.mm
@@ -97,7 +97,7 @@ .get(); // Remove credentials stored during executing the test. passwordStore->RemoveLoginsCreatedBetween(base::Time(), base::Time::Now(), - base::OnceClosure()); + base::DoNothing()); } + (int)storedCredentialsCount {
diff --git a/ios/chrome/browser/passwords/save_passwords_consumer.h b/ios/chrome/browser/passwords/save_passwords_consumer.h index b897814..456c4db 100644 --- a/ios/chrome/browser/passwords/save_passwords_consumer.h +++ b/ios/chrome/browser/passwords/save_passwords_consumer.h
@@ -5,6 +5,8 @@ #ifndef IOS_CHROME_BROWSER_PASSWORDS_SAVE_PASSWORDS_CONSUMER_H_ #define IOS_CHROME_BROWSER_PASSWORDS_SAVE_PASSWORDS_CONSUMER_H_ +#include <CoreFoundation/CoreFoundation.h> + #include <memory> #include <vector>
diff --git a/ios/chrome/browser/policy/policy_watcher_browser_agent.h b/ios/chrome/browser/policy/policy_watcher_browser_agent.h index 181bffd..7252ad1 100644 --- a/ios/chrome/browser/policy/policy_watcher_browser_agent.h +++ b/ios/chrome/browser/policy/policy_watcher_browser_agent.h
@@ -5,6 +5,8 @@ #ifndef IOS_CHROME_BROWSER_POLICY_POLICY_WATCHER_BROWSER_AGENT_H_ #define IOS_CHROME_BROWSER_POLICY_POLICY_WATCHER_BROWSER_AGENT_H_ +#include <CoreFoundation/CoreFoundation.h> + #include <memory> #include "base/macros.h"
diff --git a/ios/chrome/browser/providers/BUILD.gn b/ios/chrome/browser/providers/BUILD.gn index 45c4dbcd..4f5f3b02 100644 --- a/ios/chrome/browser/providers/BUILD.gn +++ b/ios/chrome/browser/providers/BUILD.gn
@@ -53,6 +53,7 @@ # The individual API implementations. "//ios/chrome/browser/providers/modals:chromium_modals", + "//ios/chrome/browser/providers/text_zoom:chromium_text_zoom", # The provider API needs to provide MaterialDesignComponent API (as the # internal provider provides an alternate implementation).
diff --git a/ios/chrome/browser/providers/text_zoom/BUILD.gn b/ios/chrome/browser/providers/text_zoom/BUILD.gn new file mode 100644 index 0000000..efe34d2 --- /dev/null +++ b/ios/chrome/browser/providers/text_zoom/BUILD.gn
@@ -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. + +source_set("chromium_text_zoom") { + configs += [ "//build/config/compiler:enable_arc" ] + sources = [ "chromium_text_zoom.mm" ] + deps = [ + "//ios/chrome/browser/web:feature_flags", + "//ios/public/provider/chrome/browser:font_size_java_script_feature", + "//ios/public/provider/chrome/browser/text_zoom:text_zoom_api", + "//ui/base", + ] +}
diff --git a/ios/chrome/browser/providers/text_zoom/chromium_text_zoom.mm b/ios/chrome/browser/providers/text_zoom/chromium_text_zoom.mm new file mode 100644 index 0000000..31e7d185 --- /dev/null +++ b/ios/chrome/browser/providers/text_zoom/chromium_text_zoom.mm
@@ -0,0 +1,27 @@ +// 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 "ios/chrome/browser/web/features.h" +#import "ios/public/provider/chrome/browser/font_size_java_script_feature.h" +#import "ios/public/provider/chrome/browser/text_zoom/text_zoom_api.h" +#include "ui/base/device_form_factor.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace ios { +namespace provider { + +void SetTextZoomForWebState(web::WebState* web_state, int size) { + FontSizeJavaScriptFeature::GetInstance()->AdjustFontSize(web_state, size); +} + +bool IsTextZoomEnabled() { + return ui::GetDeviceFormFactor() != ui::DEVICE_FORM_FACTOR_TABLET && + base::FeatureList::IsEnabled(web::kWebPageTextAccessibility); +} + +} // namespace provider +} // namespace ios
diff --git a/ios/chrome/browser/screen_time/screen_time_history_deleter_factory.h b/ios/chrome/browser/screen_time/screen_time_history_deleter_factory.h index ed12c17..7d8aefc 100644 --- a/ios/chrome/browser/screen_time/screen_time_history_deleter_factory.h +++ b/ios/chrome/browser/screen_time/screen_time_history_deleter_factory.h
@@ -5,6 +5,8 @@ #ifndef IOS_CHROME_BROWSER_SCREEN_TIME_SCREEN_TIME_HISTORY_DELETER_FACTORY_H_ #define IOS_CHROME_BROWSER_SCREEN_TIME_SCREEN_TIME_HISTORY_DELETER_FACTORY_H_ +#include <CoreFoundation/CoreFoundation.h> + #include "base/macros.h" #include "base/no_destructor.h" #include "components/keyed_service/ios/browser_state_keyed_service_factory.h"
diff --git a/ios/chrome/browser/send_tab_to_self/ios_send_tab_to_self_infobar_delegate.h b/ios/chrome/browser/send_tab_to_self/ios_send_tab_to_self_infobar_delegate.h index 0809e184..86e7ea11 100644 --- a/ios/chrome/browser/send_tab_to_self/ios_send_tab_to_self_infobar_delegate.h +++ b/ios/chrome/browser/send_tab_to_self/ios_send_tab_to_self_infobar_delegate.h
@@ -5,6 +5,8 @@ #ifndef IOS_CHROME_BROWSER_SEND_TAB_TO_SELF_IOS_SEND_TAB_TO_SELF_INFOBAR_DELEGATE_H_ #define IOS_CHROME_BROWSER_SEND_TAB_TO_SELF_IOS_SEND_TAB_TO_SELF_INFOBAR_DELEGATE_H_ +#include <CoreFoundation/CoreFoundation.h> + #include <memory> #include <string>
diff --git a/ios/chrome/browser/send_tab_to_self/send_tab_to_self_browser_agent.h b/ios/chrome/browser/send_tab_to_self/send_tab_to_self_browser_agent.h index 97bf755..89a9089 100644 --- a/ios/chrome/browser/send_tab_to_self/send_tab_to_self_browser_agent.h +++ b/ios/chrome/browser/send_tab_to_self/send_tab_to_self_browser_agent.h
@@ -5,6 +5,8 @@ #ifndef IOS_CHROME_BROWSER_SEND_TAB_TO_SELF_SEND_TAB_TO_SELF_BROWSER_AGENT_H_ #define IOS_CHROME_BROWSER_SEND_TAB_TO_SELF_SEND_TAB_TO_SELF_BROWSER_AGENT_H_ +#include <CoreFoundation/CoreFoundation.h> + #include <string> #include <vector>
diff --git a/ios/chrome/browser/sessions/session_restoration_browser_agent.h b/ios/chrome/browser/sessions/session_restoration_browser_agent.h index 129536e..e5bd9033 100644 --- a/ios/chrome/browser/sessions/session_restoration_browser_agent.h +++ b/ios/chrome/browser/sessions/session_restoration_browser_agent.h
@@ -5,6 +5,8 @@ #ifndef IOS_CHROME_BROWSER_SESSIONS_SESSION_RESTORATION_BROWSER_AGENT_H_ #define IOS_CHROME_BROWSER_SESSIONS_SESSION_RESTORATION_BROWSER_AGENT_H_ +#include <CoreFoundation/CoreFoundation.h> + #include <memory> #include <string> #include <vector>
diff --git a/ios/chrome/browser/ui/activity_services/BUILD.gn b/ios/chrome/browser/ui/activity_services/BUILD.gn index 1bfb5c107..afc359de 100644 --- a/ios/chrome/browser/ui/activity_services/BUILD.gn +++ b/ios/chrome/browser/ui/activity_services/BUILD.gn
@@ -41,6 +41,7 @@ "//ios/chrome/browser/ui/main:default_browser_scene_agent", "//ios/chrome/browser/ui/main:scene_state_header", "//ios/chrome/browser/ui/util", + "//ios/chrome/browser/ui/util:url_with_title", "//ios/chrome/browser/web_state_list", "//ui/base", "//url",
diff --git a/ios/chrome/browser/ui/activity_services/activity_params.h b/ios/chrome/browser/ui/activity_services/activity_params.h index 4a81501c..365ac3a 100644 --- a/ios/chrome/browser/ui/activity_services/activity_params.h +++ b/ios/chrome/browser/ui/activity_services/activity_params.h
@@ -8,7 +8,7 @@ #import <UIKit/UIKit.h> #import "ios/chrome/browser/ui/activity_services/activity_scenario.h" -#import "ios/chrome/browser/ui/activity_services/data/url_with_title.h" +#import "ios/chrome/browser/ui/util/url_with_title.h" class GURL;
diff --git a/ios/chrome/browser/ui/activity_services/activity_params.mm b/ios/chrome/browser/ui/activity_services/activity_params.mm index 4dbd0b376d..d4e13cc 100644 --- a/ios/chrome/browser/ui/activity_services/activity_params.mm +++ b/ios/chrome/browser/ui/activity_services/activity_params.mm
@@ -3,7 +3,7 @@ // found in the LICENSE file. #import "ios/chrome/browser/ui/activity_services/activity_params.h" -#import "ios/chrome/browser/ui/activity_services/data/url_with_title.h" +#import "ios/chrome/browser/ui/util/url_with_title.h" #include "url/gurl.h"
diff --git a/ios/chrome/browser/ui/activity_services/data/BUILD.gn b/ios/chrome/browser/ui/activity_services/data/BUILD.gn index 5b477fc1..44ba412 100644 --- a/ios/chrome/browser/ui/activity_services/data/BUILD.gn +++ b/ios/chrome/browser/ui/activity_services/data/BUILD.gn
@@ -20,8 +20,6 @@ "share_to_data.mm", "share_to_data_builder.h", "share_to_data_builder.mm", - "url_with_title.h", - "url_with_title.mm", ] deps = [ "//base", @@ -31,6 +29,7 @@ "//ios/chrome/browser/snapshots", "//ios/chrome/browser/tabs", "//ios/chrome/browser/ui/util", + "//ios/chrome/browser/ui/util:url_with_title", "//ios/web/common:user_agent", "//ios/web/public", "//ios/web/public:web_state_observer",
diff --git a/ios/chrome/browser/ui/activity_services/data/share_to_data_builder.mm b/ios/chrome/browser/ui/activity_services/data/share_to_data_builder.mm index 4d08a932..d551856 100644 --- a/ios/chrome/browser/ui/activity_services/data/share_to_data_builder.mm +++ b/ios/chrome/browser/ui/activity_services/data/share_to_data_builder.mm
@@ -12,7 +12,7 @@ #import "ios/chrome/browser/tabs/tab_title_util.h" #include "ios/chrome/browser/ui/activity_services/data/chrome_activity_item_thumbnail_generator.h" #include "ios/chrome/browser/ui/activity_services/data/share_to_data.h" -#import "ios/chrome/browser/ui/activity_services/data/url_with_title.h" +#import "ios/chrome/browser/ui/util/url_with_title.h" #import "ios/web/public/navigation/navigation_item.h" #import "ios/web/public/navigation/navigation_manager.h" #import "ios/web/public/web_state.h"
diff --git a/ios/chrome/browser/ui/autofill/autofill_app_interface.mm b/ios/chrome/browser/ui/autofill/autofill_app_interface.mm index edd083d..3fd1b103 100644 --- a/ios/chrome/browser/ui/autofill/autofill_app_interface.mm +++ b/ios/chrome/browser/ui/autofill/autofill_app_interface.mm
@@ -147,7 +147,7 @@ // Removes all credentials stored. void ClearPasswordStore() { GetPasswordStore()->RemoveLoginsCreatedBetween(base::Time(), base::Time(), - base::OnceClosure()); + base::DoNothing()); TestStoreConsumer consumer; }
diff --git a/ios/chrome/browser/ui/browser_view/BUILD.gn b/ios/chrome/browser/ui/browser_view/BUILD.gn index f71f2b9..0a316e64 100644 --- a/ios/chrome/browser/ui/browser_view/BUILD.gn +++ b/ios/chrome/browser/ui/browser_view/BUILD.gn
@@ -170,6 +170,7 @@ "//ios/chrome/browser/ui/toolbar_container", "//ios/chrome/browser/ui/toolbar_container:feature_flags", "//ios/chrome/browser/ui/util", + "//ios/chrome/browser/ui/util:url_with_title", "//ios/chrome/browser/ui/voice", "//ios/chrome/browser/upgrade", "//ios/chrome/browser/url_loading",
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 2646c51..eb42f137 100644 --- a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm +++ b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
@@ -153,6 +153,7 @@ #import "ios/chrome/browser/ui/util/page_animation_util.h" #import "ios/chrome/browser/ui/util/pasteboard_util.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h" +#import "ios/chrome/browser/ui/util/url_with_title.h" #import "ios/chrome/browser/ui/voice/text_to_speech_playback_controller.h" #import "ios/chrome/browser/ui/voice/text_to_speech_playback_controller_factory.h" #include "ios/chrome/browser/upgrade/upgrade_center.h" @@ -713,8 +714,8 @@ // Reading List // ------------ -// Adds the given url to the reading list. -- (void)addToReadingListURL:(const GURL&)URL title:(NSString*)title; +// Adds the given urls to the reading list. +- (void)addURLsToReadingList:(NSArray<URLWithTitle*>*)URLs; // The thumb strip's pan gesture handler that will be added to the toolbar and // tab strip. @@ -2866,9 +2867,19 @@ #pragma mark - Private Methods: Reading List -- (void)addToReadingListURL:(const GURL&)URL title:(NSString*)title { - ReadingListModel* readingModel = - ReadingListModelFactory::GetForBrowserState(self.browserState); +- (void)addURLsToReadingList:(NSArray<URLWithTitle*>*)URLs { + for (URLWithTitle* urlWithTitle in URLs) { + [self addURLToReadingList:urlWithTitle.URL withTitle:urlWithTitle.title]; + } + + [self.dispatcher triggerToolsMenuButtonAnimation]; + + TriggerHapticFeedbackForNotification(UINotificationFeedbackTypeSuccess); + [self showSnackbar:l10n_util::GetNSString( + IDS_IOS_READING_LIST_SNACKBAR_MESSAGE)]; +} + +- (void)addURLToReadingList:(const GURL&)URL withTitle:(NSString*)title { if (self.currentWebState && self.currentWebState->GetVisibleURL().spec() == URL.spec()) { // Log UKM if the current page is being added to Reading List. @@ -2880,16 +2891,13 @@ .Record(ukm::UkmRecorder::Get()); } } + base::RecordAction(UserMetricsAction("MobileReadingListAdd")); + ReadingListModel* readingModel = + ReadingListModelFactory::GetForBrowserState(self.browserState); readingModel->AddEntry(URL, base::SysNSStringToUTF8(title), reading_list::ADDED_VIA_CURRENT_APP); - - [self.dispatcher triggerToolsMenuButtonAnimation]; - - TriggerHapticFeedbackForNotification(UINotificationFeedbackTypeSuccess); - [self showSnackbar:l10n_util::GetNSString( - IDS_IOS_READING_LIST_SNACKBAR_MESSAGE)]; } #pragma mark - ** Protocol Implementations and Helpers ** @@ -3591,7 +3599,9 @@ base::RecordAction( base::UserMetricsAction("MobileWebContextMenuReadLater")); Record(ACTION_READ_LATER, isImage, isLink); - [weakSelf addToReadingListURL:link title:innerText]; + [weakSelf addURLsToReadingList:@[ [[URLWithTitle alloc] + initWithURL:link + title:innerText] ]]; }; [_contextMenuCoordinator addItemWithTitle:title action:action @@ -3850,7 +3860,9 @@ // Add to reading list. UIAction* addToReadingList = [actionFactory actionToAddToReadingListWithBlock:^{ - [weakSelf addToReadingListURL:link title:innerText]; + [weakSelf addURLsToReadingList:@[ [[URLWithTitle alloc] + initWithURL:link + title:innerText] ]]; }]; [menuElements addObject:addToReadingList]; } @@ -4584,7 +4596,7 @@ } - (void)addToReadingList:(ReadingListAddCommand*)command { - [self addToReadingListURL:[command URL] title:[command title]]; + [self addURLsToReadingList:command.URLs]; } - (void)preloadVoiceSearch {
diff --git a/ios/chrome/browser/ui/commands/BUILD.gn b/ios/chrome/browser/ui/commands/BUILD.gn index 74c59ec..7cb2cc2 100644 --- a/ios/chrome/browser/ui/commands/BUILD.gn +++ b/ios/chrome/browser/ui/commands/BUILD.gn
@@ -48,6 +48,7 @@ ] deps = [ + "//ios/chrome/browser/ui/util:url_with_title", "//ios/public/provider/chrome/browser/user_feedback", "//ios/web", "//net",
diff --git a/ios/chrome/browser/ui/commands/reading_list_add_command.h b/ios/chrome/browser/ui/commands/reading_list_add_command.h index 5ebb244..e0fbde3 100644 --- a/ios/chrome/browser/ui/commands/reading_list_add_command.h +++ b/ios/chrome/browser/ui/commands/reading_list_add_command.h
@@ -8,17 +8,20 @@ #import <Foundation/Foundation.h> class GURL; +@class URLWithTitle; @interface ReadingListAddCommand : NSObject -@property(nonatomic, readonly) const GURL& URL; -@property(copy, nonatomic, readonly) NSString* title; +@property(nonatomic, readonly) NSArray<URLWithTitle*>* URLs; - (instancetype)init NS_UNAVAILABLE; - (instancetype)initWithURL:(const GURL&)URL title:(NSString*)title NS_DESIGNATED_INITIALIZER; +- (instancetype)initWithURLs:(NSArray<URLWithTitle*>*)URL + NS_DESIGNATED_INITIALIZER; + @end #endif // IOS_CHROME_BROWSER_UI_COMMANDS_READING_LIST_ADD_COMMAND_H_
diff --git a/ios/chrome/browser/ui/commands/reading_list_add_command.mm b/ios/chrome/browser/ui/commands/reading_list_add_command.mm index feedae2a..20668612 100644 --- a/ios/chrome/browser/ui/commands/reading_list_add_command.mm +++ b/ios/chrome/browser/ui/commands/reading_list_add_command.mm
@@ -4,23 +4,33 @@ #import "ios/chrome/browser/ui/commands/reading_list_add_command.h" +#import "ios/chrome/browser/ui/util/url_with_title.h" #include "url/gurl.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." #endif -@implementation ReadingListAddCommand { - GURL _URL; -} +@interface ReadingListAddCommand () -@synthesize title = _title; -@synthesize URL = _URL; +@property(nonatomic, strong) NSArray<URLWithTitle*>* URLs; + +@end + +@implementation ReadingListAddCommand + +@synthesize URLs = _URLs; - (instancetype)initWithURL:(const GURL&)URL title:(NSString*)title { if (self = [super init]) { - _URL = URL; - _title = title; + _URLs = @[ [[URLWithTitle alloc] initWithURL:URL title:title] ]; + } + return self; +} + +- (instancetype)initWithURLs:(NSArray<URLWithTitle*>*)URLs { + if (self = [super init]) { + _URLs = [URLs copy]; } return self; }
diff --git a/ios/chrome/browser/ui/infobars/test_infobar_delegate.h b/ios/chrome/browser/ui/infobars/test_infobar_delegate.h index 22d24122..0e0db41 100644 --- a/ios/chrome/browser/ui/infobars/test_infobar_delegate.h +++ b/ios/chrome/browser/ui/infobars/test_infobar_delegate.h
@@ -5,6 +5,8 @@ #ifndef IOS_CHROME_BROWSER_UI_INFOBARS_TEST_INFOBAR_DELEGATE_H_ #define IOS_CHROME_BROWSER_UI_INFOBARS_TEST_INFOBAR_DELEGATE_H_ +#include <CoreFoundation/CoreFoundation.h> + #include "components/infobars/core/confirm_infobar_delegate.h" // An infobar that displays |infobar_message| and one button.
diff --git a/ios/chrome/browser/ui/settings/password/passwords_settings_app_interface.mm b/ios/chrome/browser/ui/settings/password/passwords_settings_app_interface.mm index 1bc15b65..a400944 100644 --- a/ios/chrome/browser/ui/settings/password/passwords_settings_app_interface.mm +++ b/ios/chrome/browser/ui/settings/password/passwords_settings_app_interface.mm
@@ -137,7 +137,7 @@ bool ClearPasswordStore() { GetPasswordStore()->RemoveLoginsCreatedBetween(base::Time(), base::Time(), - base::OnceClosure()); + base::DoNothing()); FakeStoreConsumer consumer; if (!consumer.FetchStoreResults()) { return false;
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/BUILD.gn b/ios/chrome/browser/ui/tab_switcher/tab_grid/BUILD.gn index 1a73e763..d8f4b53 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/BUILD.gn +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/BUILD.gn
@@ -40,7 +40,6 @@ "//ios/chrome/browser/tabs", "//ios/chrome/browser/ui:feature_flags", "//ios/chrome/browser/ui/activity_services", - "//ios/chrome/browser/ui/activity_services/data", "//ios/chrome/browser/ui/alert_coordinator", "//ios/chrome/browser/ui/bookmarks", "//ios/chrome/browser/ui/commands", @@ -64,6 +63,7 @@ "//ios/chrome/browser/ui/thumb_strip:feature_flags", "//ios/chrome/browser/ui/thumb_strip:public", "//ios/chrome/browser/ui/util", + "//ios/chrome/browser/ui/util:url_with_title", "//ios/chrome/browser/url_loading", "//ios/chrome/browser/web", "//ios/chrome/browser/web_state_list",
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_coordinator.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_coordinator.mm index 62cd0cf..5097c0b 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_coordinator.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_coordinator.mm
@@ -975,12 +975,12 @@ } - (void)addToReadingListURL:(const GURL&)URL title:(NSString*)title { + ReadingListAddCommand* command = + [[ReadingListAddCommand alloc] initWithURL:URL title:title]; // TODO(crbug.com/1045047): Use HandlerForProtocol after commands // protocol clean up. id<BrowserCommands> readingListAdder = static_cast<id<BrowserCommands>>( self.regularBrowser->GetCommandDispatcher()); - ReadingListAddCommand* command = - [[ReadingListAddCommand alloc] initWithURL:URL title:title]; [readingListAdder addToReadingList:command]; }
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm index fc02c5f..1646352 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm
@@ -102,9 +102,10 @@ } if ([self isRunningTest:@selector(testTabGridBulkActionCloseTabs)] || - [self isRunningTest:@selector(testTabGridBulkActionSelectAll)]) { + [self isRunningTest:@selector(testTabGridBulkActionSelectAll)] || + [self isRunningTest:@selector(testTabGridBulkActionAddToReadingList)]) { config.features_enabled.push_back(kTabsBulkActions); - } + } config.features_disabled.push_back(kStartSurface); @@ -956,7 +957,7 @@ assertWithMatcher:grey_notNil()]; } -// Tests selecting all items in the tab grdi edit mode using the "Select all" +// Tests selecting all items in the tab grid edit mode using the "Select all" // button. - (void)testTabGridBulkActionSelectAll { if (!base::ios::IsRunningOnIOS14OrLater()) { @@ -1005,6 +1006,44 @@ assertWithMatcher:grey_notNil()]; } +// Tests adding items to the readinglist from the tab grid edit mode. +- (void)testTabGridBulkActionAddToReadingList { + if (!base::ios::IsRunningOnIOS14OrLater()) { + EARL_GREY_TEST_SKIPPED( + @"Bulk actions are only supported on iOS 14 and later."); + } + + [ChromeEarlGrey loadURL:_URL1]; + [ChromeEarlGrey waitForWebStateContainingText:kResponse1]; + + [ChromeEarlGrey openNewTab]; + [ChromeEarlGrey loadURL:_URL2]; + [ChromeEarlGrey waitForWebStateContainingText:kResponse2]; + + [ChromeEarlGrey openNewTab]; + [ChromeEarlGrey loadURL:_URL3]; + [ChromeEarlGrey waitForWebStateContainingText:kResponse3]; + + [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] + performAction:grey_tap()]; + + [[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridEditButton()] + performAction:grey_tap()]; + + // Select the first and last items. + [[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridCellAtIndex(0)] + performAction:grey_tap()]; + [[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridCellAtIndex(2)] + performAction:grey_tap()]; + + [[EarlGrey + selectElementWithMatcher:chrome_test_util::TabGridEditAddToButton()] + performAction:grey_tap()]; + + [self waitForSnackBarMessage:IDS_IOS_READING_LIST_SNACKBAR_MESSAGE + triggeredByTappingItemWithMatcher:AddToReadingListButton()]; +} + #pragma mark - Helper Methods - (void)loadTestURLs {
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_mediator.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_mediator.mm index eda8168..8f0ff88 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_mediator.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_mediator.mm
@@ -30,12 +30,14 @@ #import "ios/chrome/browser/snapshots/snapshot_tab_helper.h" #include "ios/chrome/browser/system_flags.h" #import "ios/chrome/browser/tabs/tab_title_util.h" -#import "ios/chrome/browser/ui/activity_services/data/url_with_title.h" +#import "ios/chrome/browser/ui/commands/browser_commands.h" +#import "ios/chrome/browser/ui/commands/reading_list_add_command.h" #import "ios/chrome/browser/ui/menu/action_factory.h" #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_consumer.h" #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_item.h" #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.h" #import "ios/chrome/browser/ui/tab_switcher/tab_switcher_item.h" +#import "ios/chrome/browser/ui/util/url_with_title.h" #import "ios/chrome/browser/web/tab_id_tab_helper.h" #include "ios/chrome/browser/web_state_list/web_state_list.h" #import "ios/chrome/browser/web_state_list/web_state_list_observer_bridge.h" @@ -123,6 +125,8 @@ @property(nonatomic, readonly) ChromeBrowserState* browserState; // The UI consumer to which updates are made. @property(nonatomic, weak) id<GridConsumer> consumer; +// Handler for reading list command. +@property(nonatomic, weak) id<BrowserCommands> readingListHandler; // The saved session window just before close all tabs is called. @property(nonatomic, strong) SessionWindowIOS* closedSessionWindow; // The number of tabs in |closedSessionWindow| that are synced by @@ -171,9 +175,18 @@ [self.snapshotCache removeObserver:self]; _scopedWebStateListObservation->RemoveAllObservations(); _scopedWebStateObservation->RemoveAllObservations(); + _readingListHandler = nullptr; + _browser = browser; + _webStateList = browser ? browser->GetWebStateList() : nullptr; _browserState = browser ? browser->GetBrowserState() : nullptr; + if (_browser) { + // TODO(crbug.com/1045047): Use HandlerForProtocol after commands + // protocol clean up. + _readingListHandler = + static_cast<id<BrowserCommands>>(_browser->GetCommandDispatcher()); + } [self.snapshotCache addObserver:self]; if (_webStateList) { @@ -701,7 +714,21 @@ } - (void)addItemsToReadingList:(NSArray<NSString*>*)items { - // TODO(crbug.com/1196907): Implement add items to reading list. + if (!_readingListHandler) { + return; + } + + NSMutableArray<URLWithTitle*>* URLs = [[NSMutableArray alloc] init]; + for (NSString* itemIdentifier in items) { + GridItem* item = [self gridItemForCellIdentifier:itemIdentifier]; + URLWithTitle* URL = [[URLWithTitle alloc] initWithURL:item.URL + title:item.title]; + [URLs addObject:URL]; + } + + ReadingListAddCommand* command = + [[ReadingListAddCommand alloc] initWithURLs:URLs]; + [_readingListHandler addToReadingList:command]; } - (void)addItemsToBookmarks:(NSArray<NSString*>*)items {
diff --git a/ios/chrome/browser/ui/util/BUILD.gn b/ios/chrome/browser/ui/util/BUILD.gn index 37545ae3..5a8af4ca 100644 --- a/ios/chrome/browser/ui/util/BUILD.gn +++ b/ios/chrome/browser/ui/util/BUILD.gn
@@ -103,6 +103,15 @@ ] } +source_set("url_with_title") { + configs += [ "//build/config/compiler:enable_arc" ] + sources = [ + "url_with_title.h", + "url_with_title.mm", + ] + deps = [ "//url" ] +} + source_set("unit_tests") { configs += [ "//build/config/compiler:enable_arc" ] testonly = true
diff --git a/ios/chrome/browser/ui/util/ui_util.h b/ios/chrome/browser/ui/util/ui_util.h index aa3088a..4b70376d 100644 --- a/ios/chrome/browser/ui/util/ui_util.h +++ b/ios/chrome/browser/ui/util/ui_util.h
@@ -14,9 +14,6 @@ // ui/base/device_form_factor.h instead. bool IsIPadIdiom(); -// Enum for arrays by UI idiom. -enum InterfaceIdiom { IPHONE_IDIOM, IPAD_IDIOM, INTERFACE_IDIOM_COUNT }; - // Returns the height of the screen in the current orientation. CGFloat CurrentScreenHeight();
diff --git a/ios/chrome/browser/ui/activity_services/data/url_with_title.h b/ios/chrome/browser/ui/util/url_with_title.h similarity index 74% rename from ios/chrome/browser/ui/activity_services/data/url_with_title.h rename to ios/chrome/browser/ui/util/url_with_title.h index e25a4f21..3d9344fe 100644 --- a/ios/chrome/browser/ui/activity_services/data/url_with_title.h +++ b/ios/chrome/browser/ui/util/url_with_title.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef IOS_CHROME_BROWSER_UI_ACTIVITY_SERVICES_DATA_URL_WITH_TITLE_H_ -#define IOS_CHROME_BROWSER_UI_ACTIVITY_SERVICES_DATA_URL_WITH_TITLE_H_ +#ifndef IOS_CHROME_BROWSER_UI_UTIL_URL_WITH_TITLE_H_ +#define IOS_CHROME_BROWSER_UI_UTIL_URL_WITH_TITLE_H_ #include <url/gurl.h> @@ -23,4 +23,4 @@ @end -#endif // IOS_CHROME_BROWSER_UI_ACTIVITY_SERVICES_DATA_URL_WITH_TITLE_H_ +#endif // IOS_CHROME_BROWSER_UI_UTIL_URL_WITH_TITLE_H_
diff --git a/ios/chrome/browser/ui/activity_services/data/url_with_title.mm b/ios/chrome/browser/ui/util/url_with_title.mm similarity index 89% rename from ios/chrome/browser/ui/activity_services/data/url_with_title.mm rename to ios/chrome/browser/ui/util/url_with_title.mm index 193b50a6..2111ba4 100644 --- a/ios/chrome/browser/ui/activity_services/data/url_with_title.mm +++ b/ios/chrome/browser/ui/util/url_with_title.mm
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "ios/chrome/browser/ui/activity_services/data/url_with_title.h" +#import "ios/chrome/browser/ui/util/url_with_title.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -31,4 +31,4 @@ return _URL; } -@end \ No newline at end of file +@end
diff --git a/ios/chrome/browser/web/web_navigation_ntp_delegate.h b/ios/chrome/browser/web/web_navigation_ntp_delegate.h index a4c9499f..6a6e6f20 100644 --- a/ios/chrome/browser/web/web_navigation_ntp_delegate.h +++ b/ios/chrome/browser/web/web_navigation_ntp_delegate.h
@@ -5,6 +5,8 @@ #ifndef IOS_CHROME_BROWSER_WEB_WEB_NAVIGATION_NTP_DELEGATE_H_ #define IOS_CHROME_BROWSER_WEB_WEB_NAVIGATION_NTP_DELEGATE_H_ +#include <CoreFoundation/CoreFoundation.h> + namespace web { class WebState; }
diff --git a/ios/chrome/test/earl_grey/chrome_matchers.h b/ios/chrome/test/earl_grey/chrome_matchers.h index 90d3097..7694acec 100644 --- a/ios/chrome/test/earl_grey/chrome_matchers.h +++ b/ios/chrome/test/earl_grey/chrome_matchers.h
@@ -597,6 +597,9 @@ // Returns a matcher for the button to enter the tab grid tab edit mode. id<GREYMatcher> TabGridEditButton(); +// Returns a matcher for the button to act on the selected tabs. +id<GREYMatcher> TabGridEditAddToButton(); + // Returns a matcher for the button to close the selected tabs. id<GREYMatcher> TabGridEditCloseTabsButton();
diff --git a/ios/chrome/test/earl_grey/chrome_matchers.mm b/ios/chrome/test/earl_grey/chrome_matchers.mm index 08885ac..db48b193 100644 --- a/ios/chrome/test/earl_grey/chrome_matchers.mm +++ b/ios/chrome/test/earl_grey/chrome_matchers.mm
@@ -755,6 +755,10 @@ return [ChromeMatchersAppInterface tabGridEditButton]; } +id<GREYMatcher> TabGridEditAddToButton() { + return [ChromeMatchersAppInterface tabGridEditAddToButton]; +} + id<GREYMatcher> TabGridEditCloseTabsButton() { return [ChromeMatchersAppInterface tabGridEditCloseTabsButton]; }
diff --git a/ios/chrome/test/earl_grey/chrome_matchers_app_interface.h b/ios/chrome/test/earl_grey/chrome_matchers_app_interface.h index a98d663..c562a24 100644 --- a/ios/chrome/test/earl_grey/chrome_matchers_app_interface.h +++ b/ios/chrome/test/earl_grey/chrome_matchers_app_interface.h
@@ -589,6 +589,9 @@ // Returns a matcher for the button to enter the tab grid tab edit mode. + (id<GREYMatcher>)tabGridEditButton; +// Returns a matcher for the button to act on the selected tabs. ++ (id<GREYMatcher>)tabGridEditAddToButton; + // Returns a matcher for the button to close the selected tabs. + (id<GREYMatcher>)tabGridEditCloseTabsButton;
diff --git a/ios/chrome/test/earl_grey/chrome_matchers_app_interface.mm b/ios/chrome/test/earl_grey/chrome_matchers_app_interface.mm index e45ca9a..66ea957 100644 --- a/ios/chrome/test/earl_grey/chrome_matchers_app_interface.mm +++ b/ios/chrome/test/earl_grey/chrome_matchers_app_interface.mm
@@ -1136,6 +1136,11 @@ grey_sufficientlyVisible(), nil); } ++ (id<GREYMatcher>)tabGridEditAddToButton { + return grey_allOf(grey_accessibilityID(kTabGridEditAddToButtonIdentifier), + grey_sufficientlyVisible(), nil); +} + + (id<GREYMatcher>)tabGridEditCloseTabsButton { return grey_allOf(grey_accessibilityID(kTabGridEditCloseTabsButtonIdentifier), grey_sufficientlyVisible(), nil);
diff --git a/ios/chrome/test/wpt/cwt_request_handler.mm b/ios/chrome/test/wpt/cwt_request_handler.mm index 3dc12c3..d1bcfa5a 100644 --- a/ios/chrome/test/wpt/cwt_request_handler.mm +++ b/ios/chrome/test/wpt/cwt_request_handler.mm
@@ -428,7 +428,7 @@ } base::Value CWTRequestHandler::SetTimeouts(const base::Value& timeouts) { - for (const auto& timeout : timeouts.DictItems()) { + for (const auto timeout : timeouts.DictItems()) { if (!timeout.second.is_int() || timeout.second.GetInt() < 0) { return CreateErrorValue(kWebDriverInvalidArgumentError, kWebDriverInvalidTimeoutMessage);
diff --git a/ios/net/http_cache_helper.cc b/ios/net/http_cache_helper.cc index 1936e99..a74887c 100644 --- a/ios/net/http_cache_helper.cc +++ b/ios/net/http_cache_helper.cc
@@ -12,6 +12,7 @@ #include "base/location.h" #include "base/task_runner.h" #include "base/threading/thread_task_runner_handle.h" +#include "base/time/time.h" #include "net/base/completion_repeating_callback.h" #include "net/disk_cache/disk_cache.h" #include "net/http/http_cache.h"
diff --git a/ios/net/http_cache_helper.h b/ios/net/http_cache_helper.h index c8a7c77..9da4204 100644 --- a/ios/net/http_cache_helper.h +++ b/ios/net/http_cache_helper.h
@@ -11,6 +11,7 @@ namespace base { class TaskRunner; +class Time; } namespace net {
diff --git a/ios/public/provider/chrome/browser/BUILD.gn b/ios/public/provider/chrome/browser/BUILD.gn index c494a083..43fb8e0 100644 --- a/ios/public/provider/chrome/browser/BUILD.gn +++ b/ios/public/provider/chrome/browser/BUILD.gn
@@ -38,14 +38,15 @@ deps = [ "//base", "//ios/web/public", - "//ios/web/public/js_messaging", ] + public_deps = [ "//ios/web/public/js_messaging" ] } group("provider_api") { deps = [ # The individual APIs. "//ios/public/provider/chrome/browser/modals:modals_api", + "//ios/public/provider/chrome/browser/text_zoom:text_zoom_api", ] } @@ -95,6 +96,7 @@ # The individual API implementations. "//ios/public/provider/chrome/browser/modals:test_modals", + "//ios/public/provider/chrome/browser/text_zoom:test_text_zoom", # The provider API needs to provide MaterialDesignComponent API (as the # internal provider provides an alternate implementation).
diff --git a/ios/public/provider/chrome/browser/signin/chrome_identity_service.h b/ios/public/provider/chrome/browser/signin/chrome_identity_service.h index fb78426f..3d6398b3 100644 --- a/ios/public/provider/chrome/browser/signin/chrome_identity_service.h +++ b/ios/public/provider/chrome/browser/signin/chrome_identity_service.h
@@ -5,6 +5,8 @@ #ifndef IOS_PUBLIC_PROVIDER_CHROME_BROWSER_SIGNIN_CHROME_IDENTITY_SERVICE_H_ #define IOS_PUBLIC_PROVIDER_CHROME_BROWSER_SIGNIN_CHROME_IDENTITY_SERVICE_H_ +#include <CoreFoundation/CoreFoundation.h> + #include <set> #include <string> #include <vector>
diff --git a/ios/public/provider/chrome/browser/signin/chrome_trusted_vault_service.h b/ios/public/provider/chrome/browser/signin/chrome_trusted_vault_service.h index ef806f1..2a52356 100644 --- a/ios/public/provider/chrome/browser/signin/chrome_trusted_vault_service.h +++ b/ios/public/provider/chrome/browser/signin/chrome_trusted_vault_service.h
@@ -5,6 +5,8 @@ #ifndef IOS_PUBLIC_PROVIDER_CHROME_BROWSER_SIGNIN_CHROME_TRUSTED_VAULT_SERVICE_H_ #define IOS_PUBLIC_PROVIDER_CHROME_BROWSER_SIGNIN_CHROME_TRUSTED_VAULT_SERVICE_H_ +#include <CoreFoundation/CoreFoundation.h> + #include <memory> #include <vector>
diff --git a/ios/public/provider/chrome/browser/text_zoom/BUILD.gn b/ios/public/provider/chrome/browser/text_zoom/BUILD.gn new file mode 100644 index 0000000..c339c5d --- /dev/null +++ b/ios/public/provider/chrome/browser/text_zoom/BUILD.gn
@@ -0,0 +1,18 @@ +# 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. + +source_set("text_zoom_api") { + configs += [ "//build/config/compiler:enable_arc" ] + sources = [ "text_zoom_api.h" ] +} + +source_set("test_text_zoom") { + testonly = true + configs += [ "//build/config/compiler:enable_arc" ] + sources = [ "test_text_zoom.mm" ] + deps = [ + ":text_zoom_api", + "//ios/public/provider/chrome/browser:font_size_java_script_feature", + ] +}
diff --git a/ios/public/provider/chrome/browser/text_zoom/test_text_zoom.mm b/ios/public/provider/chrome/browser/text_zoom/test_text_zoom.mm new file mode 100644 index 0000000..4777b3b --- /dev/null +++ b/ios/public/provider/chrome/browser/text_zoom/test_text_zoom.mm
@@ -0,0 +1,24 @@ +// 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 "ios/public/provider/chrome/browser/font_size_java_script_feature.h" +#import "ios/public/provider/chrome/browser/text_zoom/text_zoom_api.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace ios { +namespace provider { + +void SetTextZoomForWebState(web::WebState* web_state, int size) { + FontSizeJavaScriptFeature::GetInstance()->AdjustFontSize(web_state, size); +} + +bool IsTextZoomEnabled() { + return true; +} + +} // namespace provider +} // namespace ios
diff --git a/ios/public/provider/chrome/browser/text_zoom/text_zoom_api.h b/ios/public/provider/chrome/browser/text_zoom/text_zoom_api.h new file mode 100644 index 0000000..205c55d --- /dev/null +++ b/ios/public/provider/chrome/browser/text_zoom/text_zoom_api.h
@@ -0,0 +1,25 @@ +// 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 IOS_PUBLIC_PROVIDER_CHROME_BROWSER_TEXT_ZOOM_TEXT_ZOOM_API_H_ +#define IOS_PUBLIC_PROVIDER_CHROME_BROWSER_TEXT_ZOOM_TEXT_ZOOM_API_H_ + +namespace web { +class WebState; +} // namespace web + +namespace ios { +namespace provider { + +// Zooms the given web_state to the provided size as a percentage. I.e. a size +// of 100 corresponds to a zoom of 100%. +void SetTextZoomForWebState(web::WebState* web_state, int size); + +// Returns whether text zoom is enabled currently. +bool IsTextZoomEnabled(); + +} // namespace provider +} // namespace ios + +#endif // IOS_PUBLIC_PROVIDER_CHROME_BROWSER_TEXT_ZOOM_TEXT_ZOOM_API_H_
diff --git a/ios/web/js_messaging/java_script_feature.mm b/ios/web/js_messaging/java_script_feature.mm index ac27113..9a65146 100644 --- a/ios/web/js_messaging/java_script_feature.mm +++ b/ios/web/js_messaging/java_script_feature.mm
@@ -8,6 +8,7 @@ #include "base/bind.h" #import "base/strings/sys_string_conversions.h" +#include "base/time/time.h" #import "ios/web/js_messaging/java_script_content_world.h" #import "ios/web/js_messaging/java_script_feature_manager.h" #include "ios/web/js_messaging/page_script_util.h"
diff --git a/ios/web/public/js_messaging/BUILD.gn b/ios/web/public/js_messaging/BUILD.gn index 8796351..1645c69 100644 --- a/ios/web/public/js_messaging/BUILD.gn +++ b/ios/web/public/js_messaging/BUILD.gn
@@ -8,6 +8,7 @@ "//ios/web/public/", "//url", ] + public_deps = [ "//third_party/abseil-cpp:absl" ] sources = [ "java_script_feature.h",
diff --git a/ios/web/public/js_messaging/java_script_feature.h b/ios/web/public/js_messaging/java_script_feature.h index 31728d5..7e320c6 100644 --- a/ios/web/public/js_messaging/java_script_feature.h +++ b/ios/web/public/js_messaging/java_script_feature.h
@@ -15,6 +15,7 @@ #include "third_party/abseil-cpp/absl/types/optional.h" namespace base { +class TimeDelta; class Value; } // namespace base
diff --git a/ios/web/test/fakes/fake_java_script_feature.mm b/ios/web/test/fakes/fake_java_script_feature.mm index 885ab1c9..27e3d83 100644 --- a/ios/web/test/fakes/fake_java_script_feature.mm +++ b/ios/web/test/fakes/fake_java_script_feature.mm
@@ -4,6 +4,8 @@ #import "ios/web/test/fakes/fake_java_script_feature.h" +#include "base/time/time.h" + #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." #endif
diff --git a/ios/web/web_state/ui/wk_web_view_configuration_provider.h b/ios/web/web_state/ui/wk_web_view_configuration_provider.h index 9c67e519..af41db8 100644 --- a/ios/web/web_state/ui/wk_web_view_configuration_provider.h +++ b/ios/web/web_state/ui/wk_web_view_configuration_provider.h
@@ -5,6 +5,8 @@ #ifndef IOS_WEB_WEB_STATE_UI_WK_WEB_VIEW_CONFIGURATION_PROVIDER_H_ #define IOS_WEB_WEB_STATE_UI_WK_WEB_VIEW_CONFIGURATION_PROVIDER_H_ +#include <CoreFoundation/CoreFoundation.h> + #include "base/macros.h" #include "base/observer_list.h" #include "base/supports_user_data.h"
diff --git a/ios/web/webui/crw_web_ui_scheme_handler.mm b/ios/web/webui/crw_web_ui_scheme_handler.mm index 824acb3..569206a9 100644 --- a/ios/web/webui/crw_web_ui_scheme_handler.mm +++ b/ios/web/webui/crw_web_ui_scheme_handler.mm
@@ -6,6 +6,7 @@ #include <map> +#include "base/files/file_path.h" #import "ios/web/webui/url_fetcher_block_adapter.h" #include "ios/web/webui/web_ui_ios_controller_factory_registry.h" #import "net/base/mac/url_conversions.h"
diff --git a/ios/web/webui/mojo_facade.mm b/ios/web/webui/mojo_facade.mm index 7ed844bf..3ea9d20 100644 --- a/ios/web/webui/mojo_facade.mm +++ b/ios/web/webui/mojo_facade.mm
@@ -148,7 +148,7 @@ } std::vector<uint8_t> bytes(buffer->DictSize()); - for (const auto& item : buffer->DictItems()) { + for (const auto item : buffer->DictItems()) { size_t index = std::numeric_limits<size_t>::max(); CHECK(base::StringToSizeT(item.first, &index)); CHECK(index < bytes.size());
diff --git a/mojo/public/tools/bindings/generators/mojolpm_templates/mojolpm_to_proto_macros.tmpl b/mojo/public/tools/bindings/generators/mojolpm_templates/mojolpm_to_proto_macros.tmpl index 38c68ea2..f50b9ef 100644 --- a/mojo/public/tools/bindings/generators/mojolpm_templates/mojolpm_to_proto_macros.tmpl +++ b/mojo/public/tools/bindings/generators/mojolpm_templates/mojolpm_to_proto_macros.tmpl
@@ -83,7 +83,7 @@ {{type}}& output) { bool result = true; - for ({{maybe_const}}auto& in_value : input) { + for (auto&& in_value : input) { {%- if kind.kind|is_nullable_kind %} {{type}}Entry* out_value = output.mutable_values()->Add(); if ({{util.not_null(kind.kind, 'in_value')}}) {
diff --git a/net/http/http_server_properties_manager_unittest.cc b/net/http/http_server_properties_manager_unittest.cc index 6789101..5db0412 100644 --- a/net/http/http_server_properties_manager_unittest.cc +++ b/net/http/http_server_properties_manager_unittest.cc
@@ -1515,8 +1515,8 @@ "\"isolation\":[]," "\"server\":\"https://www.google.com:80\"}," "{\"alternative_service\":[{" - "\"advertised_alpns\":[\"h3-Q050\",\"h3-29\"],\"expiration\":" - "\"9223372036854775807\"," + "\"advertised_alpns\":[\"h3\",\"h3-29\",\"h3-Q050\"]," + "\"expiration\":\"9223372036854775807\"," "\"host\":\"foo.google.com\",\"port\":444,\"protocol_str\":\"quic\"}]," "\"isolation\":[]," "\"network_stats\":{\"srtt\":42}," @@ -1627,7 +1627,8 @@ "\"server_id\":\"https://mail.google.com:80\"," "\"server_info\":\"quic_server_info1\"}]," "\"servers\":[" - "{\"alternative_service\":[{\"advertised_alpns\":[\"h3-Q050\",\"h3-29\"]," + "{\"alternative_service\":[{" + "\"advertised_alpns\":[\"h3\",\"h3-29\",\"h3-Q050\"]," "\"expiration\":\"13756212000000000\",\"port\":443," "\"protocol_str\":\"quic\"}]," "\"isolation\":[],"
diff --git a/net/http/http_stream_factory_job_controller_unittest.cc b/net/http/http_stream_factory_job_controller_unittest.cc index 21308bf..623db362 100644 --- a/net/http/http_stream_factory_job_controller_unittest.cc +++ b/net/http/http_stream_factory_job_controller_unittest.cc
@@ -200,6 +200,7 @@ HttpStreamFactoryJobControllerTest() : TestWithTaskEnvironment( base::test::TaskEnvironment::TimeSource::MOCK_TIME) { + FLAGS_quic_enable_http3_grease_randomness = false; session_deps_.enable_quic = true; session_deps_.host_resolver->set_synchronous_mode(true); } @@ -2934,7 +2935,14 @@ [](const quic::ParsedQuicVersion& a, const quic::ParsedQuicVersion& b) { return a.transport_version < b.transport_version; }); - EXPECT_EQ(supported_versions, alt_svc_info.advertised_versions()); + quic::ParsedQuicVersionVector advertised_versions = + alt_svc_info.advertised_versions(); + std::sort( + advertised_versions.begin(), advertised_versions.end(), + [](const quic::ParsedQuicVersion& a, const quic::ParsedQuicVersion& b) { + return a.transport_version < b.transport_version; + }); + EXPECT_EQ(supported_versions, advertised_versions); quic::ParsedQuicVersion unsupported_version_1 = quic::ParsedQuicVersion::Unsupported(); @@ -3107,8 +3115,15 @@ [](const quic::ParsedQuicVersion& a, const quic::ParsedQuicVersion& b) { return a.transport_version < b.transport_version; }); + quic::ParsedQuicVersionVector advertised_versions = + alt_svc_info.advertised_versions(); + std::sort( + advertised_versions.begin(), advertised_versions.end(), + [](const quic::ParsedQuicVersion& a, const quic::ParsedQuicVersion& b) { + return a.transport_version < b.transport_version; + }); EXPECT_EQ(kProtoQUIC, alt_svc_info.alternative_service().protocol); - EXPECT_EQ(supported_versions, alt_svc_info.advertised_versions()); + EXPECT_EQ(supported_versions, advertised_versions); session_->http_server_properties()->SetQuicAlternativeService( server, NetworkIsolationKey(),
diff --git a/net/quic/quic_context.h b/net/quic/quic_context.h index 403b4a5..736440f8 100644 --- a/net/quic/quic_context.h +++ b/net/quic/quic_context.h
@@ -20,12 +20,10 @@ // The ordering of this list does not matter for Chrome because it respects // the ordering received from the server via Alt-Svc. However, cronet offers // an addQuicHint() API which uses the first version from this list until - // it receives Alt-Svc from the server. We therefore list Q050 first here - // because there are some cronet applications which communicate with servers - // that speak Q050 but not Draft29. - // TODO(dschinazi) Move Draft29 first once those servers support it. - return quic::ParsedQuicVersionVector{quic::ParsedQuicVersion::Q050(), - quic::ParsedQuicVersion::Draft29()}; + // it receives Alt-Svc from the server. + return quic::ParsedQuicVersionVector{quic::ParsedQuicVersion::RFCv1(), + quic::ParsedQuicVersion::Draft29(), + quic::ParsedQuicVersion::Q050()}; } // Obsolete QUIC supported versions are versions that are supported by the
diff --git a/rlz/chromeos/lib/rlz_value_store_chromeos.cc b/rlz/chromeos/lib/rlz_value_store_chromeos.cc index 58c00703..62ec0a9 100644 --- a/rlz/chromeos/lib/rlz_value_store_chromeos.cc +++ b/rlz/chromeos/lib/rlz_value_store_chromeos.cc
@@ -163,7 +163,7 @@ case base::Value::Type::DICTIONARY: { base::Value::DictStorage storage; - for (const auto& key_value_pair : value.DictItems()) { + for (const auto key_value_pair : value.DictItems()) { absl::optional<base::Value> item_copy = CopyWithoutEmptyChildren(key_value_pair.second); if (item_copy)
diff --git a/services/network/network_context.cc b/services/network/network_context.cc index e458ba1..ace74b8 100644 --- a/services/network/network_context.cc +++ b/services/network/network_context.cc
@@ -1050,8 +1050,8 @@ void NetworkContext::GetDomainReliabilityJSON( GetDomainReliabilityJSONCallback callback) { if (!domain_reliability_monitor_) { - base::DictionaryValue data; - data.SetString("error", "no_service"); + base::Value data(base::Value::Type::DICTIONARY); + data.SetStringKey("error", "no_service"); std::move(callback).Run(std::move(data)); return; } @@ -1221,7 +1221,7 @@ const std::string& domain, const net::NetworkIsolationKey& network_isolation_key, GetExpectCTStateCallback callback) { - base::DictionaryValue result; + base::Value result(base::Value::Type::DICTIONARY); if (base::IsStringASCII(domain)) { net::TransportSecurityState* transport_security_state = url_request_context()->transport_security_state(); @@ -1232,23 +1232,23 @@ // TODO(estark): query static Expect-CT state as well. if (found) { - result.SetString("dynamic_expect_ct_domain", domain); - result.SetDouble("dynamic_expect_ct_observed", - dynamic_expect_ct_state.last_observed.ToDoubleT()); - result.SetDouble("dynamic_expect_ct_expiry", - dynamic_expect_ct_state.expiry.ToDoubleT()); - result.SetBoolean("dynamic_expect_ct_enforce", + result.SetStringKey("dynamic_expect_ct_domain", domain); + result.SetDoubleKey("dynamic_expect_ct_observed", + dynamic_expect_ct_state.last_observed.ToDoubleT()); + result.SetDoubleKey("dynamic_expect_ct_expiry", + dynamic_expect_ct_state.expiry.ToDoubleT()); + result.SetBoolKey("dynamic_expect_ct_enforce", dynamic_expect_ct_state.enforce); - result.SetString("dynamic_expect_ct_report_uri", - dynamic_expect_ct_state.report_uri.spec()); + result.SetStringKey("dynamic_expect_ct_report_uri", + dynamic_expect_ct_state.report_uri.spec()); } - result.SetBoolean("result", found); + result.SetBoolKey("result", found); } else { - result.SetString("error", "no Expect-CT state active"); + result.SetStringKey("error", "no Expect-CT state active"); } } else { - result.SetString("error", "non-ASCII domain name"); + result.SetStringKey("error", "non-ASCII domain name"); } std::move(callback).Run(std::move(result)); @@ -1559,7 +1559,7 @@ void NetworkContext::GetHSTSState(const std::string& domain, GetHSTSStateCallback callback) { - base::DictionaryValue result; + base::Value result(base::Value::Type::DICTIONARY); if (base::IsStringASCII(domain)) { net::TransportSecurityState* transport_security_state = @@ -1570,24 +1570,24 @@ bool found_static = transport_security_state->GetStaticDomainState( domain, &static_sts_state, &static_pkp_state); if (found_static) { - result.SetInteger("static_upgrade_mode", - static_cast<int>(static_sts_state.upgrade_mode)); - result.SetBoolean("static_sts_include_subdomains", + result.SetIntKey("static_upgrade_mode", + static_cast<int>(static_sts_state.upgrade_mode)); + result.SetBoolKey("static_sts_include_subdomains", static_sts_state.include_subdomains); - result.SetDouble("static_sts_observed", - static_sts_state.last_observed.ToDoubleT()); - result.SetDouble("static_sts_expiry", - static_sts_state.expiry.ToDoubleT()); - result.SetBoolean("static_pkp_include_subdomains", + result.SetDoubleKey("static_sts_observed", + static_sts_state.last_observed.ToDoubleT()); + result.SetDoubleKey("static_sts_expiry", + static_sts_state.expiry.ToDoubleT()); + result.SetBoolKey("static_pkp_include_subdomains", static_pkp_state.include_subdomains); - result.SetDouble("static_pkp_observed", - static_pkp_state.last_observed.ToDoubleT()); - result.SetDouble("static_pkp_expiry", - static_pkp_state.expiry.ToDoubleT()); - result.SetString("static_spki_hashes", - HashesToBase64String(static_pkp_state.spki_hashes)); - result.SetString("static_sts_domain", static_sts_state.domain); - result.SetString("static_pkp_domain", static_pkp_state.domain); + result.SetDoubleKey("static_pkp_observed", + static_pkp_state.last_observed.ToDoubleT()); + result.SetDoubleKey("static_pkp_expiry", + static_pkp_state.expiry.ToDoubleT()); + result.SetStringKey("static_spki_hashes", + HashesToBase64String(static_pkp_state.spki_hashes)); + result.SetStringKey("static_sts_domain", static_sts_state.domain); + result.SetStringKey("static_pkp_domain", static_pkp_state.domain); } net::TransportSecurityState::STSState dynamic_sts_state; @@ -1598,36 +1598,37 @@ bool found_pkp_dynamic = transport_security_state->GetDynamicPKPState( domain, &dynamic_pkp_state); if (found_sts_dynamic) { - result.SetInteger("dynamic_upgrade_mode", - static_cast<int>(dynamic_sts_state.upgrade_mode)); - result.SetBoolean("dynamic_sts_include_subdomains", + result.SetIntKey("dynamic_upgrade_mode", + static_cast<int>(dynamic_sts_state.upgrade_mode)); + result.SetBoolKey("dynamic_sts_include_subdomains", dynamic_sts_state.include_subdomains); - result.SetDouble("dynamic_sts_observed", - dynamic_sts_state.last_observed.ToDoubleT()); - result.SetDouble("dynamic_sts_expiry", - dynamic_sts_state.expiry.ToDoubleT()); - result.SetString("dynamic_sts_domain", dynamic_sts_state.domain); + result.SetDoubleKey("dynamic_sts_observed", + dynamic_sts_state.last_observed.ToDoubleT()); + result.SetDoubleKey("dynamic_sts_expiry", + dynamic_sts_state.expiry.ToDoubleT()); + result.SetStringKey("dynamic_sts_domain", dynamic_sts_state.domain); } if (found_pkp_dynamic) { - result.SetBoolean("dynamic_pkp_include_subdomains", + result.SetBoolKey("dynamic_pkp_include_subdomains", dynamic_pkp_state.include_subdomains); - result.SetDouble("dynamic_pkp_observed", - dynamic_pkp_state.last_observed.ToDoubleT()); - result.SetDouble("dynamic_pkp_expiry", - dynamic_pkp_state.expiry.ToDoubleT()); - result.SetString("dynamic_spki_hashes", - HashesToBase64String(dynamic_pkp_state.spki_hashes)); - result.SetString("dynamic_pkp_domain", dynamic_pkp_state.domain); + result.SetDoubleKey("dynamic_pkp_observed", + dynamic_pkp_state.last_observed.ToDoubleT()); + result.SetDoubleKey("dynamic_pkp_expiry", + dynamic_pkp_state.expiry.ToDoubleT()); + result.SetStringKey( + "dynamic_spki_hashes", + HashesToBase64String(dynamic_pkp_state.spki_hashes)); + result.SetStringKey("dynamic_pkp_domain", dynamic_pkp_state.domain); } - result.SetBoolean("result", + result.SetBoolKey("result", found_static || found_sts_dynamic || found_pkp_dynamic); } else { - result.SetString("error", "no TransportSecurityState active"); + result.SetStringKey("error", "no TransportSecurityState active"); } } else { - result.SetString("error", "non-ASCII domain name"); + result.SetStringKey("error", "non-ASCII domain name"); } std::move(callback).Run(std::move(result));
diff --git a/skia/OWNERS b/skia/OWNERS index dd0fc59..7fec08d 100644 --- a/skia/OWNERS +++ b/skia/OWNERS
@@ -1,5 +1,4 @@ set noparent -alokp@chromium.org borenet@google.com brianosman@google.com bsalomon@google.com
diff --git a/sql/meta_table.cc b/sql/meta_table.cc index f43d43e..c11e85b 100644 --- a/sql/meta_table.cc +++ b/sql/meta_table.cc
@@ -68,23 +68,31 @@ } // static -void MetaTable::RazeIfDeprecated(Database* db, int deprecated_version) { - DCHECK_GT(deprecated_version, 0); - DCHECK_EQ(0, db->transaction_nesting()); - - if (!DoesTableExist(db)) +void MetaTable::RazeIfIncompatible(Database* db, + int lowest_supported_version, + int current_version) { + if (!sql::MetaTable::DoesTableExist(db)) return; - // TODO(shess): Share sql with PrepareGetStatement(). - sql::Statement s(db->GetUniqueStatement( - "SELECT value FROM meta WHERE key=?")); + // TODO(crbug.com/1228463): Share sql with PrepareGetStatement(). + sql::Statement s( + db->GetUniqueStatement("SELECT value FROM meta WHERE key=?")); s.BindCString(0, kVersionKey); if (!s.Step()) return; + int on_disk_schema_version = s.ColumnInt(0); - int version = s.ColumnInt(0); + s.Assign(db->GetUniqueStatement("SELECT value FROM meta WHERE key=?")); + s.BindCString(0, kCompatibleVersionKey); + if (!s.Step()) + return; + int on_disk_compatible_version = s.ColumnInt(0); + s.Clear(); // Clear potential automatic transaction for Raze(). - if (version <= deprecated_version) { + + if ((lowest_supported_version != kNoLowestSupportedVersion && + lowest_supported_version > on_disk_schema_version) || + (current_version < on_disk_compatible_version)) { db->Raze(); return; } @@ -205,15 +213,15 @@ void MetaTable::PrepareSetStatement(Statement* statement, const char* key) { DCHECK(db_ && statement); - statement->Assign(db_->GetCachedStatement(SQL_FROM_HERE, - "INSERT OR REPLACE INTO meta (key,value) VALUES (?,?)")); + statement->Assign(db_->GetCachedStatement( + SQL_FROM_HERE, "INSERT OR REPLACE INTO meta (key,value) VALUES (?,?)")); statement->BindCString(0, key); } bool MetaTable::PrepareGetStatement(Statement* statement, const char* key) { DCHECK(db_ && statement); - statement->Assign(db_->GetCachedStatement(SQL_FROM_HERE, - "SELECT value FROM meta WHERE key=?")); + statement->Assign(db_->GetCachedStatement( + SQL_FROM_HERE, "SELECT value FROM meta WHERE key=?")); statement->BindCString(0, key); return statement->Step(); }
diff --git a/sql/meta_table.h b/sql/meta_table.h index 8ffbc8b..f723ea8 100644 --- a/sql/meta_table.h +++ b/sql/meta_table.h
@@ -9,6 +9,8 @@ #include <string> #include "base/component_export.h" +#include "base/macros.h" +#include "third_party/abseil-cpp/absl/types/optional.h" namespace sql { @@ -28,9 +30,9 @@ MetaTable& operator=(const MetaTable&) = delete; ~MetaTable(); - // Values for Get/SetMmapStatus(). |kMmapFailure| indicates that there was at + // Values for Get/SetMmapStatus(). `kMmapFailure` indicates that there was at // some point a read error and the database should not be memory-mapped, while - // |kMmapSuccess| indicates that the entire file was read at some point and + // `kMmapSuccess` indicates that the entire file was read at some point and // can be memory-mapped without constraint. static constexpr int64_t kMmapFailure = -2; static constexpr int64_t kMmapSuccess = -1; @@ -43,32 +45,37 @@ // table existed). static bool DeleteTableForTesting(Database* db); - // If the current version of the database is less than or equal to - // |deprecated_version|, raze the database. Must be called outside of a - // transaction. - // TODO(shess): At this time the database is razed IFF meta exists and - // contains a version row with value <= deprecated_version. It may make sense - // to also raze if meta exists but has no version row, or if meta doesn't - // exist. In those cases if the database is not already empty, it probably - // resulted from a broken initialization. - // TODO(shess): Folding this into Init() would allow enforcing - // |deprecated_version|<|version|. But Init() is often called in a - // transaction. - static void RazeIfDeprecated(Database* db, int deprecated_version); + // If the current version of the database is less than + // `lowest_supported_version`, or the current version is less than the + // database's least compatible version, razes the database. To only enforce + // the latter, pass `kNoLowestSupportedVersion` for + // `lowest_supported_version`. + // + // TODO(crbug.com/1228463): At this time the database is razed IFF meta exists + // and contains a version row with the value not satisfying the constraints. + // It may make sense to also raze if meta exists but has no version row, or if + // meta doesn't exist. In those cases if the database is not already empty, it + // probably resulted from a broken initialization. + // TODO(crbug.com/1228463): Folding this into Init() would allow enforcing + // the version constraint, but Init() is often called in a transaction. + static constexpr int kNoLowestSupportedVersion = 0; + static void RazeIfIncompatible(Database* db, + int lowest_supported_version, + int current_version); // Used to tuck some data into the meta table about mmap status. The value // represents how much data in bytes has successfully been read from the - // database, or |kMmapFailure| or |kMmapSuccess|. + // database, or `kMmapFailure` or `kMmapSuccess`. static bool GetMmapStatus(Database* db, int64_t* status); static bool SetMmapStatus(Database* db, int64_t status); - // Initializes the MetaTableHelper, providing the |Database| pointer and + // Initializes the MetaTableHelper, providing the `Database` pointer and // creating the meta table if necessary. Must be called before any other // non-static methods. For new tables, it will initialize the version number - // to |version| and the compatible version number to |compatible_version|. + // to `version` and the compatible version number to `compatible_version`. // Versions must be greater than 0 to distinguish missing versions (see // GetVersionNumber()). If there was no meta table (proxy for a fresh - // database), mmap status is set to |kMmapSuccess|. + // database), mmap status is set to `kMmapSuccess`. bool Init(Database* db, int version, int compatible_version); // Resets this MetaTable object, making another call to Init() possible.
diff --git a/sql/meta_table_unittest.cc b/sql/meta_table_unittest.cc index 19a3d1f..4f7ff2e 100644 --- a/sql/meta_table_unittest.cc +++ b/sql/meta_table_unittest.cc
@@ -50,62 +50,97 @@ EXPECT_FALSE(MetaTable::DoesTableExist(&db_)); } -TEST_F(SQLMetaTableTest, RazeIfDeprecated) { - const int kDeprecatedVersion = 1; - const int kVersion = 2; +TEST_F(SQLMetaTableTest, RazeIfIncompatiblePreservesDatabasesWithoutMetadata) { + EXPECT_TRUE(db_.Execute("CREATE TABLE data(id INTEGER PRIMARY KEY)")); + ASSERT_TRUE(db_.DoesTableExist("data")); + + // The table should not have been cleared, since the database does not have a + // metadata table. + MetaTable::RazeIfIncompatible(&db_, 1, + /*current_version=*/1); + EXPECT_TRUE(db_.DoesTableExist("data")); +} + +TEST_F(SQLMetaTableTest, RazeIfIncompatibleRazesIncompatiblyOldTables) { + constexpr int kWrittenVersion = 1; + constexpr int kCompatibleVersion = 1; // Setup a current database. { MetaTable meta_table; - EXPECT_TRUE(meta_table.Init(&db_, kVersion, kVersion)); - EXPECT_TRUE(db_.Execute("CREATE TABLE t(c)")); - EXPECT_TRUE(db_.DoesTableExist("t")); + EXPECT_TRUE(meta_table.Init(&db_, kWrittenVersion, kCompatibleVersion)); + EXPECT_TRUE(db_.Execute("CREATE TABLE data(id INTEGER PRIMARY KEY)")); + ASSERT_TRUE(db_.DoesTableExist("data")); } - // Table should should still exist if the database version is new enough. - MetaTable::RazeIfDeprecated(&db_, kDeprecatedVersion); - EXPECT_TRUE(db_.DoesTableExist("t")); + // The table should have been cleared, since the least version compatible with + // the written database is greater than the current version. + MetaTable::RazeIfIncompatible(&db_, kWrittenVersion + 1, + /*current_version=*/kWrittenVersion + 1); + EXPECT_FALSE(db_.DoesTableExist("data")); +} - // TODO(shess): It may make sense to Raze() if meta isn't present or - // version isn't present. See meta_table.h TODO on RazeIfDeprecated(). +TEST_F(SQLMetaTableTest, RazeIfIncompatibleRazesIncompatiblyNewTables) { + constexpr int kCompatibleVersion = 2; + constexpr int kWrittenVersion = 3; - // Table should still exist if the version is not available. - EXPECT_TRUE(db_.Execute("DELETE FROM meta WHERE key = 'version'")); + // Setup a current database. { MetaTable meta_table; - EXPECT_TRUE(meta_table.Init(&db_, kVersion, kVersion)); - EXPECT_EQ(0, meta_table.GetVersionNumber()); + EXPECT_TRUE(meta_table.Init(&db_, kWrittenVersion, kCompatibleVersion)); + EXPECT_TRUE(db_.Execute("CREATE TABLE data(id INTEGER PRIMARY KEY)")); + ASSERT_TRUE(db_.DoesTableExist("data")); } - MetaTable::RazeIfDeprecated(&db_, kDeprecatedVersion); - EXPECT_TRUE(db_.DoesTableExist("t")); - // Table should still exist if meta table is missing. - EXPECT_TRUE(db_.Execute("DROP TABLE meta")); - MetaTable::RazeIfDeprecated(&db_, kDeprecatedVersion); - EXPECT_TRUE(db_.DoesTableExist("t")); + // The table should have been cleared, since the least version compatible with + // the written database is greater than the current version. + MetaTable::RazeIfIncompatible(&db_, MetaTable::kNoLowestSupportedVersion, + /*current_version=*/kCompatibleVersion - 1); + EXPECT_FALSE(db_.DoesTableExist("data")); +} - // Setup meta with deprecated version. +TEST_F(SQLMetaTableTest, RazeIfIncompatibleDoesntRazeWhenItShouldnt) { + constexpr int kVersion = 2; + { MetaTable meta_table; - EXPECT_TRUE(meta_table.Init(&db_, kDeprecatedVersion, kDeprecatedVersion)); + EXPECT_TRUE( + meta_table.Init(&db_, kVersion, /*compatible_version=*/kVersion - 1)); + EXPECT_TRUE(db_.Execute("CREATE TABLE data(id INTEGER PRIMARY KEY)")); + EXPECT_TRUE(db_.DoesTableExist("data")); } - // Deprecation check should remove the table. - EXPECT_TRUE(db_.DoesTableExist("t")); - MetaTable::RazeIfDeprecated(&db_, kDeprecatedVersion); - EXPECT_FALSE(MetaTable::DoesTableExist(&db_)); - EXPECT_FALSE(db_.DoesTableExist("t")); + MetaTable::RazeIfIncompatible(&db_, kVersion, + /*current_version=*/kVersion); + EXPECT_TRUE(db_.DoesTableExist("data")) + << "Table should still exist if the database version is exactly right."; + + MetaTable::RazeIfIncompatible(&db_, kVersion - 1, + /*current_version=*/kVersion); + EXPECT_TRUE(db_.DoesTableExist("data")) + << "... or if the lower bound is less than the actual version"; + + MetaTable::RazeIfIncompatible(&db_, MetaTable::kNoLowestSupportedVersion, + /*current_version=*/kVersion); + EXPECT_TRUE(db_.DoesTableExist("data")) + << "... or if the lower bound is not set"; + + MetaTable::RazeIfIncompatible(&db_, MetaTable::kNoLowestSupportedVersion, + /*current_version=*/kVersion - 1); + EXPECT_TRUE(db_.DoesTableExist("data")) + << "... even if the current version exactly matches the written " + "database's least compatible version."; } TEST_F(SQLMetaTableTest, VersionNumber) { // Compatibility versions one less than the main versions to make // sure the values aren't being crossed with each other. - const int kVersionFirst = 2; - const int kCompatVersionFirst = kVersionFirst - 1; - const int kVersionSecond = 4; - const int kCompatVersionSecond = kVersionSecond - 1; - const int kVersionThird = 6; - const int kCompatVersionThird = kVersionThird - 1; + constexpr int kVersionFirst = 2; + constexpr int kCompatVersionFirst = kVersionFirst - 1; + constexpr int kVersionSecond = 4; + constexpr int kCompatVersionSecond = kVersionSecond - 1; + constexpr int kVersionThird = 6; + constexpr int kCompatVersionThird = kVersionThird - 1; // First Init() sets the version info as expected. { @@ -178,8 +213,8 @@ TEST_F(SQLMetaTableTest, IntValue) { static const char kKey[] = "Int Key"; - const int kFirstValue = 17; - const int kSecondValue = 23; + constexpr int kFirstValue = 17; + constexpr int kSecondValue = 23; // Initially, the value isn't there until set. {
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index ea0a554..479fd38 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -83276,6 +83276,2105 @@ } ] }, + "linux-exp-code-coverage": { + "gtest_tests": [ + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "absl_hardening_tests", + "test_id_prefix": "ninja://third_party/abseil-cpp:absl_hardening_tests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "accessibility_unittests", + "test_id_prefix": "ninja://ui/accessibility:accessibility_unittests/" + }, + { + "args": [ + "angle_unittests" + ], + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "angle_unittests", + "test_id_prefix": "ninja://third_party/angle/src/tests:angle_unittests/", + "use_isolated_scripts_api": true + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "app_shell_unittests", + "test_id_prefix": "ninja://extensions/shell:app_shell_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "aura_unittests", + "test_id_prefix": "ninja://ui/aura:aura_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "base_unittests", + "test_id_prefix": "ninja://base:base_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "base_util_unittests", + "test_id_prefix": "ninja://base/util:base_util_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "blink_common_unittests", + "test_id_prefix": "ninja://third_party/blink/common:blink_common_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "blink_fuzzer_unittests", + "test_id_prefix": "ninja://third_party/blink/renderer/platform:blink_fuzzer_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "blink_heap_unittests", + "test_id_prefix": "ninja://third_party/blink/renderer/platform/heap:blink_heap_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "blink_platform_unittests", + "test_id_prefix": "ninja://third_party/blink/renderer/platform:blink_platform_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "name": "webkit_unit_tests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "blink_unittests", + "test_id_prefix": "ninja://third_party/blink/renderer/controller:blink_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "boringssl_crypto_tests", + "test_id_prefix": "ninja://third_party/boringssl:boringssl_crypto_tests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "boringssl_ssl_tests", + "test_id_prefix": "ninja://third_party/boringssl:boringssl_ssl_tests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 10 + }, + "test": "browser_tests", + "test_id_prefix": "ninja://chrome/test:browser_tests/" + }, + { + "args": [ + "--gtest_filter=-*UsingRealWebcam*" + ], + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "capture_unittests", + "test_id_prefix": "ninja://media/capture:capture_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "cast_unittests", + "test_id_prefix": "ninja://media/cast:cast_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "cc_unittests", + "test_id_prefix": "ninja://cc:cc_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "chrome_app_unittests", + "test_id_prefix": "ninja://chrome/test:chrome_app_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "chromedriver_unittests", + "test_id_prefix": "ninja://chrome/test/chromedriver:chromedriver_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "color_unittests", + "test_id_prefix": "ninja://ui/color:color_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "components_browsertests", + "test_id_prefix": "ninja://components:components_browsertests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "components_unittests", + "test_id_prefix": "ninja://components:components_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "compositor_unittests", + "test_id_prefix": "ninja://ui/compositor:compositor_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 6 + }, + "test": "content_browsertests", + "test_id_prefix": "ninja://content/test:content_browsertests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "content_unittests", + "test_id_prefix": "ninja://content/test:content_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "crashpad_tests", + "test_id_prefix": "ninja://third_party/crashpad/crashpad:crashpad_tests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "cronet_tests", + "test_id_prefix": "ninja://components/cronet:cronet_tests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "cronet_unittests", + "test_id_prefix": "ninja://components/cronet:cronet_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "crypto_unittests", + "test_id_prefix": "ninja://crypto:crypto_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "dbus_unittests", + "test_id_prefix": "ninja://dbus:dbus_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "device_unittests", + "test_id_prefix": "ninja://device:device_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "display_unittests", + "test_id_prefix": "ninja://ui/display:display_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "events_unittests", + "test_id_prefix": "ninja://ui/events:events_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "extensions_browsertests", + "test_id_prefix": "ninja://extensions:extensions_browsertests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "extensions_unittests", + "test_id_prefix": "ninja://extensions:extensions_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "filesystem_service_unittests", + "test_id_prefix": "ninja://components/services/filesystem:filesystem_service_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "gcm_unit_tests", + "test_id_prefix": "ninja://google_apis/gcm:gcm_unit_tests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "gfx_unittests", + "test_id_prefix": "ninja://ui/gfx:gfx_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "gin_unittests", + "test_id_prefix": "ninja://gin:gin_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "google_apis_unittests", + "test_id_prefix": "ninja://google_apis:google_apis_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "gpu_unittests", + "test_id_prefix": "ninja://gpu:gpu_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "gtk_unittests", + "test_id_prefix": "ninja://ui/gtk:gtk_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "gwp_asan_unittests", + "test_id_prefix": "ninja://components/gwp_asan:gwp_asan_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "headless_browsertests", + "test_id_prefix": "ninja://headless:headless_browsertests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "headless_unittests", + "test_id_prefix": "ninja://headless:headless_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 + }, + "test": "interactive_ui_tests", + "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "ipc_tests", + "test_id_prefix": "ninja://ipc:ipc_tests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "jingle_unittests", + "test_id_prefix": "ninja://jingle:jingle_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "latency_unittests", + "test_id_prefix": "ninja://ui/latency:latency_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "libjingle_xmpp_unittests", + "test_id_prefix": "ninja://third_party/libjingle_xmpp:libjingle_xmpp_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "liburlpattern_unittests", + "test_id_prefix": "ninja://third_party/liburlpattern:liburlpattern_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "media_unittests", + "test_id_prefix": "ninja://media:media_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "message_center_unittests", + "test_id_prefix": "ninja://ui/message_center:message_center_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "midi_unittests", + "test_id_prefix": "ninja://media/midi:midi_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "mojo_core_unittests", + "test_id_prefix": "ninja://mojo/core:mojo_core_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "mojo_unittests", + "test_id_prefix": "ninja://mojo:mojo_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "nacl_helper_nonsfi_unittests", + "test_id_prefix": "ninja://components/nacl/loader:nacl_helper_nonsfi_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "nacl_loader_unittests", + "test_id_prefix": "ninja://components/nacl/loader:nacl_loader_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "native_theme_unittests", + "test_id_prefix": "ninja://ui/native_theme:native_theme_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "net_unittests", + "test_id_prefix": "ninja://net:net_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "openscreen_unittests", + "test_id_prefix": "ninja://chrome/browser/media/router:openscreen_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "pdf_unittests", + "test_id_prefix": "ninja://pdf:pdf_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "perfetto_unittests", + "test_id_prefix": "ninja://third_party/perfetto:perfetto_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "ppapi_unittests", + "test_id_prefix": "ninja://ppapi:ppapi_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "printing_unittests", + "test_id_prefix": "ninja://printing:printing_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "remoting_unittests", + "test_id_prefix": "ninja://remoting:remoting_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "sandbox_linux_unittests", + "test_id_prefix": "ninja://sandbox/linux:sandbox_linux_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "service_manager_unittests", + "test_id_prefix": "ninja://services/service_manager/tests:service_manager_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "services_unittests", + "test_id_prefix": "ninja://services:services_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "shell_dialogs_unittests", + "test_id_prefix": "ninja://ui/shell_dialogs:shell_dialogs_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "skia_unittests", + "test_id_prefix": "ninja://skia:skia_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "snapshot_unittests", + "test_id_prefix": "ninja://ui/snapshot:snapshot_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "sql_unittests", + "test_id_prefix": "ninja://sql:sql_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "storage_unittests", + "test_id_prefix": "ninja://storage:storage_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "sync_integration_tests", + "test_id_prefix": "ninja://chrome/test:sync_integration_tests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "traffic_annotation_auditor_unittests", + "test_id_prefix": "ninja://tools/traffic_annotation/auditor:traffic_annotation_auditor_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "ui_base_unittests", + "test_id_prefix": "ninja://ui/base:ui_base_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "ui_touch_selection_unittests", + "test_id_prefix": "ninja://ui/touch_selection:ui_touch_selection_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "unit_tests", + "test_id_prefix": "ninja://chrome/test:unit_tests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "url_unittests", + "test_id_prefix": "ninja://url:url_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "views_unittests", + "test_id_prefix": "ninja://ui/views:views_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "viz_unittests", + "test_id_prefix": "ninja://components/viz:viz_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "vr_common_unittests", + "test_id_prefix": "ninja://chrome/browser/vr:vr_common_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "vr_pixeltests", + "test_id_prefix": "ninja://chrome/browser/vr:vr_pixeltests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "weblayer_browsertests", + "test_id_prefix": "ninja://weblayer/test:weblayer_browsertests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "weblayer_unittests", + "test_id_prefix": "ninja://weblayer/test:weblayer_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "wm_unittests", + "test_id_prefix": "ninja://ui/wm:wm_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "wtf_unittests", + "test_id_prefix": "ninja://third_party/blink/renderer/platform/wtf:wtf_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "x11_unittests", + "test_id_prefix": "ninja://ui/platform_window/x11:x11_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "name": "xr_browser_tests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "xr_browser_tests", + "test_id_prefix": "ninja://chrome/test:xr_browser_tests/" + }, + { + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "zlib_unittests", + "test_id_prefix": "ninja://third_party/zlib:zlib_unittests/" + } + ], + "isolated_scripts": [ + { + "isolate_name": "blink_python_tests", + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "blink_python_tests", + "resultdb": { + "enable": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://:blink_python_tests/" + }, + { + "args": [ + "--num-retries=3", + "--additional-env-var=LLVM_PROFILE_FILE=${ISOLATED_OUTDIR}/profraw/default-%2m.profraw" + ], + "isolate_name": "blink_web_tests", + "isolate_profile_data": true, + "merge": { + "args": [ + "--verbose" + ], + "script": "//third_party/blink/tools/merge_web_test_results.py" + }, + "name": "blink_web_tests", + "resultdb": { + "enable": true + }, + "results_handler": "layout tests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 20 + }, + "test_id_prefix": "ninja://:blink_web_tests/" + }, + { + "args": [ + "--test-type=integration" + ], + "isolate_name": "chromedriver_py_tests", + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "chromedriver_py_tests", + "resultdb": { + "enable": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://chrome/test/chromedriver:chromedriver_py_tests/" + }, + { + "isolate_name": "chromedriver_replay_unittests", + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "chromedriver_replay_unittests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://chrome/test/chromedriver:chromedriver_replay_unittests/" + }, + { + "isolate_name": "content_shell_crash_test", + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "content_shell_crash_test", + "resultdb": { + "enable": true, + "result_format": "single" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://content/shell:content_shell_crash_test/" + }, + { + "isolate_name": "flatbuffers_unittests", + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "flatbuffers_unittests", + "resultdb": { + "enable": true, + "result_format": "single" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://third_party/flatbuffers:flatbuffers_unittests/" + }, + { + "isolate_name": "grit_python_unittests", + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "grit_python_unittests", + "resultdb": { + "enable": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://tools/grit:grit_python_unittests/" + }, + { + "isolate_name": "mojo_python_unittests", + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "mojo_python_unittests", + "resultdb": { + "enable": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://mojo/public/tools:mojo_python_unittests/" + }, + { + "args": [ + "--additional-driver-flag", + "--disable-site-isolation-trials", + "--additional-expectations=../../third_party/blink/web_tests/FlagExpectations/disable-site-isolation-trials", + "--num-retries=3" + ], + "isolate_name": "blink_web_tests", + "isolate_profile_data": true, + "merge": { + "args": [ + "--verbose" + ], + "script": "//third_party/blink/tools/merge_web_test_results.py" + }, + "name": "not_site_per_process_blink_web_tests", + "resultdb": { + "enable": true + }, + "results_handler": "layout tests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 10 + }, + "test_id_prefix": "ninja://:blink_web_tests/" + }, + { + "isolate_name": "telemetry_gpu_unittests", + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "telemetry_gpu_unittests", + "resultdb": { + "enable": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_unittests/" + }, + { + "args": [ + "--extra-browser-args=--enable-crashpad" + ], + "isolate_name": "telemetry_perf_unittests", + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "telemetry_perf_unittests", + "resultdb": { + "enable": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 12 + }, + "test_id_prefix": "ninja://chrome/test:telemetry_perf_unittests/" + }, + { + "args": [ + "--jobs=1", + "--extra-browser-args=--disable-gpu" + ], + "isolate_name": "telemetry_unittests", + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "telemetry_unittests", + "resultdb": { + "enable": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 8 + }, + "test_id_prefix": "ninja://chrome/test:telemetry_unittests/" + }, + { + "args": [ + "--gtest-benchmark-name=views_perftests" + ], + "isolate_name": "views_perftests", + "isolate_profile_data": true, + "merge": { + "args": [ + "--smoke-test-mode" + ], + "script": "//tools/perf/process_perf_results.py" + }, + "name": "views_perftests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ui/views:views_perftests/" + }, + { + "args": [ + "--num-retries=3", + "--additional-driver-flag=--enable-gpu-rasterization", + "--additional-driver-flag=--enable-features=UseSkiaRenderer,Vulkan", + "--additional-driver-flag=--enable-oop-rasterization", + "--additional-driver-flag=--use-vulkan=swiftshader", + "--additional-driver-flag=--disable-vulkan-fallback-to-gl-for-testing", + "--fuzzy-diff", + "--skipped=always", + "--test-list=../../testing/buildbot/filters/gpu.skiarenderer_vulkan_blink_web_tests.filter", + "--additional-expectations=../../third_party/blink/web_tests/FlagExpectations/enable-features=UseSkiaRenderer", + "--additional-expectations=../../third_party/blink/web_tests/FlagExpectations/enable-gpu-rasterization", + "--additional-expectations=../../third_party/blink/web_tests/FlagExpectations/use-vulkan=swiftshader" + ], + "isolate_name": "blink_web_tests", + "isolate_profile_data": true, + "merge": { + "args": [ + "--verbose" + ], + "script": "//third_party/blink/tools/merge_web_test_results.py" + }, + "name": "vulkan_swiftshader_blink_web_tests", + "resultdb": { + "enable": true + }, + "results_handler": "layout tests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://:blink_web_tests/" + }, + { + "isolate_name": "webdriver_wpt_tests", + "isolate_profile_data": true, + "merge": { + "args": [ + "--verbose" + ], + "script": "//third_party/blink/tools/merge_web_test_results.py" + }, + "name": "webdriver_tests_suite", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 4 + }, + "test_id_prefix": "ninja://:webdriver_wpt_tests/" + } + ], + "scripts": [ + { + "isolate_profile_data": true, + "name": "check_network_annotations", + "script": "check_network_annotations.py", + "swarming": {} + }, + { + "isolate_profile_data": true, + "name": "check_static_initializers", + "script": "check_static_initializers.py", + "swarming": {} + }, + { + "isolate_profile_data": true, + "name": "checkdeps", + "script": "checkdeps.py", + "swarming": {} + }, + { + "isolate_profile_data": true, + "name": "checkperms", + "script": "checkperms.py", + "swarming": {} + }, + { + "isolate_profile_data": true, + "name": "headless_python_unittests", + "script": "headless_python_unittests.py", + "swarming": {} + }, + { + "isolate_profile_data": true, + "name": "metrics_python_tests", + "script": "metrics_python_tests.py", + "swarming": {} + }, + { + "isolate_profile_data": true, + "name": "webkit_lint", + "script": "blink_lint_expectations.py", + "swarming": {} + } + ] + }, "linux-fieldtrial-rel": { "gtest_tests": [ {
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index 908c240..3c8f996c 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -479,6 +479,14 @@ 'shards': 20, }, }, + 'linux-exp-code-coverage': { + 'args': [ + '--additional-env-var=LLVM_PROFILE_FILE=${ISOLATED_OUTDIR}/profraw/default-%2m.profraw', + ], + 'swarming': { + 'shards': 20, + }, + }, 'linux-layout-tests-edit-ng': { 'args': [ '--additional-driver-flag=--enable-blink-features=EditingNG',
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index c6511f56..f332f26 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -3183,6 +3183,17 @@ 'gtest_tests': 'linux_example_builder_gtests', }, }, + 'linux-exp-code-coverage': { + 'mixins': [ + 'isolate_profile_data', + 'linux-bionic', + ], + 'test_suites': { + 'gtest_tests': 'chromium_linux_gtests', + 'isolated_scripts': 'chromium_linux_rel_isolated_scripts', + 'scripts': 'chromium_linux_scripts', + }, + }, 'linux-fieldtrial-rel': { 'mixins': [ 'linux-bionic',
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index bf7bc0d..7fd1b1b 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -6647,7 +6647,7 @@ "name": "Enabled", "params": { "enable_quic": "true", - "quic_version": "h3-29,h3-Q050", + "quic_version": "h3,h3-29,h3-Q050", "retransmittable_on_wire_timeout_milliseconds": "200" }, "enable_features": [
diff --git a/third_party/blink/public/mojom/link_to_text/link_to_text.mojom b/third_party/blink/public/mojom/link_to_text/link_to_text.mojom index 048ad17..ffecbad 100644 --- a/third_party/blink/public/mojom/link_to_text/link_to_text.mojom +++ b/third_party/blink/public/mojom/link_to_text/link_to_text.mojom
@@ -8,8 +8,10 @@ import "ui/gfx/geometry/mojom/geometry.mojom"; // TextFragmentReceiver is used for requesting renderer to perform text fragment -// operations on the main frame, mainly generating and removing fragments. -// Implemented in renderer. +// operations on the frame that interacts with the link-to-text/shared-highlighting +// feature, mainly generating and removing fragments. A text fragment receiver is +// associated with exactly one frame but a frame will only create its receiver +// lazily when needed. interface TextFragmentReceiver { // Cancel text fragment generation if in progress. Cancel(); @@ -19,7 +21,7 @@ // https://github.com/WICG/scroll-to-text-fragment. RequestSelector() => (string selector); - // Dismiss all text fragments from the current main frame at the time the + // Dismiss all text fragments from this frame at the time the // context menu was invoked. RemoveFragments();
diff --git a/third_party/blink/public/mojom/webid/federated_auth_request.mojom b/third_party/blink/public/mojom/webid/federated_auth_request.mojom index ffef84f..2753124 100644 --- a/third_party/blink/public/mojom/webid/federated_auth_request.mojom +++ b/third_party/blink/public/mojom/webid/federated_auth_request.mojom
@@ -40,10 +40,18 @@ // This interface is called from a renderer process and implemented in the // browser process. interface FederatedAuthRequest { - // Requests an IdToken to be generated, given an IDP URL and an OAuth request. + // Requests an IdToken to be generated, given an IDP URL, some request + // parameters, and a mode that specifies the UI flow. + // |client_id| and |nonce| can be empty strings to omit the fields in the + // request sent to the provider. // Returns the raw content of the IdToken. - RequestIdToken(url.mojom.Url provider, string id_request, RequestMode mode) => (RequestIdTokenStatus status, string? id_token); + RequestIdToken(url.mojom.Url provider, + string client_id, + string nonce, + RequestMode mode) => + (RequestIdTokenStatus status, string? id_token); - // Contact the list of Relying Party logout endpoints to attempt to initiate user logout. + // Contact the list of Relying Party logout endpoints to attempt to initiate + // user logout. Logout(array<string> rp_logout_endpoints) => (LogoutStatus status); };
diff --git a/third_party/blink/renderer/bindings/generated_in_modules.gni b/third_party/blink/renderer/bindings/generated_in_modules.gni index 3b34900..0d57134 100644 --- a/third_party/blink/renderer/bindings/generated_in_modules.gni +++ b/third_party/blink/renderer/bindings/generated_in_modules.gni
@@ -391,6 +391,8 @@ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_extent_3d_dict.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_external_texture_binding_layout.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_external_texture_binding_layout.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_external_texture_descriptor.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_external_texture_descriptor.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_fragment_state.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_fragment_state.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_image_copy_buffer.cc",
diff --git a/third_party/blink/renderer/core/BUILD.gn b/third_party/blink/renderer/core/BUILD.gn index 15cf975..d7c3833f 100644 --- a/third_party/blink/renderer/core/BUILD.gn +++ b/third_party/blink/renderer/core/BUILD.gn
@@ -1391,7 +1391,6 @@ "layout/ng/ng_column_layout_algorithm_test.cc", "layout/ng/ng_constraint_space_builder_test.cc", "layout/ng/ng_fieldset_layout_algorithm_test.cc", - "layout/ng/ng_fragment_child_iterator_test.cc", "layout/ng/ng_fragmentation_test.cc", "layout/ng/ng_ink_overflow_test.cc", "layout/ng/ng_inline_layout_test.cc",
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc index 1305ec45..2b96901 100644 --- a/third_party/blink/renderer/core/frame/local_frame.cc +++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -473,11 +473,8 @@ GetTaskRunner(blink::TaskType::kInternalDefault))); GetInterfaceRegistry()->AddAssociatedInterface(WTF::BindRepeating( &LocalFrame::BindToReceiver, WrapWeakPersistent(this))); - - if (IsMainFrame()) { - GetInterfaceRegistry()->AddInterface(WTF::BindRepeating( - &LocalFrame::BindTextFragmentReceiver, WrapWeakPersistent(this))); - } + GetInterfaceRegistry()->AddInterface(WTF::BindRepeating( + &LocalFrame::BindTextFragmentReceiver, WrapWeakPersistent(this))); DCHECK(!mojo_receiver_); mojo_receiver_ = MakeGarbageCollected<LocalFrameMojoReceiver>(*this); @@ -3880,9 +3877,13 @@ void LocalFrame::BindTextFragmentReceiver( mojo::PendingReceiver<mojom::blink::TextFragmentReceiver> receiver) { - if (IsDetached() || !text_fragment_handler_) + if (IsDetached()) return; + if (!text_fragment_handler_) { + text_fragment_handler_ = MakeGarbageCollected<TextFragmentHandler>(this); + } + text_fragment_handler_->BindTextFragmentReceiver(std::move(receiver)); }
diff --git a/third_party/blink/renderer/core/frame/local_frame.h b/third_party/blink/renderer/core/frame/local_frame.h index 9f6c04d..1e7189a 100644 --- a/third_party/blink/renderer/core/frame/local_frame.h +++ b/third_party/blink/renderer/core/frame/local_frame.h
@@ -798,6 +798,9 @@ // https://github.com/jeremyroman/alternate-loading-modes/blob/main/browsing-context.md#session-history bool ShouldMaintainTrivialSessionHistory() const; + void BindTextFragmentReceiver( + mojo::PendingReceiver<mojom::blink::TextFragmentReceiver> receiver); + private: friend class FrameNavigationDisabler; FRIEND_TEST_ALL_PREFIXES(LocalFrameTest, CharacterIndexAtPointWithPinchZoom); @@ -905,8 +908,6 @@ static void BindToReceiver( blink::LocalFrame* frame, mojo::PendingAssociatedReceiver<mojom::blink::LocalFrame> receiver); - void BindTextFragmentReceiver( - mojo::PendingReceiver<mojom::blink::TextFragmentReceiver> receiver); // Whether a navigation should replace the current history entry or not. // Note this isn't exhaustive; there are other cases where a navigation does a
diff --git a/third_party/blink/renderer/core/layout/build.gni b/third_party/blink/renderer/core/layout/build.gni index cf2afc0..a827731 100644 --- a/third_party/blink/renderer/core/layout/build.gni +++ b/third_party/blink/renderer/core/layout/build.gni
@@ -498,8 +498,6 @@ "ng/ng_floats_utils.h", "ng/ng_fragment.h", "ng/ng_fragment_builder.h", - "ng/ng_fragment_child_iterator.cc", - "ng/ng_fragment_child_iterator.h", "ng/ng_fragmentation_utils.cc", "ng/ng_fragmentation_utils.h", "ng/ng_ink_overflow.cc",
diff --git a/third_party/blink/renderer/core/layout/layout_object.cc b/third_party/blink/renderer/core/layout/layout_object.cc index c668328..f6bfc7c1 100644 --- a/third_party/blink/renderer/core/layout/layout_object.cc +++ b/third_party/blink/renderer/core/layout/layout_object.cc
@@ -473,14 +473,6 @@ NOT_DESTROYED(); if (!PaintInvalidationStateIsDirty() || ChildPrePaintBlockedByDisplayLock()) return; - // NG text objects are exempt, as pre-paint walking doesn't visit those with - // no paint effects (only white-space, for instance). - if ((IsText() && IsLayoutNGObject()) || - // and culled inline boxes too. - (IsInLayoutNGInlineFormattingContext() && IsLayoutInline()) || - // TablesNG columns are also not visited. - (IsLayoutTableCol() && IsLayoutNGObject())) - return; ShowLayoutTreeForThis(); NOTREACHED(); }
diff --git a/third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator.cc b/third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator.cc deleted file mode 100644 index bfa773e6..0000000 --- a/third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator.cc +++ /dev/null
@@ -1,188 +0,0 @@ -// 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 "third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator.h" - -#include "third_party/blink/renderer/core/layout/layout_box.h" -#include "third_party/blink/renderer/core/layout/ng/ng_block_break_token.h" -#include "third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.h" -#include "third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h" - -namespace blink { - -NGFragmentChildIterator::NGFragmentChildIterator( - const NGPhysicalBoxFragment& parent, - const NGBlockBreakToken* parent_break_token) - : parent_fragment_(&parent), - parent_break_token_(parent_break_token), - is_fragmentation_context_root_(parent.IsFragmentationContextRoot()) { - current_.link_.fragment = nullptr; - if (parent_break_token) - child_break_tokens_ = parent_break_token->ChildBreakTokens(); - if (parent.HasItems()) { - current_.cursor_.emplace(parent); - current_.block_break_token_ = parent_break_token; - UpdateSelfFromCursor(); - } else { - UpdateSelfFromFragment(); - } -} - -NGFragmentChildIterator::NGFragmentChildIterator( - const NGInlineCursor& parent, - const NGBlockBreakToken* parent_break_token, - base::span<const NGBreakToken* const> child_break_tokens) - : parent_break_token_(parent_break_token), - child_break_tokens_(child_break_tokens) { - current_.block_break_token_ = parent_break_token; - current_.link_.fragment = nullptr; - current_.cursor_ = parent.CursorForDescendants(); - UpdateSelfFromCursor(); -} - -NGFragmentChildIterator NGFragmentChildIterator::Descend() const { - if (current_.cursor_) { - const NGFragmentItem* item = current_.cursor_->CurrentItem(); - // Descend using the cursor if the current item doesn't establish a new - // formatting context. - if (!item->IsFormattingContextRoot()) { - return NGFragmentChildIterator( - *current_.cursor_, - current_.BlockBreakToken() ? parent_break_token_ : nullptr, - child_break_tokens_.subspan(child_break_token_idx_)); - } - } - DCHECK(current_.BoxFragment()); - return NGFragmentChildIterator(*current_.BoxFragment(), - current_.BlockBreakToken()); -} - -bool NGFragmentChildIterator::AdvanceChildFragment() { - DCHECK(parent_fragment_); - const auto children = parent_fragment_->Children(); - const NGPhysicalBoxFragment* previous_fragment = - To<NGPhysicalBoxFragment>(current_.link_.fragment); - DCHECK(previous_fragment); - if (child_fragment_idx_ < children.size()) - child_fragment_idx_++; - // There may be line box fragments among the children, and we're not - // interested in them (lines will already have been handled by the inline - // cursor). - SkipToBoxFragment(); - if (child_fragment_idx_ >= children.size()) - return false; - if (child_break_token_idx_ < child_break_tokens_.size()) - child_break_token_idx_++; - UpdateSelfFromFragment(previous_fragment); - return true; -} - -void NGFragmentChildIterator::UpdateSelfFromFragment( - const NGPhysicalBoxFragment* previous_fragment) { - DCHECK(parent_fragment_); - const auto children = parent_fragment_->Children(); - if (child_fragment_idx_ >= children.size()) - return; - current_.link_ = children[child_fragment_idx_]; - DCHECK(current_.link_.fragment); - SkipToBlockBreakToken(); - if (child_break_token_idx_ < child_break_tokens_.size()) { - current_.block_break_token_ = - To<NGBlockBreakToken>(child_break_tokens_[child_break_token_idx_]); - // TODO(mstensho): Clean up this. What we're trying to do here is to detect - // whether the incoming break token matches the current fragment or not. - // Figuring out if a fragment is generated from a given node is currently - // not possible without checking the LayoutObject associated. - const auto* layout_object = current_.link_.fragment->GetLayoutObject(); - if (layout_object && - layout_object != - current_.block_break_token_->InputNode().GetLayoutBox()) { - DCHECK(current_.link_.fragment->IsColumnSpanAll() || - // List markers are |IsMonolithic| that the flag doesn't matter. - current_.link_.fragment->IsListMarker()); - current_.break_token_for_fragmentainer_only_ = true; - } else { - current_.break_token_for_fragmentainer_only_ = false; - } - } else if (is_fragmentation_context_root_ && previous_fragment) { - // The outgoing break token from one fragmentainer is the incoming break - // token to the next one. This is also true when there are column spanners - // (and other types of non-fragmentainers) between two columns - // (fragmentainers); the outgoing break token from the former column will be - // ignored by any intervening spanners (and other non-fragmentainers), and - // then fed into the first column that comes after them, as an incoming - // break token. - // - // A multicol container may contain other kinds of children than - // fragmentainers, such as a column spanner, a list item marker (if the - // multicol container is a list item), a rendered legend (if the parent - // fieldset also establishes a multicol container), or an out-of-flow - // positioned fragment whose containing block is the multicol container - // itself (in which case the OOF doesn't participate in the fragmentation - // context established by the multicol container). We'll leave - // |current_.block_break_token_| alone then, as it will be used as an - // incoming break token when we get to the next column. - if (previous_fragment->IsFragmentainerBox()) { - current_.block_break_token_ = - To<NGBlockBreakToken>(previous_fragment->BreakToken()); - current_.break_token_for_fragmentainer_only_ = true; - } - } else { - current_.block_break_token_ = nullptr; - } -} - -bool NGFragmentChildIterator::AdvanceWithCursor() { - DCHECK(current_.cursor_); - current_.cursor_->MoveToNextSkippingChildren(); - UpdateSelfFromCursor(); - if (current_.cursor_->CurrentItem()) - return true; - // If there are more items, proceed and see if we have box fragment - // children. There may be out-of-flow positioned child fragments. - if (!parent_fragment_) - return false; - current_.cursor_.reset(); - SkipToBoxFragment(); - UpdateSelfFromFragment(); - return !IsAtEnd(); -} - -void NGFragmentChildIterator::UpdateSelfFromCursor() { - DCHECK(current_.cursor_); - // For inline items we just use the incoming break token to the containing - // block. - current_.block_break_token_ = parent_break_token_; - const NGFragmentItem* item = current_.cursor_->CurrentItem(); - if (!item) { - current_.link_.fragment = nullptr; - return; - } - current_.link_ = {item->BoxFragment(), item->OffsetInContainerFragment()}; -} - -void NGFragmentChildIterator::SkipToBoxFragment() { - for (const auto children = parent_fragment_->Children(); - child_fragment_idx_ < children.size(); child_fragment_idx_++) { - if (children[child_fragment_idx_].fragment->IsBox()) - break; - } -} - -void NGFragmentChildIterator::SkipToBlockBreakToken() { - // There may be inline break tokens here. Ignore them. - while (child_break_token_idx_ < child_break_tokens_.size()) { - const auto* current_break_token = DynamicTo<NGBlockBreakToken>( - child_break_tokens_[child_break_token_idx_]); - // Skip over any out-of-flow positioned break tokens that are the result of - // a break before. - if (current_break_token && - (!current_break_token->InputNode().IsOutOfFlowPositioned() || - !current_break_token->IsBreakBefore())) - return; - child_break_token_idx_++; - } -} - -} // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator.h b/third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator.h deleted file mode 100644 index 435a0af..0000000 --- a/third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator.h +++ /dev/null
@@ -1,143 +0,0 @@ -// 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 THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_NG_FRAGMENT_CHILD_ITERATOR_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_NG_FRAGMENT_CHILD_ITERATOR_H_ - -#include "base/containers/span.h" -#include "third_party/abseil-cpp/absl/types/optional.h" -#include "third_party/blink/renderer/core/core_export.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/ng_link.h" -#include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h" - -namespace blink { - -class LayoutObject; -class NGBlockBreakToken; - -// Iterator for children of a box fragment. Supports fragment items and break -// tokens. To advance to the next sibling, call |Advance()|. To descend into -// children of the current child, call |Descend()|. -// -// Using this class requires LayoutNGFragmentItem to be enabled. While fragment -// items are in a flat list representing the contents of an inline formatting -// context, the iterator will to a certain extent restore the object hierarchy, -// so that we can calculate the global offset of children of a relatively -// positioned inline correctly. -class CORE_EXPORT NGFragmentChildIterator { - STACK_ALLOCATED(); - - public: - explicit NGFragmentChildIterator( - const NGPhysicalBoxFragment& parent, - const NGBlockBreakToken* parent_break_token = nullptr); - - // Create a child iterator for the current child. - NGFragmentChildIterator Descend() const; - - // Move to the next sibling. Return false if there's no next sibling. Once - // false is returned, this object is in an unusable state, with the exception - // that calling IsAtEnd() is allowed. - bool Advance() { - if (current_.cursor_) - return AdvanceWithCursor(); - return AdvanceChildFragment(); - } - - bool IsAtEnd() { - if (current_.cursor_) - return !*current_.cursor_; - DCHECK(parent_fragment_); - const auto children = parent_fragment_->Children(); - return child_fragment_idx_ >= children.size(); - } - - class Current { - STACK_ALLOCATED(); - - friend class NGFragmentChildIterator; - - public: - // Return the current NGLink. Note that its offset is relative to the inline - // formatting context root, if the fragment / item participates in one. - const NGLink& Link() const { return link_; } - - const NGPhysicalBoxFragment* BoxFragment() const { - return To<NGPhysicalBoxFragment>(link_.fragment); - } - const NGFragmentItem* FragmentItem() const { - if (!cursor_) - return nullptr; - return cursor_->CurrentItem(); - } - - // Get the incoming break token for the current child, i.e. the context at - // which layout of this child's node was resumed. Note that for text and - // non-atomic inlines this will be the incoming block break token to the - // inline formatting context root. For monolithic content, no break token - // will be returned (since such content isn't considered to participate in a - // fragmentation context). - const NGBlockBreakToken* BlockBreakToken() const { - if (LIKELY(!block_break_token_)) - return nullptr; - if (link_.fragment) { - // Don't pass the break token into monolithic content. - if (link_.fragment->IsMonolithic()) - return nullptr; - // If the break token we've found is from a fragmentainer, it's only to - // be used by a subsequent fragmentainer. Other fragment types (such as - // column spanners) need to ignore it. - if (break_token_for_fragmentainer_only_ && - !link_.fragment->IsFragmentainerBox()) - return nullptr; - } - return block_break_token_; - } - - const LayoutObject* GetLayoutObject() const { - if (const NGFragmentItem* item = FragmentItem()) - return item->GetLayoutObject(); - return BoxFragment()->GetLayoutObject(); - } - - private: - NGLink link_; - absl::optional<NGInlineCursor> cursor_; - const NGBlockBreakToken* block_break_token_ = nullptr; - bool break_token_for_fragmentainer_only_ = false; - }; - - const Current& GetCurrent() const { return current_; } - const Current& operator*() const { return current_; } - const Current* operator->() const { return ¤t_; } - - private: - NGFragmentChildIterator( - const NGInlineCursor& parent, - const NGBlockBreakToken* parent_break_token, - base::span<const NGBreakToken* const> child_break_tokens); - - bool AdvanceChildFragment(); - void UpdateSelfFromFragment( - const NGPhysicalBoxFragment* previous_fragment = nullptr); - - bool AdvanceWithCursor(); - void UpdateSelfFromCursor(); - void SkipToBoxFragment(); - void SkipToBlockBreakToken(); - - const NGPhysicalBoxFragment* parent_fragment_ = nullptr; - const NGBlockBreakToken* parent_break_token_ = nullptr; - Current current_; - base::span<const NGBreakToken* const> child_break_tokens_; - wtf_size_t child_fragment_idx_ = 0; - wtf_size_t child_break_token_idx_ = 0; - bool is_fragmentation_context_root_ = false; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_NG_FRAGMENT_CHILD_ITERATOR_H_
diff --git a/third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator_test.cc b/third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator_test.cc deleted file mode 100644 index 68de9194..0000000 --- a/third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator_test.cc +++ /dev/null
@@ -1,806 +0,0 @@ -// 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 "third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator.h" -#include "third_party/blink/renderer/core/layout/ng/ng_base_layout_algorithm_test.h" -#include "third_party/blink/renderer/core/layout/ng/ng_block_break_token.h" -#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h" - -namespace blink { -namespace { - -class NGFragmentChildIteratorTest - : public NGBaseLayoutAlgorithmTest, - private ScopedLayoutNGBlockFragmentationForTest { - protected: - NGFragmentChildIteratorTest() - : ScopedLayoutNGBlockFragmentationForTest(true) {} - - scoped_refptr<const NGPhysicalBoxFragment> RunBlockLayoutAlgorithm( - Element* element) { - NGBlockNode container(element->GetLayoutBox()); - NGConstraintSpace space = ConstructBlockLayoutTestConstraintSpace( - {WritingMode::kHorizontalTb, TextDirection::kLtr}, - LogicalSize(LayoutUnit(1000), kIndefiniteSize)); - return NGBaseLayoutAlgorithmTest::RunBlockLayoutAlgorithm(container, space); - } -}; - -TEST_F(NGFragmentChildIteratorTest, Basic) { - SetBodyInnerHTML(R"HTML( - <div id="container"> - <div id="child1"> - <div id="grandchild"></div> - </div> - <div id="child2"></div> - </div> - )HTML"); - - const LayoutObject* child1 = GetLayoutObjectByElementId("child1"); - const LayoutObject* child2 = GetLayoutObjectByElementId("child2"); - const LayoutObject* grandchild = GetLayoutObjectByElementId("grandchild"); - - scoped_refptr<const NGPhysicalBoxFragment> container = - RunBlockLayoutAlgorithm(GetElementById("container")); - NGFragmentChildIterator iterator1(*container.get()); - EXPECT_FALSE(iterator1.IsAtEnd()); - - const NGPhysicalBoxFragment* fragment = iterator1->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_EQ(fragment->GetLayoutObject(), child1); - EXPECT_FALSE(iterator1.IsAtEnd()); - - NGFragmentChildIterator iterator2 = iterator1.Descend(); - EXPECT_FALSE(iterator2.IsAtEnd()); - fragment = iterator2->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_EQ(fragment->GetLayoutObject(), grandchild); - EXPECT_FALSE(iterator2.IsAtEnd()); - EXPECT_FALSE(iterator2.Advance()); - EXPECT_TRUE(iterator2.IsAtEnd()); - - EXPECT_TRUE(iterator1.Advance()); - fragment = iterator1->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_EQ(fragment->GetLayoutObject(), child2); - EXPECT_FALSE(iterator1.IsAtEnd()); - - // #child2 has no children. - EXPECT_TRUE(iterator1.Descend().IsAtEnd()); - - // No more children left. - EXPECT_FALSE(iterator1.Advance()); - EXPECT_TRUE(iterator1.IsAtEnd()); -} - -TEST_F(NGFragmentChildIteratorTest, BasicInline) { - SetBodyInnerHTML(R"HTML( - <div id="container"> - xxx - <span id="span1" style="border:solid;"> - <div id="float1" style="float:left;"></div> - xxx - </span> - xxx - </div> - )HTML"); - - const LayoutObject* span1 = GetLayoutObjectByElementId("span1"); - const LayoutObject* float1 = GetLayoutObjectByElementId("float1"); - - scoped_refptr<const NGPhysicalBoxFragment> container = - RunBlockLayoutAlgorithm(GetElementById("container")); - NGFragmentChildIterator iterator1(*container.get()); - - EXPECT_FALSE(iterator1->BoxFragment()); - const NGFragmentItem* fragment_item = iterator1->FragmentItem(); - ASSERT_TRUE(fragment_item); - EXPECT_EQ(fragment_item->Type(), NGFragmentItem::kLine); - - // Descend into the line box. - NGFragmentChildIterator iterator2 = iterator1.Descend(); - fragment_item = iterator2->FragmentItem(); - ASSERT_TRUE(fragment_item); - EXPECT_TRUE(fragment_item->IsText()); - - EXPECT_TRUE(iterator2.Advance()); - const NGPhysicalBoxFragment* fragment = iterator2->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_EQ(fragment->GetLayoutObject(), span1); - - // Descend into children of #span1. - NGFragmentChildIterator iterator3 = iterator2.Descend(); - fragment = iterator3->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_EQ(fragment->GetLayoutObject(), float1); - - EXPECT_TRUE(iterator3.Advance()); - fragment_item = iterator3->FragmentItem(); - ASSERT_TRUE(fragment_item); - EXPECT_TRUE(fragment_item->IsText()); - EXPECT_FALSE(iterator3.Advance()); - - // Continue with siblings of #span1. - EXPECT_TRUE(iterator2.Advance()); - fragment_item = iterator2->FragmentItem(); - ASSERT_TRUE(fragment_item); - EXPECT_TRUE(fragment_item->IsText()); - - EXPECT_FALSE(iterator2.Advance()); - EXPECT_FALSE(iterator1.Advance()); -} - -TEST_F(NGFragmentChildIteratorTest, InlineBlock) { - SetBodyInnerHTML(R"HTML( - <div id="container"> - xxx - <span id="inlineblock"> - <div id="float1" style="float:left;"></div> - </span> - xxx - </div> - )HTML"); - - const LayoutObject* inlineblock = GetLayoutObjectByElementId("inlineblock"); - const LayoutObject* float1 = GetLayoutObjectByElementId("float1"); - - scoped_refptr<const NGPhysicalBoxFragment> container = - RunBlockLayoutAlgorithm(GetElementById("container")); - NGFragmentChildIterator iterator1(*container.get()); - - EXPECT_FALSE(iterator1->BoxFragment()); - const NGFragmentItem* fragment_item = iterator1->FragmentItem(); - ASSERT_TRUE(fragment_item); - EXPECT_EQ(fragment_item->Type(), NGFragmentItem::kLine); - - // Descend into the line box. - NGFragmentChildIterator iterator2 = iterator1.Descend(); - fragment_item = iterator2->FragmentItem(); - ASSERT_TRUE(fragment_item); - EXPECT_TRUE(fragment_item->IsText()); - - EXPECT_TRUE(iterator2.Advance()); - const NGPhysicalBoxFragment* fragment = iterator2->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_EQ(fragment->GetLayoutObject(), inlineblock); - - // Descend into children of #inlineblock. - NGFragmentChildIterator iterator3 = iterator2.Descend(); - fragment = iterator3->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_EQ(fragment->GetLayoutObject(), float1); - EXPECT_FALSE(iterator3.Advance()); - - // Continue with siblings of #inlineblock. - EXPECT_TRUE(iterator2.Advance()); - fragment_item = iterator2->FragmentItem(); - ASSERT_TRUE(fragment_item); - EXPECT_TRUE(fragment_item->IsText()); - - EXPECT_FALSE(iterator2.Advance()); - EXPECT_FALSE(iterator1.Advance()); -} - -TEST_F(NGFragmentChildIteratorTest, FloatsInInline) { - SetBodyInnerHTML(R"HTML( - <div id="container"> - <span id="span1" style="border:solid;"> - <div id="float1" style="float:left;"> - <div id="child"></div> - </div> - </span> - </div> - )HTML"); - - const LayoutObject* span1 = GetLayoutObjectByElementId("span1"); - const LayoutObject* float1 = GetLayoutObjectByElementId("float1"); - const LayoutObject* child = GetLayoutObjectByElementId("child"); - - scoped_refptr<const NGPhysicalBoxFragment> container = - RunBlockLayoutAlgorithm(GetElementById("container")); - NGFragmentChildIterator iterator1(*container.get()); - - const NGPhysicalBoxFragment* fragment = iterator1->BoxFragment(); - EXPECT_FALSE(fragment); - const NGFragmentItem* item = iterator1->FragmentItem(); - ASSERT_TRUE(item); - EXPECT_EQ(item->Type(), NGFragmentItem::kLine); - - // Descend into the line box. - NGFragmentChildIterator iterator2 = iterator1.Descend(); - fragment = iterator2->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_EQ(fragment->GetLayoutObject(), span1); - - // Descend into children of #span1. - NGFragmentChildIterator iterator3 = iterator2.Descend(); - fragment = iterator3->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_EQ(fragment->GetLayoutObject(), float1); - - // Descend into children of #float1. - NGFragmentChildIterator iterator4 = iterator3.Descend(); - fragment = iterator4->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_EQ(fragment->GetLayoutObject(), child); - - EXPECT_FALSE(iterator4.Advance()); - EXPECT_FALSE(iterator3.Advance()); - EXPECT_FALSE(iterator2.Advance()); - EXPECT_FALSE(iterator1.Advance()); -} - -TEST_F(NGFragmentChildIteratorTest, AbsposAndLine) { - SetBodyInnerHTML(R"HTML( - <div id="container" style="position:relative;"> - <div id="abspos" style="position:absolute;"></div> - xxx - </div> - )HTML"); - - const LayoutObject* abspos = GetLayoutObjectByElementId("abspos"); - - scoped_refptr<const NGPhysicalBoxFragment> container = - RunBlockLayoutAlgorithm(GetElementById("container")); - NGFragmentChildIterator iterator1(*container.get()); - - const NGPhysicalBoxFragment* fragment = iterator1->BoxFragment(); - EXPECT_FALSE(fragment); - const NGFragmentItem* item = iterator1->FragmentItem(); - ASSERT_TRUE(item); - EXPECT_EQ(item->Type(), NGFragmentItem::kLine); - - // Descend into the line box. - NGFragmentChildIterator iterator2 = iterator1.Descend(); - - fragment = iterator2->BoxFragment(); - EXPECT_FALSE(fragment); - item = iterator2->FragmentItem(); - ASSERT_TRUE(item); - EXPECT_TRUE(item->IsText()); - EXPECT_FALSE(iterator2.Advance()); - - // The abspos is a sibling of the line box. - EXPECT_TRUE(iterator1.Advance()); - fragment = iterator1->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_EQ(fragment->GetLayoutObject(), abspos); - EXPECT_FALSE(iterator1.Advance()); -} - -TEST_F(NGFragmentChildIteratorTest, BasicMulticol) { - SetBodyInnerHTML(R"HTML( - <div id="container"> - <div id="mc" style="columns:3; padding:2px; column-fill:auto; column-gap:10px; width:320px; height:100px;"> - <div id="child" style="margin-top:30px; margin-left:4px; height:200px;"></div> - </div> - </div> - )HTML"); - - const LayoutObject* mc = GetLayoutObjectByElementId("mc"); - const LayoutObject* child = GetLayoutObjectByElementId("child"); - - scoped_refptr<const NGPhysicalBoxFragment> container = - RunBlockLayoutAlgorithm(GetElementById("container")); - NGFragmentChildIterator iterator(*container.get()); - - const NGPhysicalBoxFragment* fragment = iterator->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_EQ(fragment->GetLayoutObject(), mc); - - // First column. - NGFragmentChildIterator child_iterator = iterator.Descend(); - fragment = child_iterator->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_TRUE(fragment->IsColumnBox()); - EXPECT_EQ(child_iterator->Link().offset.top, LayoutUnit(2)); - EXPECT_EQ(child_iterator->Link().offset.left, LayoutUnit(2)); - EXPECT_EQ(fragment->Size().height, LayoutUnit(100)); - EXPECT_FALSE(fragment->GetLayoutObject()); - EXPECT_FALSE(child_iterator->BlockBreakToken()); - - NGFragmentChildIterator grandchild_iterator = child_iterator.Descend(); - fragment = grandchild_iterator->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_EQ(grandchild_iterator->Link().offset.top, LayoutUnit(30)); - EXPECT_EQ(grandchild_iterator->Link().offset.left, LayoutUnit(4)); - EXPECT_EQ(fragment->Size().height, LayoutUnit(70)); - EXPECT_EQ(fragment->GetLayoutObject(), child); - EXPECT_FALSE(grandchild_iterator.Advance()); - EXPECT_FALSE(grandchild_iterator->BlockBreakToken()); - - // Second column. - ASSERT_TRUE(child_iterator.Advance()); - fragment = child_iterator->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_TRUE(fragment->IsColumnBox()); - EXPECT_EQ(child_iterator->Link().offset.top, LayoutUnit(2)); - EXPECT_EQ(child_iterator->Link().offset.left, LayoutUnit(112)); - EXPECT_EQ(fragment->Size().height, LayoutUnit(100)); - EXPECT_FALSE(fragment->GetLayoutObject()); - const auto* break_token = child_iterator->BlockBreakToken(); - ASSERT_TRUE(break_token); - EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(100)); - EXPECT_EQ(break_token->InputNode().GetLayoutBox(), mc); - - grandchild_iterator = child_iterator.Descend(); - fragment = grandchild_iterator->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_EQ(grandchild_iterator->Link().offset.top, LayoutUnit(0)); - EXPECT_EQ(grandchild_iterator->Link().offset.left, LayoutUnit(4)); - EXPECT_EQ(fragment->Size().height, LayoutUnit(100)); - EXPECT_EQ(fragment->GetLayoutObject(), child); - EXPECT_FALSE(grandchild_iterator.Advance()); - break_token = grandchild_iterator->BlockBreakToken(); - ASSERT_TRUE(break_token); - EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(70)); - EXPECT_EQ(break_token->InputNode().GetLayoutBox(), child); - - // Third column. - ASSERT_TRUE(child_iterator.Advance()); - fragment = child_iterator->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_TRUE(fragment->IsColumnBox()); - EXPECT_EQ(child_iterator->Link().offset.top, LayoutUnit(2)); - EXPECT_EQ(child_iterator->Link().offset.left, LayoutUnit(222)); - EXPECT_EQ(fragment->Size().height, LayoutUnit(100)); - EXPECT_FALSE(fragment->GetLayoutObject()); - break_token = child_iterator->BlockBreakToken(); - ASSERT_TRUE(break_token); - EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(200)); - EXPECT_EQ(break_token->InputNode().GetLayoutBox(), mc); - - grandchild_iterator = child_iterator.Descend(); - fragment = grandchild_iterator->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_EQ(grandchild_iterator->Link().offset.top, LayoutUnit(0)); - EXPECT_EQ(grandchild_iterator->Link().offset.left, LayoutUnit(4)); - EXPECT_EQ(fragment->Size().height, LayoutUnit(30)); - EXPECT_EQ(fragment->GetLayoutObject(), child); - EXPECT_FALSE(grandchild_iterator.Advance()); - break_token = grandchild_iterator->BlockBreakToken(); - ASSERT_TRUE(break_token); - EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(170)); - EXPECT_EQ(break_token->InputNode().GetLayoutBox(), child); - - EXPECT_FALSE(child_iterator.Advance()); - EXPECT_FALSE(iterator.Advance()); -} - -TEST_F(NGFragmentChildIteratorTest, ColumnSpanner) { - SetBodyInnerHTML(R"HTML( - <div id="container"> - <div id="mc" style="columns:2;"> - <div id="child"> - <div id="grandchild1" style="height:150px;"></div> - <div id="spanner" style="column-span:all; height:11px;"></div> - <div id="grandchild2" style="height:66px;"></div> - </div> - </div> - </div> - )HTML"); - - scoped_refptr<const NGPhysicalBoxFragment> container = - RunBlockLayoutAlgorithm(GetElementById("container")); - NGFragmentChildIterator iterator1(*container.get()); - - const LayoutObject* mc = GetLayoutObjectByElementId("mc"); - const LayoutObject* child = GetLayoutObjectByElementId("child"); - const LayoutObject* spanner = GetLayoutObjectByElementId("spanner"); - const LayoutObject* grandchild1 = GetLayoutObjectByElementId("grandchild1"); - const LayoutObject* grandchild2 = GetLayoutObjectByElementId("grandchild2"); - - const NGPhysicalBoxFragment* fragment = iterator1->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_EQ(fragment->GetLayoutObject(), mc); - - // First column before spanner. - NGFragmentChildIterator iterator2 = iterator1.Descend(); - fragment = iterator2->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_TRUE(fragment->IsColumnBox()); - EXPECT_EQ(fragment->Size().height, LayoutUnit(75)); - EXPECT_FALSE(fragment->GetLayoutObject()); - EXPECT_FALSE(iterator2->BlockBreakToken()); - - // First fragment for #child. - NGFragmentChildIterator iterator3 = iterator2.Descend(); - fragment = iterator3->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_EQ(fragment->Size().height, LayoutUnit(75)); - EXPECT_EQ(fragment->GetLayoutObject(), child); - EXPECT_FALSE(iterator3->BlockBreakToken()); - - // First fragment for #grandchild1. - NGFragmentChildIterator iterator4 = iterator3.Descend(); - fragment = iterator4->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_EQ(fragment->Size().height, LayoutUnit(75)); - EXPECT_EQ(fragment->GetLayoutObject(), grandchild1); - EXPECT_FALSE(iterator4->BlockBreakToken()); - EXPECT_FALSE(iterator4.Advance()); - EXPECT_FALSE(iterator3.Advance()); - - // Second column before spanner. - EXPECT_TRUE(iterator2.Advance()); - fragment = iterator2->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_TRUE(fragment->IsColumnBox()); - EXPECT_EQ(fragment->Size().height, LayoutUnit(75)); - EXPECT_FALSE(fragment->GetLayoutObject()); - const auto* break_token = iterator2->BlockBreakToken(); - ASSERT_TRUE(break_token); - EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(75)); - EXPECT_EQ(break_token->InputNode().GetLayoutBox(), mc); - - // Second fragment for #child. - iterator3 = iterator2.Descend(); - fragment = iterator3->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_EQ(fragment->Size().height, LayoutUnit(75)); - EXPECT_EQ(fragment->GetLayoutObject(), child); - break_token = iterator3->BlockBreakToken(); - ASSERT_TRUE(break_token); - EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(75)); - EXPECT_EQ(break_token->InputNode().GetLayoutBox(), child); - - // Second fragment for #grandchild1. - iterator4 = iterator3.Descend(); - fragment = iterator4->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_EQ(fragment->Size().height, LayoutUnit(75)); - EXPECT_EQ(fragment->GetLayoutObject(), grandchild1); - break_token = iterator4->BlockBreakToken(); - ASSERT_TRUE(break_token); - EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(75)); - EXPECT_EQ(break_token->InputNode().GetLayoutBox(), grandchild1); - EXPECT_FALSE(iterator4.Advance()); - EXPECT_FALSE(iterator3.Advance()); - - // The spanner. - EXPECT_TRUE(iterator2.Advance()); - fragment = iterator2->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_EQ(fragment->Size().height, LayoutUnit(11)); - EXPECT_EQ(fragment->GetLayoutObject(), spanner); - EXPECT_FALSE(iterator2->BlockBreakToken()); - - // First column after spanner. - EXPECT_TRUE(iterator2.Advance()); - fragment = iterator2->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_TRUE(fragment->IsColumnBox()); - EXPECT_EQ(fragment->Size().height, LayoutUnit(33)); - EXPECT_FALSE(fragment->GetLayoutObject()); - break_token = iterator2->BlockBreakToken(); - ASSERT_TRUE(break_token); - EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(150)); - EXPECT_EQ(break_token->InputNode().GetLayoutBox(), mc); - - // Third fragment for #child. - iterator3 = iterator2.Descend(); - fragment = iterator3->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_EQ(fragment->Size().height, LayoutUnit(33)); - EXPECT_EQ(fragment->GetLayoutObject(), child); - break_token = iterator3->BlockBreakToken(); - ASSERT_TRUE(break_token); - EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(150)); - EXPECT_EQ(break_token->InputNode().GetLayoutBox(), child); - - // First fragment for #grandchild2. - iterator4 = iterator3.Descend(); - fragment = iterator4->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_EQ(fragment->Size().height, LayoutUnit(33)); - EXPECT_EQ(fragment->GetLayoutObject(), grandchild2); - break_token = iterator4->BlockBreakToken(); - ASSERT_TRUE(break_token); - EXPECT_TRUE(break_token->IsBreakBefore()); - EXPECT_EQ(break_token->InputNode().GetLayoutBox(), grandchild2); - EXPECT_FALSE(iterator4.Advance()); - EXPECT_FALSE(iterator3.Advance()); - - // Second column after spanner. - EXPECT_TRUE(iterator2.Advance()); - fragment = iterator2->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_TRUE(fragment->IsColumnBox()); - EXPECT_EQ(fragment->Size().height, LayoutUnit(33)); - EXPECT_FALSE(fragment->GetLayoutObject()); - break_token = iterator2->BlockBreakToken(); - ASSERT_TRUE(break_token); - EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(183)); - EXPECT_EQ(break_token->InputNode().GetLayoutBox(), mc); - - // Fourth fragment for #child. - iterator3 = iterator2.Descend(); - fragment = iterator3->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_EQ(fragment->Size().height, LayoutUnit(33)); - EXPECT_EQ(fragment->GetLayoutObject(), child); - break_token = iterator3->BlockBreakToken(); - ASSERT_TRUE(break_token); - EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(183)); - EXPECT_EQ(break_token->InputNode().GetLayoutBox(), child); - - // Second fragment for #grandchild2. - iterator4 = iterator3.Descend(); - fragment = iterator4->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_EQ(fragment->Size().height, LayoutUnit(33)); - EXPECT_EQ(fragment->GetLayoutObject(), grandchild2); - break_token = iterator4->BlockBreakToken(); - ASSERT_TRUE(break_token); - EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(33)); - EXPECT_EQ(break_token->InputNode().GetLayoutBox(), grandchild2); - EXPECT_FALSE(iterator4.Advance()); - EXPECT_FALSE(iterator3.Advance()); - - EXPECT_FALSE(iterator2.Advance()); - EXPECT_FALSE(iterator1.Advance()); -} - -TEST_F(NGFragmentChildIteratorTest, NestedWithColumnSpanner) { - SetBodyInnerHTML(R"HTML( - <div id="container"> - <div id="mc1" style="columns:2; column-fill:auto; height:100px;"> - <div id="mc2" style="columns:2;"> - <div id="child1" style="height:150px;"></div> - <div id="spanner1" style="column-span:all;"> - <div id="spanner1child" style="height:55px;"></div> - </div> - <div id="child2" style="height:50px;"></div> - <div id="spanner2" style="column-span:all;"> - <div id="spanner2child" style="height:20px;"></div> - </div> - <div id="child3" style="height:20px;"></div> - </div> - </div> - </div> - )HTML"); - - scoped_refptr<const NGPhysicalBoxFragment> container = - RunBlockLayoutAlgorithm(GetElementById("container")); - NGFragmentChildIterator iterator1(*container.get()); - - const LayoutObject* mc1 = GetLayoutObjectByElementId("mc1"); - const LayoutObject* mc2 = GetLayoutObjectByElementId("mc2"); - const LayoutObject* child1 = GetLayoutObjectByElementId("child1"); - const LayoutObject* child2 = GetLayoutObjectByElementId("child2"); - const LayoutObject* child3 = GetLayoutObjectByElementId("child3"); - const LayoutObject* spanner1 = GetLayoutObjectByElementId("spanner1"); - const LayoutObject* spanner2 = GetLayoutObjectByElementId("spanner2"); - const LayoutObject* spanner1child = - GetLayoutObjectByElementId("spanner1child"); - const LayoutObject* spanner2child = - GetLayoutObjectByElementId("spanner2child"); - - const NGPhysicalBoxFragment* fragment = iterator1->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_EQ(fragment->GetLayoutObject(), mc1); - - // First outer column. - NGFragmentChildIterator iterator2 = iterator1.Descend(); - fragment = iterator2->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_TRUE(fragment->IsColumnBox()); - EXPECT_FALSE(fragment->GetLayoutObject()); - EXPECT_FALSE(iterator2->BlockBreakToken()); - - // First fragment for #mc2. - NGFragmentChildIterator iterator3 = iterator2.Descend(); - fragment = iterator3->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_EQ(fragment->GetLayoutObject(), mc2); - EXPECT_FALSE(iterator3->BlockBreakToken()); - - // First inner column in first outer column. - NGFragmentChildIterator iterator4 = iterator3.Descend(); - fragment = iterator4->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_TRUE(fragment->IsColumnBox()); - EXPECT_FALSE(fragment->GetLayoutObject()); - EXPECT_FALSE(iterator4->BlockBreakToken()); - - // First fragment for #child1. - NGFragmentChildIterator iterator5 = iterator4.Descend(); - fragment = iterator5->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_EQ(fragment->GetLayoutObject(), child1); - EXPECT_FALSE(iterator5->BlockBreakToken()); - EXPECT_FALSE(iterator5.Advance()); - - // Second inner column in first outer column. - EXPECT_TRUE(iterator4.Advance()); - fragment = iterator4->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_TRUE(fragment->IsColumnBox()); - EXPECT_FALSE(fragment->GetLayoutObject()); - const auto* break_token = iterator4->BlockBreakToken(); - ASSERT_TRUE(break_token); - EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(75)); - EXPECT_EQ(break_token->InputNode().GetLayoutBox(), mc2); - - // Second fragment for #child1. - iterator5 = iterator4.Descend(); - fragment = iterator5->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_EQ(fragment->GetLayoutObject(), child1); - break_token = iterator5->BlockBreakToken(); - ASSERT_TRUE(break_token); - EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(75)); - EXPECT_EQ(break_token->InputNode().GetLayoutBox(), child1); - - // First fragment for #spanner1 (it's split into the first and second outer - // columns). - EXPECT_TRUE(iterator4.Advance()); - fragment = iterator4->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_EQ(fragment->GetLayoutObject(), spanner1); - EXPECT_FALSE(iterator4->BlockBreakToken()); - - // First fragment for #spanner1child - iterator5 = iterator4.Descend(); - fragment = iterator5->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_EQ(fragment->GetLayoutObject(), spanner1child); - EXPECT_FALSE(iterator5->BlockBreakToken()); - EXPECT_FALSE(iterator5.Advance()); - EXPECT_FALSE(iterator4.Advance()); - EXPECT_FALSE(iterator3.Advance()); - - // Second outer column - EXPECT_TRUE(iterator2.Advance()); - fragment = iterator2->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_TRUE(fragment->IsColumnBox()); - EXPECT_FALSE(fragment->GetLayoutObject()); - break_token = iterator2->BlockBreakToken(); - ASSERT_TRUE(break_token); - EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(100)); - EXPECT_EQ(break_token->InputNode().GetLayoutBox(), mc1); - - // Second fragment for #mc2. - iterator3 = iterator2.Descend(); - fragment = iterator3->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_EQ(fragment->GetLayoutObject(), mc2); - break_token = iterator3->BlockBreakToken(); - ASSERT_TRUE(break_token); - EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(100)); - EXPECT_EQ(break_token->InputNode().GetLayoutBox(), mc2); - - // Second fragment for #spanner1 (it's split into the first and second outer - // columns). - iterator4 = iterator3.Descend(); - fragment = iterator4->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_EQ(fragment->GetLayoutObject(), spanner1); - break_token = iterator4->BlockBreakToken(); - ASSERT_TRUE(break_token); - EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(25)); - EXPECT_EQ(break_token->InputNode().GetLayoutBox(), spanner1); - - // Second fragment for #spanner1child. - iterator5 = iterator4.Descend(); - fragment = iterator5->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_EQ(fragment->GetLayoutObject(), spanner1child); - break_token = iterator5->BlockBreakToken(); - ASSERT_TRUE(break_token); - EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(25)); - EXPECT_EQ(break_token->InputNode().GetLayoutBox(), spanner1child); - EXPECT_FALSE(iterator5.Advance()); - - // First inner column after first spanner in second outer column. - EXPECT_TRUE(iterator4.Advance()); - fragment = iterator4->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_TRUE(fragment->IsColumnBox()); - EXPECT_FALSE(fragment->GetLayoutObject()); - break_token = iterator4->BlockBreakToken(); - ASSERT_TRUE(break_token); - EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(150)); - EXPECT_EQ(break_token->InputNode().GetLayoutBox(), mc2); - - // First fragment for #child2. - iterator5 = iterator4.Descend(); - fragment = iterator5->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_EQ(fragment->GetLayoutObject(), child2); - break_token = iterator5->BlockBreakToken(); - EXPECT_TRUE(break_token); - EXPECT_TRUE(break_token->IsBreakBefore()); - EXPECT_EQ(break_token->InputNode().GetLayoutBox(), child2); - EXPECT_FALSE(iterator5.Advance()); - - // Second inner column after first spanner in second outer column. - EXPECT_TRUE(iterator4.Advance()); - fragment = iterator4->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_TRUE(fragment->IsColumnBox()); - EXPECT_FALSE(fragment->GetLayoutObject()); - break_token = iterator4->BlockBreakToken(); - ASSERT_TRUE(break_token); - EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(175)); - EXPECT_EQ(break_token->InputNode().GetLayoutBox(), mc2); - - // Second fragment for #child2. - iterator5 = iterator4.Descend(); - fragment = iterator5->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_EQ(fragment->GetLayoutObject(), child2); - break_token = iterator5->BlockBreakToken(); - ASSERT_TRUE(break_token); - EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(25)); - EXPECT_EQ(break_token->InputNode().GetLayoutBox(), child2); - EXPECT_FALSE(iterator5.Advance()); - - // The only fragment for #spanner2 - EXPECT_TRUE(iterator4.Advance()); - fragment = iterator4->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_EQ(fragment->GetLayoutObject(), spanner2); - EXPECT_FALSE(iterator4->BlockBreakToken()); - - // First fragment for #spanner2child - iterator5 = iterator4.Descend(); - fragment = iterator5->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_EQ(fragment->GetLayoutObject(), spanner2child); - EXPECT_FALSE(iterator5->BlockBreakToken()); - EXPECT_FALSE(iterator5.Advance()); - - // First inner column after second spanner in second outer column. - EXPECT_TRUE(iterator4.Advance()); - fragment = iterator4->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_TRUE(fragment->IsColumnBox()); - EXPECT_FALSE(fragment->GetLayoutObject()); - break_token = iterator4->BlockBreakToken(); - ASSERT_TRUE(break_token); - EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(200)); - EXPECT_EQ(break_token->InputNode().GetLayoutBox(), mc2); - - // First fragment for #child3. - iterator5 = iterator4.Descend(); - fragment = iterator5->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_EQ(fragment->GetLayoutObject(), child3); - break_token = iterator5->BlockBreakToken(); - EXPECT_TRUE(break_token); - EXPECT_TRUE(break_token->IsBreakBefore()); - EXPECT_EQ(break_token->InputNode().GetLayoutBox(), child3); - EXPECT_FALSE(iterator5.Advance()); - - // Second inner column after second spanner in second outer column. - EXPECT_TRUE(iterator4.Advance()); - fragment = iterator4->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_TRUE(fragment->IsColumnBox()); - EXPECT_FALSE(fragment->GetLayoutObject()); - break_token = iterator4->BlockBreakToken(); - ASSERT_TRUE(break_token); - EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(210)); - EXPECT_EQ(break_token->InputNode().GetLayoutBox(), mc2); - - // Second fragment for #child3. - iterator5 = iterator4.Descend(); - fragment = iterator5->BoxFragment(); - ASSERT_TRUE(fragment); - EXPECT_EQ(fragment->GetLayoutObject(), child3); - break_token = iterator5->BlockBreakToken(); - ASSERT_TRUE(break_token); - EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(10)); - EXPECT_EQ(break_token->InputNode().GetLayoutBox(), child3); - EXPECT_FALSE(iterator5.Advance()); - EXPECT_FALSE(iterator4.Advance()); - EXPECT_FALSE(iterator3.Advance()); - EXPECT_FALSE(iterator2.Advance()); - EXPECT_FALSE(iterator1.Advance()); -} - -} // anonymous namespace -} // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.cc b/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.cc index 5aea7279..1c85994 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.cc
@@ -4,6 +4,7 @@ #include "third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.h" +#include "base/containers/adapters.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/layout/ng/ng_block_break_token.h" #include "third_party/blink/renderer/core/layout/ng/ng_box_fragment.h" @@ -862,4 +863,73 @@ return previous_break_token; } +const NGBlockBreakToken* FindPreviousBreakToken( + const NGPhysicalBoxFragment& fragment) { + const LayoutBox* box = To<LayoutBox>(fragment.GetLayoutObject()); + DCHECK(box); + DCHECK_GE(box->PhysicalFragmentCount(), 1u); + + // Bail early if this is the first fragment. There'll be no previous break + // token then. + if (fragment.IsFirstForNode()) + return nullptr; + + // If this isn't the first fragment, it means that there has to be multiple + // fragments. + DCHECK_GT(box->PhysicalFragmentCount(), 1u); + + const NGPhysicalBoxFragment* previous_fragment; + if (const auto* break_token = To<NGBlockBreakToken>(fragment.BreakToken())) { + // The sequence number of the outgoing break token is the same as the index + // of this fragment. + DCHECK_GE(break_token->SequenceNumber(), 1u); + previous_fragment = + box->GetPhysicalFragment(break_token->SequenceNumber() - 1); + } else { + // This is the last fragment, so its incoming break token will be the + // outgoing one from the penultimate fragment. + previous_fragment = + box->GetPhysicalFragment(box->PhysicalFragmentCount() - 2); + } + return To<NGBlockBreakToken>(previous_fragment->BreakToken()); +} + +wtf_size_t PreviousInnerFragmentainerIndex( + const NGPhysicalBoxFragment& fragment) { + // This should be a fragmentation context root, typically a multicol + // container. + DCHECK(fragment.IsFragmentationContextRoot()); + + const LayoutBox* box = To<LayoutBox>(fragment.GetLayoutObject()); + DCHECK_GE(box->PhysicalFragmentCount(), 1u); + if (box->PhysicalFragmentCount() == 1) + return 0; + + wtf_size_t idx = 0; + // Walk the list of fragments generated by the node, until we reach the + // specified one. Note that some fragments may not contain any fragmentainers + // at all, if all the space is taken up by column spanners, for instance. + for (const NGPhysicalBoxFragment& walker : box->PhysicalFragments()) { + if (&walker == &fragment) + return idx; + const auto* break_token = To<NGBlockBreakToken>(walker.BreakToken()); + + // Find the last fragmentainer inside this fragment. + const auto children = break_token->ChildBreakTokens(); + for (scoped_refptr<const NGBreakToken> child_token : + base::Reversed(children)) { + DCHECK(child_token->IsBlockType()); + if (child_token->InputNode() != break_token->InputNode()) { + // Not a fragmentainer (probably a spanner) + continue; + } + idx = To<NGBlockBreakToken>(child_token.get())->SequenceNumber() + 1; + break; + } + } + + NOTREACHED(); + return idx; +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.h b/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.h index 2b7f1f3..5dabb13 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.h +++ b/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.h
@@ -351,6 +351,19 @@ const NGBoxFragmentBuilder& container_builder, wtf_size_t index); +// Return the break token that led to the creation of the fragment specified, or +// nullptr if this is the first fragment. Note that this operation is O(n) +// (number of fragments generated from the node), and should be avoided when +// possible. This function should no longer be necessary once everything has +// been properly converted to LayoutNG, and we have also gotten rid of the +// fragment stitching of composited objects (will be fixed by +// CompositeAfterPaint). +const NGBlockBreakToken* FindPreviousBreakToken(const NGPhysicalBoxFragment&); + +// Return the index of the fragmentainer preceding the first fragmentainer +// inside this fragment. Used by nested block fragmentation. +wtf_size_t PreviousInnerFragmentainerIndex(const NGPhysicalBoxFragment&); + } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_NG_FRAGMENTATION_UTILS_H_
diff --git a/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.cc b/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.cc index 21333b4a..20e15e4 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.cc
@@ -459,7 +459,6 @@ } const FragmentData* NGPhysicalFragment::GetFragmentData() const { - DCHECK(CanTraverse()); const LayoutBox* box = DynamicTo<LayoutBox>(GetLayoutObject()); if (!box) { DCHECK(!GetLayoutObject());
diff --git a/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h b/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h index 0cdd681..851f3c40 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h +++ b/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h
@@ -133,6 +133,9 @@ bool IsOutOfFlowPositioned() const { return IsBox() && BoxType() == NGBoxType::kOutOfFlowPositioned; } + bool IsFixedPositioned() const { + return IsCSSBox() && layout_object_->IsFixedPositioned(); + } bool IsFloatingOrOutOfFlowPositioned() const { return IsFloating() || IsOutOfFlowPositioned(); }
diff --git a/third_party/blink/renderer/core/page/context_menu_controller.cc b/third_party/blink/renderer/core/page/context_menu_controller.cc index a8ade0d8..3d6ffff 100644 --- a/third_party/blink/renderer/core/page/context_menu_controller.cc +++ b/third_party/blink/renderer/core/page/context_menu_controller.cc
@@ -642,12 +642,6 @@ << "]\nVisibleSelection: " << selected_frame->Selection() .ComputeVisibleSelectionInDOMTreeDeprecated(); - if (!result.IsContentEditable()) { - // Store text selection when it happens as it might be cleared when the - // browser will request |TextFragmentHandler| to generate - // selector. - UpdateTextFragmentHandler(selected_frame); - } } // If there is a text fragment at the same location as the click indicate that @@ -784,16 +778,4 @@ return true; } -void ContextMenuController::UpdateTextFragmentHandler( - LocalFrame* selected_frame) { - if (!selected_frame->GetTextFragmentHandler()) - return; - - VisibleSelectionInFlatTree selection = - selected_frame->Selection().ComputeVisibleSelectionInFlatTree(); - EphemeralRangeInFlatTree selection_range(selection.Start(), selection.End()); - selected_frame->GetTextFragmentHandler()->MainFrameDidUpdateSelection( - selection_range); -} - } // namespace blink
diff --git a/third_party/blink/renderer/core/page/context_menu_controller.h b/third_party/blink/renderer/core/page/context_menu_controller.h index 008ded23..63a00e8 100644 --- a/third_party/blink/renderer/core/page/context_menu_controller.h +++ b/third_party/blink/renderer/core/page/context_menu_controller.h
@@ -129,8 +129,6 @@ Node* GetContextMenuNodeWithImageContents(); - void UpdateTextFragmentHandler(LocalFrame*); - HeapMojoAssociatedReceiver<mojom::blink::ContextMenuClient, ContextMenuController> context_menu_client_receiver_{this, nullptr};
diff --git a/third_party/blink/renderer/core/page/scrolling/text_fragment_handler.cc b/third_party/blink/renderer/core/page/scrolling/text_fragment_handler.cc index aceb9cf..a5e18427 100644 --- a/third_party/blink/renderer/core/page/scrolling/text_fragment_handler.cc +++ b/third_party/blink/renderer/core/page/scrolling/text_fragment_handler.cc
@@ -13,6 +13,7 @@ #include "third_party/blink/renderer/core/editing/markers/document_marker_controller.h" #include "third_party/blink/renderer/core/editing/position_with_affinity.h" #include "third_party/blink/renderer/core/editing/range_in_flat_tree.h" +#include "third_party/blink/renderer/core/editing/selection_editor.h" #include "third_party/blink/renderer/core/editing/visible_units.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/page/scrolling/text_fragment_anchor.h" @@ -32,6 +33,7 @@ void TextFragmentHandler::BindTextFragmentReceiver( mojo::PendingReceiver<mojom::blink::TextFragmentReceiver> producer) { + StartPreemptiveGenerationIfNeeded(); selector_producer_.reset(); selector_producer_.Bind( std::move(producer), @@ -46,6 +48,7 @@ void TextFragmentHandler::RequestSelector(RequestSelectorCallback callback) { DCHECK(shared_highlighting::ShouldOfferLinkToText( GetFrame()->GetDocument()->Url())); + DCHECK(!GetFrame()->Selection().SelectedText().IsEmpty()); if (PreemptiveGenerationEnabled()) { GetTextFragmentSelectorGenerator()->RecordSelectorStateUma(); @@ -56,9 +59,9 @@ // If preemptive link generation is enabled, the generator would have // already been invoked when the selection was updated in - // MainFrameDidUpdateSelection. If that generation finished simply respond - // with the result. Otherwise, the response callback is stored so that we - // reply on completion. + // StartPreemptiveGenerationIfNeeded. If that generation finished simply + // respond with the result. Otherwise, the response callback is stored so + // that we reply on completion. if (!selector_requested_before_ready_.value()) InvokeReplyCallback(preemptive_generation_result_.value()); } else { @@ -185,8 +188,17 @@ } void TextFragmentHandler::StartGeneratingForCurrentSelection() { + if (GetFrame()->Selection().SelectedText().IsEmpty()) + return; + + VisibleSelectionInFlatTree selection = + GetFrame()->Selection().ComputeVisibleSelectionInFlatTree(); + EphemeralRangeInFlatTree selection_range(selection.Start(), selection.End()); + RangeInFlatTree* current_selection_range = + MakeGarbageCollected<RangeInFlatTree>(selection_range.StartPosition(), + selection_range.EndPosition()); GetTextFragmentSelectorGenerator()->Generate( - *current_selection_range_, + *current_selection_range, WTF::Bind(&TextFragmentHandler::DidFinishSelectorGeneration, WrapWeakPersistent(this))); } @@ -219,12 +231,7 @@ } } -void TextFragmentHandler::MainFrameDidUpdateSelection( - const EphemeralRangeInFlatTree& selection_range) { - // TODO(bokan): Why can't we query this rather than trying to keep track of - // it? - current_selection_range_ = MakeGarbageCollected<RangeInFlatTree>( - selection_range.StartPosition(), selection_range.EndPosition()); +void TextFragmentHandler::StartPreemptiveGenerationIfNeeded() { if (PreemptiveGenerationEnabled() && shared_highlighting::ShouldOfferLinkToText( GetFrame()->GetDocument()->Url())) { @@ -235,16 +242,10 @@ void TextFragmentHandler::Trace(Visitor* visitor) const { visitor->Trace(text_fragment_selector_generator_); - visitor->Trace(current_selection_range_); visitor->Trace(selector_producer_); } void TextFragmentHandler::DidDetachDocumentOrFrame() { - // A frame (and thus, this object) can survive multiple documents. When a - // document is detached we need to explicitly clear the selection range so - // that we don't keep alive a stale range. - current_selection_range_ = nullptr; - // Clear out any state in the generator and cancel pending tasks so they // don't run after frame detachment. GetTextFragmentSelectorGenerator()->Reset();
diff --git a/third_party/blink/renderer/core/page/scrolling/text_fragment_handler.h b/third_party/blink/renderer/core/page/scrolling/text_fragment_handler.h index 62e9fc80..6a74f84 100644 --- a/third_party/blink/renderer/core/page/scrolling/text_fragment_handler.h +++ b/third_party/blink/renderer/core/page/scrolling/text_fragment_handler.h
@@ -12,14 +12,14 @@ namespace blink { class LocalFrame; -class RangeInFlatTree; class TextFragmentAnchor; // TextFragmentHandler is responsible for handling requests from the // browser-side link-to-text/shared-highlighting feature. It is responsible for // generating a text fragment URL based on the current selection as well as // collecting information about and modifying text fragments on the current -// page. This class is registered on and owned by the main frame of a page. +// page. This class is registered on and owned by the frame that interacts with +// the link-to-text/shared-highlighting feature. class CORE_EXPORT TextFragmentHandler final : public GarbageCollected<TextFragmentHandler>, public blink::mojom::blink::TextFragmentReceiver { @@ -41,9 +41,9 @@ void ExtractFirstFragmentRect( ExtractFirstFragmentRectCallback callback) override; - // Called by Blink when the selection in the main frame changes. - void MainFrameDidUpdateSelection( - const EphemeralRangeInFlatTree& selection_range); + // This starts the preemptive generation on the current selection if it is not + // empty. + void StartPreemptiveGenerationIfNeeded(); void BindTextFragmentReceiver( mojo::PendingReceiver<mojom::blink::TextFragmentReceiver> producer); @@ -61,9 +61,8 @@ // result. void DidFinishSelectorGeneration(const TextFragmentSelector& selector); - // This starts running the generator over the selection in - // |current_selection_range_|. The result will be returned by invoking - // DidFinishSelectorGeneration(). + // This starts running the generator over the current selection. + // The result will be returned by invoking DidFinishSelectorGeneration(). void StartGeneratingForCurrentSelection(); void RecordPreemptiveGenerationMetrics(const TextFragmentSelector& selector); @@ -81,11 +80,6 @@ // selection. Member<TextFragmentSelectorGenerator> text_fragment_selector_generator_; - // The Range of DOM currently selected by the user in the main frame. This - // class may preemptively start generating a selector based on this - // selection. - Member<RangeInFlatTree> current_selection_range_; - // The result of preemptively generating on selection changes will be stored // in this member when completed. Used only in preemptive link generation // mode.
diff --git a/third_party/blink/renderer/core/page/scrolling/text_fragment_handler_test.cc b/third_party/blink/renderer/core/page/scrolling/text_fragment_handler_test.cc index d247421..bb32852 100644 --- a/third_party/blink/renderer/core/page/scrolling/text_fragment_handler_test.cc +++ b/third_party/blink/renderer/core/page/scrolling/text_fragment_handler_test.cc
@@ -17,8 +17,10 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_union_arraybuffer_arraybufferview_string.h" #include "third_party/blink/renderer/core/css/css_font_face.h" #include "third_party/blink/renderer/core/css/font_face_set_document.h" +#include "third_party/blink/renderer/core/editing/frame_selection.h" #include "third_party/blink/renderer/core/editing/markers/document_marker_controller.h" #include "third_party/blink/renderer/core/editing/visible_units.h" +#include "third_party/blink/renderer/core/html/html_frame_owner_element.h" #include "third_party/blink/renderer/core/testing/sim/sim_request.h" #include "third_party/blink/renderer/core/testing/sim/sim_test.h" #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" @@ -50,6 +52,17 @@ feature_list_.InitWithFeatures(enabled, disabled); } + void BeginEmptyFrame() { + // If a test case doesn't find a match and therefore doesn't schedule the + // beforematch event, we should still render a second frame as if we did + // schedule the event to retain test coverage. + // When the beforematch event is not scheduled, a DCHECK will fail on + // BeginFrame() because no event was scheduled, so we schedule an empty task + // here. + GetDocument().EnqueueAnimationFrameTask(WTF::Bind([]() {})); + Compositor().BeginFrame(); + } + void RunAsyncMatchingTasks() { auto* scheduler = ThreadScheduler::Current()->GetWebMainThreadSchedulerForTest(); @@ -58,9 +71,16 @@ RunPendingTasks(); } + void SetSelection(const Position& start, const Position& end) { + GetDocument().GetFrame()->Selection().SetSelection( + SelectionInDOMTree::Builder().SetBaseAndExtent(start, end).Build(), + SetSelectionOptions()); + } + String SelectThenRequestSelector(const Position& start, const Position& end) { - GetTextFragmentHandler().MainFrameDidUpdateSelection( - ToEphemeralRangeInFlatTree(EphemeralRange(start, end))); + SetSelection(start, end); + + GetTextFragmentHandler().StartPreemptiveGenerationIfNeeded(); bool callback_called = false; String selector; @@ -171,6 +191,10 @@ return *GetDocument().GetFrame()->GetTextFragmentHandler(); } + bool HasTextFragmentHandler(LocalFrame* frame) { + return frame->GetTextFragmentHandler(); + } + protected: base::HistogramTester histogram_tester_; base::test::ScopedFeatureList feature_list_; @@ -603,8 +627,9 @@ const auto& selected_end = Position(first_paragraph, 5); ASSERT_EQ("First", PlainText(EphemeralRange(selected_start, selected_end))); - GetTextFragmentHandler().MainFrameDidUpdateSelection( - ToEphemeralRangeInFlatTree(EphemeralRange(selected_start, selected_end))); + SetSelection(selected_start, selected_end); + GetTextFragmentHandler().StartPreemptiveGenerationIfNeeded(); + base::RunLoop().RunUntilIdle(); histogram_tester_.ExpectTotalCount("SharedHighlights.LinkGenerated", 1); @@ -628,8 +653,9 @@ const auto& selected_end = Position(first_paragraph, 5); ASSERT_EQ("First", PlainText(EphemeralRange(selected_start, selected_end))); - GetTextFragmentHandler().MainFrameDidUpdateSelection( - ToEphemeralRangeInFlatTree(EphemeralRange(selected_start, selected_end))); + SetSelection(selected_start, selected_end); + GetTextFragmentHandler().StartPreemptiveGenerationIfNeeded(); + base::RunLoop().RunUntilIdle(); histogram_tester_.ExpectTotalCount("SharedHighlights.LinkGenerated", 0); @@ -656,8 +682,9 @@ ASSERT_EQ("default text", PlainText(EphemeralRange(selected_start, selected_end))); - GetTextFragmentHandler().MainFrameDidUpdateSelection( - ToEphemeralRangeInFlatTree(EphemeralRange(selected_start, selected_end))); + SetSelection(selected_start, selected_end); + GetTextFragmentHandler().StartPreemptiveGenerationIfNeeded(); + base::RunLoop().RunUntilIdle(); histogram_tester_.ExpectTotalCount("SharedHighlights.LinkGenerated", 0); @@ -679,6 +706,7 @@ const auto& start = Position(p->lastChild(), 0); const auto& end = Position(p->lastChild(), 15); ASSERT_EQ("First paragraph", PlainText(EphemeralRange(start, end))); + SetSelection(start, end); auto callback = WTF::Bind([](const TextFragmentSelector& selector) {}); GetDocument() @@ -688,8 +716,7 @@ ->SetCallbackForTesting(std::move(callback)); // This shouldn't crash. - GetTextFragmentHandler().MainFrameDidUpdateSelection( - ToEphemeralRangeInFlatTree(EphemeralRange(start, end))); + GetTextFragmentHandler().StartPreemptiveGenerationIfNeeded(); base::RunLoop().RunUntilIdle(); } @@ -740,6 +767,157 @@ VerifyPreemptiveGenerationMetrics(false); } +TEST_P(TextFragmentHandlerTest, + ShouldCreateTextFragmentHandlerAndRemoveHighlightForIframes) { + base::test::ScopedFeatureList feature_list_; + feature_list_.InitAndEnableFeature( + shared_highlighting::kSharedHighlightingAmp); + SimRequest main_request("https://example.com/test.html", "text/html"); + SimRequest child_request("https://example.com/child.html#:~:text=test", + "text/html"); + LoadURL("https://example.com/test.html"); + main_request.Complete(R"HTML( + <!DOCTYPE html> + <iframe id="iframe" src="child.html#:~:text=test"></iframe> + )HTML"); + + child_request.Complete(R"HTML( + <!DOCTYPE html> + <style> + p { + margin-top: 1000px; + } + </style> + <p> + test + </p> + )HTML"); + RunAsyncMatchingTasks(); + + // Render two frames to handle the async step added by the beforematch event. + Compositor().BeginFrame(); + BeginEmptyFrame(); + + Element* iframe = GetDocument().getElementById("iframe"); + auto* child_frame = + To<LocalFrame>(To<HTMLFrameOwnerElement>(iframe)->ContentFrame()); + + EXPECT_EQ(1u, child_frame->GetDocument()->Markers().Markers().size()); + EXPECT_FALSE(HasTextFragmentHandler(child_frame)); + + mojo::Remote<mojom::blink::TextFragmentReceiver> remote; + EXPECT_FALSE(remote.is_bound()); + child_frame->BindTextFragmentReceiver(remote.BindNewPipeAndPassReceiver()); + + EXPECT_TRUE(HasTextFragmentHandler(child_frame)); + EXPECT_TRUE(remote.is_bound()); + remote.get()->RemoveFragments(); + + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(0u, child_frame->GetDocument()->Markers().Markers().size()); + + // Ensure the fragment is uninstalled + EXPECT_FALSE(child_frame->GetDocument()->View()->GetFragmentAnchor()); +} + +TEST_P(TextFragmentHandlerTest, + ShouldCreateTextFragmentHandlerAndRemoveHighlight) { + SimRequest request( + "https://example.com/" + "test.html#:~:text=test%20page&text=more%20text", + "text/html"); + LoadURL( + "https://example.com/" + "test.html#:~:text=test%20page&text=more%20text"); + request.Complete(R"HTML( + <!DOCTYPE html> + <style> + body { + height: 2200px; + } + #first { + position: absolute; + top: 1000px; + } + #second { + position: absolute; + top: 2000px; + } + </style> + <p id="first">This is a test page</p> + <p id="second">With some more text</p> + )HTML"); + RunAsyncMatchingTasks(); + + // Render two frames to handle the async step added by the beforematch event. + Compositor().BeginFrame(); + Compositor().BeginFrame(); + + EXPECT_EQ(2u, GetDocument().Markers().Markers().size()); + EXPECT_TRUE(HasTextFragmentHandler(GetDocument().GetFrame())); + + mojo::Remote<mojom::blink::TextFragmentReceiver> remote; + EXPECT_FALSE(remote.is_bound()); + GetDocument().GetFrame()->BindTextFragmentReceiver( + remote.BindNewPipeAndPassReceiver()); + + EXPECT_TRUE(HasTextFragmentHandler(GetDocument().GetFrame())); + EXPECT_TRUE(remote.is_bound()); + remote.get()->RemoveFragments(); + + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(0u, GetDocument().Markers().Markers().size()); + + // Ensure the fragment is uninstalled + EXPECT_FALSE(GetDocument().View()->GetFragmentAnchor()); +} + +TEST_P(TextFragmentHandlerTest, + ShouldCreateTextFragmentHandlerAndRequestSelector) { + SimRequest request("https://example.com/test.html", "text/html"); + LoadURL("https://example.com/test.html"); + request.Complete(R"HTML( + <!DOCTYPE html> + <div>Test page</div> + <p id='first'>First paragraph text that is longer than 20 chars</p> + <p id='second'>Second paragraph text</p> + )HTML"); + + Node* first_paragraph = GetDocument().getElementById("first")->firstChild(); + const auto& selected_start = Position(first_paragraph, 0); + const auto& selected_end = Position(first_paragraph, 28); + ASSERT_EQ("First paragraph text that is", + PlainText(EphemeralRange(selected_start, selected_end))); + + SetSelection(selected_start, selected_end); + + mojo::Remote<mojom::blink::TextFragmentReceiver> remote; + EXPECT_TRUE(HasTextFragmentHandler(GetDocument().GetFrame())); + EXPECT_FALSE(remote.is_bound()); + + GetDocument().GetFrame()->BindTextFragmentReceiver( + remote.BindNewPipeAndPassReceiver()); + + EXPECT_TRUE(HasTextFragmentHandler(GetDocument().GetFrame())); + EXPECT_TRUE(remote.is_bound()); + + bool callback_called = false; + String selector; + auto lambda = [](bool& callback_called, String& selector, + const String& generated_selector) { + selector = generated_selector; + callback_called = true; + }; + auto callback = + WTF::Bind(lambda, std::ref(callback_called), std::ref(selector)); + remote->RequestSelector(std::move(callback)); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(callback_called); + + EXPECT_EQ(selector, "First%20paragraph%20text%20that%20is"); + VerifyPreemptiveGenerationMetrics(true); +} + struct PreemptiveLinkGenerationTestPassToString { std::string operator()(const testing::TestParamInfo<bool> b) const { return b.param ? "Preemptive" : "NonPreemptive";
diff --git a/third_party/blink/renderer/core/page/scrolling/text_fragment_selector_generator.cc b/third_party/blink/renderer/core/page/scrolling/text_fragment_selector_generator.cc index 05923aa..5dc11019 100644 --- a/third_party/blink/renderer/core/page/scrolling/text_fragment_selector_generator.cc +++ b/third_party/blink/renderer/core/page/scrolling/text_fragment_selector_generator.cc
@@ -187,8 +187,12 @@ TextFragmentSelectorGenerator::TextFragmentSelectorGenerator( LocalFrame* main_frame) : frame_(main_frame) { - // Scroll-to-text doesn't support iframes. - DCHECK(main_frame->IsMainFrame()); + // Links are generally generated in the main frame except when the main frame + // delegates the text fragment to an iframe (e.g AMP Viewer pages). + if (!base::FeatureList::IsEnabled( + shared_highlighting::kSharedHighlightingAmp)) { + DCHECK(main_frame->IsMainFrame()); + } } void TextFragmentSelectorGenerator::Generate(const RangeInFlatTree& range,
diff --git a/third_party/blink/renderer/core/paint/cull_rect_updater.cc b/third_party/blink/renderer/core/paint/cull_rect_updater.cc index 3ff3e60d..c744e2a5 100644 --- a/third_party/blink/renderer/core/paint/cull_rect_updater.cc +++ b/third_party/blink/renderer/core/paint/cull_rect_updater.cc
@@ -196,8 +196,7 @@ if (should_match_fragments) { for (parent_fragment = &first_parent_fragment; parent_fragment; parent_fragment = parent_fragment->NextFragment()) { - if (parent_fragment->LogicalTopInFlowThread() == - fragment->LogicalTopInFlowThread()) + if (parent_fragment->FragmentID() == fragment->FragmentID()) break; } } else {
diff --git a/third_party/blink/renderer/core/paint/fragment_data.h b/third_party/blink/renderer/core/paint/fragment_data.h index e54f4b3..641bc33c1 100644 --- a/third_party/blink/renderer/core/paint/fragment_data.h +++ b/third_party/blink/renderer/core/paint/fragment_data.h
@@ -52,12 +52,32 @@ } void SetLayer(std::unique_ptr<PaintLayer>); - LayoutUnit LogicalTopInFlowThread() const { - return rare_data_ ? rare_data_->logical_top_in_flow_thread : LayoutUnit(); + // A fragment ID unique within the LayoutObject. In NG block fragmentation, + // this is the fragmentainer index. In legacy block fragmentation, it's the + // flow thread block-offset. + wtf_size_t FragmentID() const { + return rare_data_ ? rare_data_->fragment_id : 0; } + void SetFragmentID(wtf_size_t id) { + if (!rare_data_ && id == 0) + return; + EnsureRareData().fragment_id = id; + } + + LayoutUnit LogicalTopInFlowThread() const { +#if DCHECK_IS_ON() + DCHECK(!rare_data_ || rare_data_->has_set_flow_thread_offset_ || + !rare_data_->fragment_id); +#endif + return LayoutUnit::FromRawValue(static_cast<int>(FragmentID())); + } + void SetLogicalTopInFlowThread(LayoutUnit top) { - if (rare_data_ || top) - EnsureRareData().logical_top_in_flow_thread = top; + SetFragmentID(top.RawValue()); +#if DCHECK_IS_ON() + if (rare_data_) + rare_data_->has_set_flow_thread_offset_ = true; +#endif } // The pagination offset is the additional factor to add in to map from flow @@ -225,7 +245,7 @@ // Fragment specific data. PhysicalOffset legacy_pagination_offset; - LayoutUnit logical_top_in_flow_thread; + wtf_size_t fragment_id = 0; std::unique_ptr<ObjectPaintProperties> paint_properties; std::unique_ptr<RefCountedPropertyTreeState> local_border_box_properties; bool is_clip_path_cache_valid = false; @@ -234,6 +254,15 @@ CullRect cull_rect_; CullRect contents_cull_rect_; std::unique_ptr<FragmentData> next_fragment_; + +#if DCHECK_IS_ON() + // Legacy block fragmentation sets the flow thread offset for each + // FragmentData object, and this is used as its fragment_id, whereas NG + // block fragmentation uses the fragmentainer index instead. Here's a flag + // which can be used to assert that legacy code which expects flow thread + // offsets actually gets that. + bool has_set_flow_thread_offset_ = false; +#endif }; RareData& EnsureRareData();
diff --git a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc index b39306e..8d40c18 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc +++ b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc
@@ -727,6 +727,7 @@ PhysicalOffset paint_offset) { DCHECK(!box_fragment_.IsInlineFormattingContext()); PaintInfo paint_info_for_descendants = paint_info.ForDescendants(); + paint_info_for_descendants.SetIsInFragmentTraversal(); for (const NGLink& child : box_fragment_.Children()) { const NGPhysicalFragment& child_fragment = *child; DCHECK(child_fragment.IsBox());
diff --git a/third_party/blink/renderer/core/paint/paint_info.h b/third_party/blink/renderer/core/paint/paint_info.h index 37f14981..b6e1c70 100644 --- a/third_party/blink/renderer/core/paint/paint_info.h +++ b/third_party/blink/renderer/core/paint/paint_info.h
@@ -28,8 +28,8 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_PAINT_INFO_H_ #include "third_party/blink/renderer/core/core_export.h" -#include "third_party/blink/renderer/core/layout/layout_object.h" -#include "third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h" +#include "third_party/blink/renderer/core/layout/layout_box.h" +#include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h" // TODO(jchaffraix): Once we unify PaintBehavior and PaintLayerFlags, we should // move PaintLayerFlags to PaintPhase and rename it. Thus removing the need for // this #include @@ -59,14 +59,11 @@ PaintPhase phase, GlobalPaintFlags global_paint_flags, PaintLayerFlags paint_flags, - const LayoutBoxModelObject* paint_container = nullptr, - LayoutUnit fragment_logical_top_in_flow_thread = LayoutUnit()) + const LayoutBoxModelObject* paint_container = nullptr) : context(context), phase(phase), cull_rect_(cull_rect), paint_container_(paint_container), - fragment_logical_top_in_flow_thread_( - fragment_logical_top_in_flow_thread), paint_flags_(paint_flags), global_paint_flags_(global_paint_flags) {} @@ -76,8 +73,7 @@ phase(copy_other_fields_from.phase), cull_rect_(copy_other_fields_from.cull_rect_), paint_container_(copy_other_fields_from.paint_container_), - fragment_logical_top_in_flow_thread_( - copy_other_fields_from.fragment_logical_top_in_flow_thread_), + fragment_id_(copy_other_fields_from.fragment_id_), paint_flags_(copy_other_fields_from.paint_flags_), global_paint_flags_(copy_other_fields_from.global_paint_flags_) { // We should never pass is_painting_scrolling_background_ other PaintInfo. @@ -152,11 +148,16 @@ // Returns the fragment of the current painting object matching the current // layer fragment. - const FragmentData* FragmentToPaint(const LayoutObject& object) const { + const FragmentData* LegacyFragmentToPaint(const LayoutObject& object) const { + if (fragment_id_ == WTF::kNotFound) { + // We haven't been set up for legacy block fragmentation, so the object + // better not be fragmented, then. + DCHECK(!object.FirstFragment().NextFragment()); + return &object.FirstFragment(); + } for (const auto* fragment = &object.FirstFragment(); fragment; fragment = fragment->NextFragment()) { - if (fragment->LogicalTopInFlowThread() == - fragment_logical_top_in_flow_thread_) + if (fragment->FragmentID() == fragment_id_) return fragment; } // No fragment of the current painting object matches the layer fragment, @@ -164,20 +165,43 @@ return nullptr; } - // Returns the FragmentData of the specified physical fragment. If fragment - // traversal is supported, it will map directly to the right FragmentData. - // Otherwise we'll fall back to matching against the current + const FragmentData* FragmentToPaint(const LayoutObject& object) const { + if (const auto* box = DynamicTo<LayoutBox>(&object)) { + // We're are looking up FragmentData via LayoutObject, even though the + // object has NG fragments. This happens with objects that don't support + // fragment traversal, such as replaced content. We cannot use legacy- + // based lookup in such cases, as we might not have set a fragment ID to + // match against. Since we got here, though, it has to mean that we should + // paint the one and only fragment. + if (box->PhysicalFragmentCount()) { + // TODO(mstensho): We should DCHECK that box->PhysicalFragmentCount() is + // exactly 1 here (i.e. that the object is monolithic), but we are not + // ready for that yet, as there's code that enters legacy paint + // functions when we're traversing the fragment tree. See + // e.g. NGBoxFragmentPainter::RecordScrollHitTestData(), and how it does + // the job by invoking BoxPainter, which has no concept of + // fragments. One of the tests that would fail with such a DCHECK here + // is: + // virtual/layout_ng_block_frag/fast/multicol/overflow-across-columns.html + return &box->FirstFragment(); + } + } + return LegacyFragmentToPaint(object); + } + + // Returns the FragmentData of the specified physical fragment. If we're + // performing fragment traversal, it will map directly to the right + // FragmentData. Otherwise we'll fall back to matching against the current // PaintLayerFragment. const FragmentData* FragmentToPaint( const NGPhysicalFragment& fragment) const { - if (fragment.CanTraverse()) + if (fragment_id_ == WTF::kNotFound) return fragment.GetFragmentData(); - return FragmentToPaint(*fragment.GetLayoutObject()); + return LegacyFragmentToPaint(*fragment.GetLayoutObject()); } - void SetFragmentLogicalTopInFlowThread(LayoutUnit fragment_logical_top) { - fragment_logical_top_in_flow_thread_ = fragment_logical_top; - } + void SetFragmentID(wtf_size_t id) { fragment_id_ = id; } + void SetIsInFragmentTraversal() { fragment_id_ = WTF::kNotFound; } bool IsPaintingScrollingBackground() const { DCHECK(RuntimeEnabledFeatures::CompositeAfterPaintEnabled()); @@ -206,9 +230,13 @@ // The box model object that originates the current painting. const LayoutBoxModelObject* paint_container_; - // The logical top of the current fragment of the self-painting PaintLayer - // which initiated the current painting, in the containing flow thread. - LayoutUnit fragment_logical_top_in_flow_thread_; + // The ID of the fragment that we're currently painting. + // + // This is always used in legacy block fragmentation. In NG block + // fragmentation, it's only used when painting self-painting non-atomic + // inlines (because we currently have no way of mapping from + // NGPhysicalFragment to FragmentData in such cases). + wtf_size_t fragment_id_ = WTF::kNotFound; PaintLayerFlags paint_flags_; const GlobalPaintFlags global_paint_flags_;
diff --git a/third_party/blink/renderer/core/paint/paint_invalidator.cc b/third_party/blink/renderer/core/paint/paint_invalidator.cc index 7affc79..8289b31 100644 --- a/third_party/blink/renderer/core/paint/paint_invalidator.cc +++ b/third_party/blink/renderer/core/paint/paint_invalidator.cc
@@ -17,7 +17,6 @@ #include "third_party/blink/renderer/core/layout/layout_view.h" #include "third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h" #include "third_party/blink/renderer/core/layout/ng/legacy_layout_tree_walking.h" -#include "third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator.h" #include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h" #include "third_party/blink/renderer/core/mobile_metrics/mobile_friendliness_checker.h" #include "third_party/blink/renderer/core/page/link_highlight.h" @@ -32,14 +31,12 @@ namespace blink { void PaintInvalidator::UpdatePaintingLayer(const LayoutObject& object, - PaintInvalidatorContext& context, - bool is_ng_painting) { + PaintInvalidatorContext& context) { if (object.HasLayer() && To<LayoutBoxModelObject>(object).HasSelfPaintingLayer()) { context.painting_layer = To<LayoutBoxModelObject>(object).Layer(); - } else if (!is_ng_painting && - (object.IsColumnSpanAll() || - object.IsFloatingWithNonContainingBlockParent())) { + } else if (object.IsColumnSpanAll() || + object.IsFloatingWithNonContainingBlockParent()) { // See |LayoutObject::PaintingLayer| for the special-cases of floating under // inline and multicolumn. // Post LayoutNG the |LayoutObject::IsFloatingWithNonContainingBlockParent| @@ -68,8 +65,7 @@ void PaintInvalidator::UpdateDirectlyCompositedContainer( const LayoutObject& object, - PaintInvalidatorContext& context, - bool is_ng_painting) { + PaintInvalidatorContext& context) { if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) return; @@ -88,9 +84,8 @@ context.directly_composited_container_for_stacked_contents = context.directly_composited_container = &object.DirectlyCompositableContainer(); - } else if (!is_ng_painting && - (object.IsColumnSpanAll() || - object.IsFloatingWithNonContainingBlockParent())) { + } else if (object.IsColumnSpanAll() || + object.IsFloatingWithNonContainingBlockParent()) { // In these cases, the object may belong to an ancestor of the current // paint invalidation container, in paint order. // Post LayoutNG the |LayoutObject::IsFloatingWithNonContainingBlockParent| @@ -141,11 +136,6 @@ context.subtree_flags = 0; } } - - DCHECK_EQ(context.directly_composited_container, - object.DirectlyCompositableContainer()) - << object; - DCHECK_EQ(context.painting_layer, object.PaintingLayer()) << object; } void PaintInvalidator::UpdateFromTreeBuilderContext( @@ -311,9 +301,26 @@ object.GetMutableForPainting().EnsureIsReadyForPaintInvalidation(); - UpdatePaintingLayer(object, context, /* is_ng_painting */ !!pre_paint_info); - UpdateDirectlyCompositedContainer(object, context, - /* is_ng_painting */ !!pre_paint_info); + UpdatePaintingLayer(object, context); + UpdateDirectlyCompositedContainer(object, context); + +#if DCHECK_IS_ON() + // Assert that the container state in the invalidation context is consistent + // with what the LayoutObject tree says. We cannot do this if we're fragment- + // traversing an "orphaned" object (an object that has a fragment inside a + // fragmentainer, even though not all its ancestor objects have it; this may + // happen to OOFs, and also to floats, if they are inside a non-atomic + // inline). In such cases we'll just have to live with the inconsitency, which + // means that we'll lose any paint effects from such "missing" ancestors. + if (!pre_paint_info || !pre_paint_info->is_inside_orphaned_object) { + if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) { + DCHECK_EQ(context.directly_composited_container, + object.DirectlyCompositableContainer()) + << object; + } + DCHECK_EQ(context.painting_layer, object.PaintingLayer()) << object; + } +#endif // DCHECK_IS_ON() if (!object.ShouldCheckForPaintInvalidation() && !context.NeedsSubtreeWalk()) return false; @@ -339,7 +346,7 @@ } if (pre_paint_info) { - FragmentData& fragment_data = pre_paint_info->fragment_data; + FragmentData& fragment_data = *pre_paint_info->fragment_data; context.fragment_data = &fragment_data; if (tree_builder_context) {
diff --git a/third_party/blink/renderer/core/paint/paint_invalidator.h b/third_party/blink/renderer/core/paint/paint_invalidator.h index 58ceb37..7c6d974 100644 --- a/third_party/blink/renderer/core/paint/paint_invalidator.h +++ b/third_party/blink/renderer/core/paint/paint_invalidator.h
@@ -106,11 +106,10 @@ friend struct PaintInvalidatorContext; ALWAYS_INLINE void UpdatePaintingLayer(const LayoutObject&, - PaintInvalidatorContext&, - bool is_ng_painting); - ALWAYS_INLINE void UpdateDirectlyCompositedContainer(const LayoutObject&, - PaintInvalidatorContext&, - bool is_ng_painting); + PaintInvalidatorContext&); + ALWAYS_INLINE void UpdateDirectlyCompositedContainer( + const LayoutObject&, + PaintInvalidatorContext&); ALWAYS_INLINE void UpdateFromTreeBuilderContext( const PaintPropertyTreeBuilderFragmentContext&, PaintInvalidatorContext&);
diff --git a/third_party/blink/renderer/core/paint/paint_layer.cc b/third_party/blink/renderer/core/paint/paint_layer.cc index f748b7c..5523be3 100644 --- a/third_party/blink/renderer/core/paint/paint_layer.cc +++ b/third_party/blink/renderer/core/paint/paint_layer.cc
@@ -1817,8 +1817,7 @@ } else if (should_match_fragments) { for (root_fragment_data = &first_root_fragment_data; root_fragment_data; root_fragment_data = root_fragment_data->NextFragment()) { - if (root_fragment_data->LogicalTopInFlowThread() == - fragment_data->LogicalTopInFlowThread()) + if (root_fragment_data->FragmentID() == fragment_data->FragmentID()) break; } } else {
diff --git a/third_party/blink/renderer/core/paint/paint_layer_painter.cc b/third_party/blink/renderer/core/paint/paint_layer_painter.cc index 1b2303d..55179cf 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_painter.cc +++ b/third_party/blink/renderer/core/paint/paint_layer_painter.cc
@@ -731,18 +731,19 @@ context.GetPaintController(), chunk_properties, paint_layer_, DisplayItem::PaintPhaseToDrawingType(phase)); - PaintInfo paint_info( - context, cull_rect, phase, painting_info.GetGlobalPaintFlags(), - paint_flags, &painting_info.root_layer->GetLayoutObject(), - fragment.fragment_data ? fragment.fragment_data->LogicalTopInFlowThread() - : LayoutUnit()); + PaintInfo paint_info(context, cull_rect, phase, + painting_info.GetGlobalPaintFlags(), paint_flags, + &painting_info.root_layer->GetLayoutObject()); if (paint_layer_.GetLayoutObject().ChildPaintBlockedByDisplayLock()) paint_info.SetDescendantPaintingBlocked(true); - if (fragment.physical_fragment) + if (fragment.physical_fragment) { NGBoxFragmentPainter(*fragment.physical_fragment).Paint(paint_info); - else + } else { + if (fragment.fragment_data) + paint_info.SetFragmentID(fragment.fragment_data->FragmentID()); paint_layer_.GetLayoutObject().Paint(paint_info); + } } static CullRect LegacyCullRect(const PaintLayerFragment& fragment,
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc index 3d0cc4920..f10c509 100644 --- a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc +++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
@@ -28,7 +28,7 @@ #include "third_party/blink/renderer/core/layout/layout_view.h" #include "third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h" #include "third_party/blink/renderer/core/layout/ng/ng_block_break_token.h" -#include "third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator.h" +#include "third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.h" #include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h" #include "third_party/blink/renderer/core/layout/svg/layout_svg_resource_masker.h" #include "third_party/blink/renderer/core/layout/svg/layout_svg_root.h" @@ -255,6 +255,38 @@ bool IsInNGFragmentTraversal() const { return pre_paint_info_; } + void SwitchToOOFContext( + PaintPropertyTreeBuilderFragmentContext::ContainingBlockContext& + oof_context) const { + context_.current = oof_context; + + // If we're not block-fragmented, or if we're traversing the fragment tree + // to an orphaned object, simply setting a new context is all we have to do. + if (!oof_context.is_in_block_fragmentation || + (pre_paint_info_ && pre_paint_info_->is_inside_orphaned_object)) + return; + + // Inside NG block fragmentation we have to perform an offset adjustment. + // An OOF fragment that is contained by something inside a fragmentainer + // will be a direct child of the fragmentainer, rather than a child of its + // actual containing block. We therefore need to adjust the offset to make + // us relative to the fragmentainer before applying the offset of the OOF. + PhysicalOffset delta = + oof_context.paint_offset - context_.fragmentainer_paint_offset; + // So, we did store |fragmentainer_paint_offset| when entering the + // fragmentainer, but the offset may have been reset by + // UpdateForPaintOffsetTranslation() since we entered it, which we'll need + // to compensate for now. + delta += context_.adjustment_for_oof_in_fragmentainer; + context_.current.paint_offset -= delta; + } + + void ResetPaintOffset(PhysicalOffset new_offset = PhysicalOffset()) { + context_.adjustment_for_oof_in_fragmentainer += + context_.current.paint_offset - new_offset; + context_.current.paint_offset = new_offset; + } + void OnUpdate(PaintPropertyChangeType change) { property_changed_ = std::max(property_changed_, change); } @@ -504,7 +536,7 @@ // compositing code. if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() && NeedsIsolationNodes(object_)) { - context_.current.paint_offset = PhysicalOffset(); + ResetPaintOffset(); context_.current.directly_composited_container_paint_offset_subpixel_delta = PhysicalOffset(); return; @@ -519,9 +551,7 @@ PhysicalOffset subpixel_accumulation; if (RequiresFragmentStitching()) { const LayoutBox& box = To<LayoutBox>(object_); - const NGFragmentChildIterator& iterator = pre_paint_info_->iterator; - const NGPhysicalBoxFragment& fragment = *iterator->BoxFragment(); - const NGBlockBreakToken* incoming_break_token = iterator->BlockBreakToken(); + const NGPhysicalBoxFragment& fragment = pre_paint_info_->box_fragment; // Calculate this fragment's rectangle relatively to the enclosing stitched // layout object, with help from the break token. @@ -533,7 +563,8 @@ WritingModeConverter converter(box.StyleRef().GetWritingDirection(), PhysicalSize(box.Size())); LogicalOffset logical_offset; - if (incoming_break_token) + if (const NGBlockBreakToken* incoming_break_token = + FindPreviousBreakToken(fragment)) logical_offset.block_offset = incoming_break_token->ConsumedBlockSize(); LogicalRect logical_rect(logical_offset, converter.ToLogical(fragment.Size())); @@ -545,7 +576,7 @@ // offset in order to get to the right offset for each fragment. new_paint_offset = converter.ToPhysical(logical_rect).offset; - if (&pre_paint_info_->fragment_data == &object_.FirstFragment()) { + if (pre_paint_info_->fragment_data == &object_.FirstFragment()) { // Make the translation relatively to the top/left corner of the box. In // vertical-rl writing mode, the first fragment is not the leftmost one. PhysicalOffset topleft = context_.current.paint_offset - new_paint_offset; @@ -576,7 +607,7 @@ // If the object has a non-translation transform, discard the fractional // paint offset which can't be transformed by the transform. if (!CanPropagateSubpixelAccumulation()) { - context_.current.paint_offset = new_paint_offset; + ResetPaintOffset(new_paint_offset); context_.current .directly_composited_container_paint_offset_subpixel_delta = PhysicalOffset(); @@ -584,7 +615,7 @@ } } - context_.current.paint_offset = new_paint_offset + subpixel_accumulation; + ResetPaintOffset(new_paint_offset + subpixel_accumulation); bool can_be_directly_composited = RuntimeEnabledFeatures::CompositeAfterPaintEnabled() @@ -973,10 +1004,11 @@ // Each individual fragment should have its own transform origin, based // on the fragment size. We'll do that, unless the fragments aren't to // be stitched together. - PhysicalSize size( - !pre_paint_info_ || RequiresFragmentStitching() - ? PhysicalSize(box.Size()) - : pre_paint_info_->iterator->BoxFragment()->Size()); + PhysicalSize size; + if (!pre_paint_info_ || RequiresFragmentStitching()) + size = PhysicalSize(box.Size()); + else + size = pre_paint_info_->box_fragment.Size(); TransformationMatrix matrix; style.ApplyTransform( matrix, size.ToLayoutSize(), ComputedStyle::kExcludeTransformOrigin, @@ -1100,9 +1132,10 @@ (object.HasLayer() || object.IsSVGChild()); } -static bool NeedsClipPathClip(const LayoutObject& object) { +static bool NeedsClipPathClip(const LayoutObject& object, + const FragmentData& fragment_data) { // We should have already updated the clip path cache when this is called. - if (object.FirstFragment().ClipPathPath()) { + if (fragment_data.ClipPathPath()) { DCHECK(MayNeedClipPathClip(object)); return true; } @@ -1639,7 +1672,7 @@ void FragmentPaintPropertyTreeBuilder::UpdateClipPathClip() { if (NeedsPaintPropertyUpdate()) { - if (!NeedsClipPathClip(object_)) { + if (!NeedsClipPathClip(object_, fragment_data_)) { OnClearClip(properties_->ClearClipPathClip()); } else { ClipPaintPropertyNode::State state( @@ -1868,9 +1901,9 @@ } else if (object_.IsBox()) { PhysicalRect clip_rect; if (pre_paint_info_) { - const NGFragmentChildIterator& iterator = pre_paint_info_->iterator; - clip_rect = iterator->BoxFragment()->OverflowClipRect( - context_.current.paint_offset, iterator->BlockBreakToken()); + clip_rect = pre_paint_info_->box_fragment.OverflowClipRect( + context_.current.paint_offset, + FindPreviousBreakToken(pre_paint_info_->box_fragment)); } else { clip_rect = To<LayoutBox>(object_).OverflowClipRect( context_.current.paint_offset); @@ -2452,15 +2485,6 @@ } void FragmentPaintPropertyTreeBuilder::UpdatePaintOffset() { - if (IsInNGFragmentTraversal()) { - // Text and non-atomic inlines are special, in that they share one - // FragmentData per fragmentainer, so their paint offset is kept at their - // container. For all other objects, include the offset now. - if (object_.IsBox()) - context_.current.paint_offset += pre_paint_info_->iterator->Link().offset; - return; - } - // Paint offsets for fragmented content are computed from scratch. const auto* enclosing_pagination_layer = full_context_.painting_layer->EnclosingPaginationLayer(); @@ -2515,14 +2539,17 @@ return; } - if (object_.IsFloating() && !object_.IsInLayoutNGInlineFormattingContext()) - context_.current.paint_offset = context_.paint_offset_for_float; + if (!pre_paint_info_) { + if (object_.IsFloating() && !object_.IsInLayoutNGInlineFormattingContext()) + context_.current.paint_offset = context_.paint_offset_for_float; - // Multicolumn spanners are painted starting at the multicolumn container (but - // still inherit properties in layout-tree order) so reset the paint offset. - if (object_.IsColumnSpanAll()) { - context_.current.paint_offset = - object_.Container()->FirstFragment().PaintOffset(); + // Multicolumn spanners are painted starting at the multicolumn container + // (but still inherit properties in layout-tree order) so reset the paint + // offset. + if (object_.IsColumnSpanAll()) { + context_.current.paint_offset = + object_.Container()->FirstFragment().PaintOffset(); + } } if (object_.IsBoxModelObject()) { @@ -2535,8 +2562,12 @@ box_model_object.OffsetForInFlowPosition(); break; case EPosition::kAbsolute: { - DCHECK_EQ(full_context_.container_for_absolute_position, - box_model_object.Container()); +#if DCHECK_IS_ON() + if (!pre_paint_info_ || !pre_paint_info_->is_inside_orphaned_object) { + DCHECK_EQ(full_context_.container_for_absolute_position, + box_model_object.Container()); + } +#endif if (RuntimeEnabledFeatures::TransformInteropEnabled()) { // FIXME(dbaron): When the TransformInteropEnabled flag is removed // because it's always enabled, we should move these variables from @@ -2547,7 +2578,7 @@ context_.absolute_position.rendering_context_id = context_.current.rendering_context_id; } - context_.current = context_.absolute_position; + SwitchToOOFContext(context_.absolute_position); // Absolutely positioned content in an inline should be positioned // relative to the inline. @@ -2564,8 +2595,12 @@ case EPosition::kSticky: break; case EPosition::kFixed: { - DCHECK_EQ(full_context_.container_for_fixed_position, - box_model_object.Container()); +#if DCHECK_IS_ON() + if (!pre_paint_info_ || !pre_paint_info_->is_inside_orphaned_object) { + DCHECK_EQ(full_context_.container_for_fixed_position, + box_model_object.Container()); + } +#endif if (RuntimeEnabledFeatures::TransformInteropEnabled()) { // FIXME(dbaron): When the TransformInteropEnabled flag is removed // because it's always enabled, we should move these variables from @@ -2576,7 +2611,7 @@ context_.fixed_position.rendering_context_id = context_.current.rendering_context_id; } - context_.current = context_.fixed_position; + SwitchToOOFContext(context_.fixed_position); // Fixed-position elements that are fixed to the viewport have a // transform above the scroll of the LayoutView. Child content is // relative to that transform, and hence the fixed-position element. @@ -2598,21 +2633,32 @@ } } - if (object_.IsBox()) { - // TODO(pdr): Several calls in this function walk back up the tree to - // calculate containers (e.g., physicalLocation, offsetForInFlowPosition*). - // The containing block and other containers can be stored on - // PaintPropertyTreeBuilderFragmentContext instead of recomputing them. - context_.current.paint_offset += To<LayoutBox>(object_).PhysicalLocation(); + if (const auto* box = DynamicTo<LayoutBox>(&object_)) { + if (pre_paint_info_) { + context_.current.paint_offset += pre_paint_info_->paint_offset; - // This is a weird quirk that table cells paint as children of table rows, - // but their location have the row's location baked-in. - // Similar adjustment is done in LayoutTableCell::offsetFromContainer(). - if (object_.IsTableCellLegacy()) { - LayoutObject* parent_row = object_.Parent(); - DCHECK(parent_row && parent_row->IsTableRow()); - context_.current.paint_offset -= - To<LayoutBox>(parent_row)->PhysicalLocation(); + // Determine whether we're inside block fragmentation or not. OOF + // descendants need special treatment inside block fragmentation. + context_.current.is_in_block_fragmentation = + pre_paint_info_->fragmentainer_idx != WTF::kNotFound && + box->GetNGPaginationBreakability() != LayoutBox::kForbidBreaks; + } else { + // TODO(pdr): Several calls in this function walk back up the tree to + // calculate containers (e.g., physicalLocation, + // offsetForInFlowPosition*). The containing block and other containers + // can be stored on PaintPropertyTreeBuilderFragmentContext instead of + // recomputing them. + context_.current.paint_offset += box->PhysicalLocation(); + + // This is a weird quirk that table cells paint as children of table rows, + // but their location have the row's location baked-in. + // Similar adjustment is done in LayoutTableCell::offsetFromContainer(). + if (object_.IsTableCellLegacy()) { + LayoutObject* parent_row = object_.Parent(); + DCHECK(parent_row && parent_row->IsTableRow()); + context_.current.paint_offset -= + To<LayoutBox>(parent_row)->PhysicalLocation(); + } } } @@ -2942,7 +2988,7 @@ context_.fragments.push_back(PaintPropertyTreeBuilderFragmentContext()); else context_.fragments.resize(1); - InitFragmentPaintProperties(pre_paint_info_->fragment_data, + InitFragmentPaintProperties(*pre_paint_info_->fragment_data, needs_paint_properties, context_.fragments[0]); } @@ -3810,7 +3856,7 @@ DCHECK_EQ(context_.fragments.size(), 1u); FragmentPaintPropertyTreeBuilder builder(object_, pre_paint_info_, context_, context_.fragments[0], - pre_paint_info_->fragment_data); + *pre_paint_info_->fragment_data); builder.UpdateForSelf(); property_changed = std::max(property_changed, builder.PropertyChanged()); } else { @@ -3861,7 +3907,7 @@ FragmentData* fragment_data; if (pre_paint_info_) { DCHECK_EQ(context_.fragments.size(), 1u); - fragment_data = &pre_paint_info_->fragment_data; + fragment_data = pre_paint_info_->fragment_data; DCHECK(fragment_data); } else { fragment_data = &object_.GetMutableForPainting().FirstFragment();
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder.h b/third_party/blink/renderer/core/paint/paint_property_tree_builder.h index cd2800f..00a8f62 100644 --- a/third_party/blink/renderer/core/paint/paint_property_tree_builder.h +++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder.h
@@ -21,7 +21,7 @@ class LayoutObject; class LayoutNGTableSectionInterface; class LocalFrameView; -class NGFragmentChildIterator; +class NGPhysicalBoxFragment; class PaintLayer; class VisualViewport; @@ -96,6 +96,8 @@ // object has changed. bool layout_shift_root_changed = false; + bool is_in_block_fragmentation = false; + // Rendering context for 3D sorting. See // TransformPaintPropertyNode::renderingContextId. unsigned rendering_context_id = 0; @@ -123,8 +125,6 @@ // containing block of corresponding positioned descendants. Overflow clips // are also inherited by containing block tree instead of DOM tree, thus they // are included in the additional context too. - // - // Note that these contexts are not used in LayoutNGFragmentTraversal. ContainingBlockContext absolute_position; ContainingBlockContext fixed_position; @@ -156,6 +156,13 @@ PhysicalOffset old_paint_offset; + // Paint offset at the current innermost fragmentainer. + PhysicalOffset fragmentainer_paint_offset; + + // Amount of adjustment done by UpdateForPaintOffsetTranslation() since we + // entered the innermost fragmentainer. + PhysicalOffset adjustment_for_oof_in_fragmentainer; + // An additional offset that applies to the current fragment, but is detected // *before* the ContainingBlockContext is updated for it. Once the // ContainingBlockContext is set, this value should be added to @@ -177,7 +184,6 @@ Vector<PaintPropertyTreeBuilderFragmentContext, 1> fragments; - // TODO(mstensho): Stop using these in LayoutNGFragmentTraversal. const LayoutObject* container_for_absolute_position = nullptr; const LayoutObject* container_for_fixed_position = nullptr; @@ -262,12 +268,41 @@ STACK_ALLOCATED(); public: - NGPrePaintInfo(const NGFragmentChildIterator& iterator, - FragmentData& fragment_data) - : iterator(iterator), fragment_data(fragment_data) {} + NGPrePaintInfo(const NGPhysicalBoxFragment& box_fragment, + PhysicalOffset paint_offset, + wtf_size_t fragmentainer_idx, + bool is_first_for_node, + bool is_last_for_node, + bool is_inside_orphaned_object, + bool is_inside_fragment_child) + : box_fragment(box_fragment), + paint_offset(paint_offset), + fragmentainer_idx(fragmentainer_idx), + is_first_for_node(is_first_for_node), + is_last_for_node(is_last_for_node), + is_inside_orphaned_object(is_inside_orphaned_object), + is_inside_fragment_child(is_inside_fragment_child) {} - const NGFragmentChildIterator& iterator; - FragmentData& fragment_data; + // The fragment for the LayoutObject currently being processed, or, in the + // case of text and non-atomic inlines: the fragment of the containing block. + const NGPhysicalBoxFragment& box_fragment; + + FragmentData* fragment_data = nullptr; + PhysicalOffset paint_offset; + wtf_size_t fragmentainer_idx; + bool is_first_for_node; + bool is_last_for_node; + + // True if we're fragment-traversing an object (OOF or float) directly, + // instead of walking the layout object tree. In this case, the property / + // invalidation context chains will be missing ancestors between the + // fragmentainer and the OOF / float. + bool is_inside_orphaned_object; + + // True if |box_fragment| is the containing block of the LayoutObject + // currently being processed. Otherwise, |box_fragment| is a fragment for the + // LayoutObject itself. + bool is_inside_fragment_child; }; // Creates paint property tree nodes for non-local effects in the layout tree.
diff --git a/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc b/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc index cd331950..4c573771 100644 --- a/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc +++ b/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc
@@ -16,13 +16,11 @@ #include "third_party/blink/renderer/core/frame/visual_viewport.h" #include "third_party/blink/renderer/core/layout/layout_box_model_object.h" #include "third_party/blink/renderer/core/layout/layout_embedded_content.h" -#include "third_party/blink/renderer/core/layout/layout_fieldset.h" -#include "third_party/blink/renderer/core/layout/layout_multi_column_spanner_placeholder.h" +#include "third_party/blink/renderer/core/layout/layout_multi_column_flow_thread.h" #include "third_party/blink/renderer/core/layout/layout_shift_tracker.h" #include "third_party/blink/renderer/core/layout/layout_view.h" #include "third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h" #include "third_party/blink/renderer/core/layout/ng/ng_block_break_token.h" -#include "third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator.h" #include "third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.h" #include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h" #include "third_party/blink/renderer/core/page/chrome_client.h" @@ -37,114 +35,6 @@ namespace blink { -namespace { - -// Locate or/and set up the current FragmentData object. This may involve -// creating it, or resetting an existing one. If |allow_reset| is set, we're -// allowed to clear old FragmentData objects. -NGPrePaintInfo SetupFragmentData(const NGFragmentChildIterator& iterator, - bool allow_reset) { - // TODO(crbug.com/1043787): What's here is mostly gross, and we need to come - // up with something better. The way FragmentData works (and is stored) - // vs. the way NGPhysicalFragment works is less than ideal. - // - // There's essentially a 1:1 correspondence between a block-level - // NGPhysicalBoxFragment and FragmentData, but there's no direct link between - // them, so we have to do some work. In the future we might want to make - // FragmentData part of NGPhysicalBoxFragment objects, to simplify this, and - // to get rid of O(n^2) performance complexity (where n is the number of - // fragments generated by a node). Note that this performance complexity also - // exists in the legacy engine. - // - // For inline-level nodes, it gets a bit more complicated. There's one - // FragmentData object per fragmentainer said node occurs in. The offset and - // invalidation rectangle in each FragmentData will be a union of all the - // fragments generated by the node (one per line box, typically) in that - // fragmentainer. This also matches how we do it in legacy layout. It's - // considered too expensive to have one FragmentData object per line for each - // text node or non-atomic inline. - DCHECK(iterator->GetLayoutObject()); - const LayoutObject& object = *iterator->GetLayoutObject(); - FragmentData* fragment_data = &object.GetMutableForPainting().FirstFragment(); - const auto* incoming_break_token = iterator->BlockBreakToken(); - const NGPhysicalBoxFragment* box_fragment = iterator->BoxFragment(); - - // The need for paint properties is the same across all fragments, so if the - // first FragmentData needs it, so do all the others. - bool needs_paint_properties = fragment_data->PaintProperties(); - - if (const NGFragmentItem* fragment_item = iterator->FragmentItem()) { - // We're in an inline formatting context. The consumed block-size stored in - // the incoming break token will be stored in FragmentData objects to - // identify each portion for a given fragmentainer. - LayoutUnit consumed_block_size; - if (incoming_break_token) - consumed_block_size = incoming_break_token->ConsumedBlockSize(); - if (fragment_item->IsFirstForNode()) { - // This is the first fragment generated for the node (i.e. we're on the - // first line and first fragmentainer (column) that this node occurs - // in). Now is our chance to reset everything (the number or size of - // fragments may have changed since last time). All the other fragments - // will be visited in due course. - if (allow_reset && !object.IsBox()) { - // For text and non-atomic inlines, we now remove additional - // FragmentData objects, and reset the visual rect. The visual rect will - // be set and expanded, as we visit each individual fragment. - fragment_data->ClearNextFragment(); - } - fragment_data->SetLogicalTopInFlowThread(consumed_block_size); - } else { - // This is not the first fragment. Now see if we can find a FragmentData - // with the right consumed block-size (or flow thread logical top). If - // not, we'll have to create one now. - while (consumed_block_size > fragment_data->LogicalTopInFlowThread()) { - FragmentData* next_fragment_data = fragment_data->NextFragment(); - if (!next_fragment_data) { - fragment_data = &fragment_data->EnsureNextFragment(); - fragment_data->SetLogicalTopInFlowThread(consumed_block_size); - break; - } - fragment_data = next_fragment_data; - } - DCHECK_EQ(fragment_data->LogicalTopInFlowThread(), consumed_block_size); - } - } else { - // The fragment is block-level. - if (IsResumingLayout(incoming_break_token)) { - // This isn't the first fragment for the node. We now need to walk past - // all preceding fragments to figure out which FragmentData to return (or - // create, if it doesn't already exist). - const auto& layout_box = To<LayoutBox>(object); - for (wtf_size_t idx = 0;; idx++) { - DCHECK_LT(idx, layout_box.PhysicalFragmentCount()); - if (layout_box.GetPhysicalFragment(idx) == box_fragment) - break; - FragmentData* next = fragment_data->NextFragment(); - if (!next) { - DCHECK_EQ(layout_box.GetPhysicalFragment(idx + 1), box_fragment); - fragment_data = &fragment_data->EnsureNextFragment(); - break; - } - fragment_data = next; - } - fragment_data->SetLogicalTopInFlowThread( - incoming_break_token->ConsumedBlockSize()); - } - if (!box_fragment->BreakToken()) { - // We have reached the end. There may be more data entries that were - // needed in the previous layout, but not any more. Clear them. - fragment_data->ClearNextFragment(); - } - } - - if (needs_paint_properties) - fragment_data->EnsurePaintProperties(); - - return NGPrePaintInfo(iterator, *fragment_data); -} - -} // anonymous namespace - static void SetNeedsCompositingLayerPropertyUpdate(const LayoutObject& object) { if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) return; @@ -254,6 +144,12 @@ PrePaintTreeWalkContext context(parent_context, needs_tree_builder_context_update); + // Block fragmentation doesn't cross frame boundaries. + context.current_fragmentainer = {}; + context.absolute_positioned_container = {}; + context.fixed_positioned_container = {}; + context.oof_container_candidate_fragment = nullptr; + // ancestor_scroll_container_paint_layer does not cross frame boundaries. context.ancestor_scroll_container_paint_layer = nullptr; if (context.tree_builder_context) { @@ -277,7 +173,7 @@ is_wheel_event_regions_enabled_ = base::FeatureList::IsEnabled(::features::kWheelEventRegions); - Walk(*view, context, /* iterator */ nullptr); + Walk(*view, context, /* pre_paint_info */ nullptr); #if DCHECK_IS_ON() view->AssertSubtreeClearedPaintInvalidationFlags(); #endif @@ -425,8 +321,14 @@ } return frame_view.GetLayoutView() && - (ObjectRequiresTreeBuilderContext(*frame_view.GetLayoutView()) || - ContextRequiresChildTreeBuilderContext(context)); + NeedsTreeBuilderContextUpdate(*frame_view.GetLayoutView(), context); +} + +bool PrePaintTreeWalk::NeedsTreeBuilderContextUpdate( + const LayoutObject& object, + const PrePaintTreeWalkContext& parent_context) { + return ContextRequiresChildTreeBuilderContext(parent_context) || + ObjectRequiresTreeBuilderContext(object); } bool PrePaintTreeWalk::ObjectRequiresPrePaint(const LayoutObject& object) { @@ -545,18 +447,108 @@ } } +NGPrePaintInfo PrePaintTreeWalk::CreatePrePaintInfo( + const NGLink& child, + const PrePaintTreeWalkContext& context) { + const auto& fragment = *To<NGPhysicalBoxFragment>(child.fragment); + return NGPrePaintInfo(fragment, child.offset, + context.current_fragmentainer.fragmentainer_idx, + fragment.IsFirstForNode(), !fragment.BreakToken(), + context.is_inside_orphaned_object, + /* is_inside_fragment_child */ false); +} + +FragmentData* PrePaintTreeWalk::GetOrCreateFragmentData( + const LayoutObject& object, + const PrePaintTreeWalkContext& context, + const NGPrePaintInfo& pre_paint_info) { + // If |allow_update| is set, we're allowed to add, remove and modify + // FragmentData objects. Otherwise they will be left alone. + bool allow_update = context.NeedsTreeBuilderContext(); + + FragmentData* fragment_data = &object.GetMutableForPainting().FirstFragment(); + + // The need for paint properties is the same across all fragments, so if the + // first FragmentData needs it, so do all the others. + bool needs_paint_properties = fragment_data->PaintProperties(); + + wtf_size_t fragment_id = pre_paint_info.fragmentainer_idx; + // TODO(mstensho): For now we need to treat unfragmented as ID 0. It doesn't + // really matter for LayoutNG, but legacy + // PaintPropertyTreeBuilder::ContextForFragment() may take a walk up the tree + // and end up querying this (LayoutNG) object, and + // FragmentData::LogicalTopInFlowThread() will DCHECK that the value is 0 + // unless it has been explicitly set by legacy code (which won't happen, since + // it's an NG object). + if (fragment_id == WTF::kNotFound) + fragment_id = 0; + + if (pre_paint_info.is_first_for_node) { + if (allow_update) + fragment_data->ClearNextFragment(); + else + DCHECK_EQ(fragment_data->FragmentID(), fragment_id); + } else { + FragmentData* last_fragment = nullptr; + do { + if (fragment_data->FragmentID() >= fragment_id) + break; + last_fragment = fragment_data; + fragment_data = fragment_data->NextFragment(); + } while (fragment_data); + if (fragment_data) { + if (pre_paint_info.is_last_for_node) { + // We have reached the end. There may be more data entries that were + // needed in the previous layout, but not any more. Clear them. + if (allow_update) + fragment_data->ClearNextFragment(); + else + DCHECK(!fragment_data->NextFragment()); + } else if (fragment_data->FragmentID() != fragment_id) { + // There are entries for fragmentainers after this one, but none for + // this one. Remove the fragment tail. + DCHECK(allow_update); + DCHECK_GT(fragment_data->FragmentID(), fragment_id); + fragment_data->ClearNextFragment(); + } + } else { + DCHECK(allow_update); + fragment_data = &last_fragment->EnsureNextFragment(); + } + } + + if (allow_update) { + fragment_data->SetFragmentID(fragment_id); + + if (needs_paint_properties) + fragment_data->EnsurePaintProperties(); + } else { + DCHECK_EQ(fragment_data->FragmentID(), fragment_id); + DCHECK(!needs_paint_properties || fragment_data->PaintProperties()); + } + + return fragment_data; +} + void PrePaintTreeWalk::WalkInternal(const LayoutObject& object, PrePaintTreeWalkContext& context, - const NGFragmentChildIterator* iterator) { + NGPrePaintInfo* pre_paint_info) { PaintInvalidatorContext& paint_invalidator_context = context.paint_invalidator_context; - absl::optional<NGPrePaintInfo> pre_paint_info_storage; - NGPrePaintInfo* pre_paint_info = nullptr; - if (iterator) { - bool allow_reset = context.NeedsTreeBuilderContext(); - pre_paint_info_storage.emplace(SetupFragmentData(*iterator, allow_reset)); - pre_paint_info = &pre_paint_info_storage.value(); + if (pre_paint_info) { + DCHECK(!pre_paint_info->fragment_data); + // Find, update or create a FragmentData object to match the current block + // fragment. + // + // TODO(mstensho): If this is collapsed text or a culled inline, we might + // not have any work to do (we could just return early here), as there'll be + // no need for paint property updates or invalidation. However, this is a + // bit tricky to determine, because of things like LinkHighlight, which + // might set paint properties on a culled inline. + pre_paint_info->fragment_data = + GetOrCreateFragmentData(object, context, *pre_paint_info); + DCHECK(pre_paint_info->fragment_data); } // This must happen before updatePropertiesForSelf, because the latter reads @@ -674,6 +666,70 @@ } } +bool PrePaintTreeWalk::CollectMissableChildren( + PrePaintTreeWalkContext& context, + const NGPhysicalBoxFragment& parent) { + bool has_missable_children = false; + for (const NGLink& child : parent.Children()) { + if ((child->IsOutOfFlowPositioned() && + (context.current_fragmentainer.fragment || + child->IsFixedPositioned())) || + (child->IsFloating() && parent.IsInlineFormattingContext() && + context.current_fragmentainer.fragment)) { + // We'll add resumed floats (or floats that couldn't fit a fragment in the + // fragmentainer where it was discovered) that have escaped their inline + // formatting context. + // + // We'll also add all out-of-flow positioned fragments inside a + // fragmentation context. If a fragment is fixed-positioned, we even need + // to add those that aren't inside a fragmentation context, because they + // may have an ancestor LayoutObject inside one, and one of those + // ancestors may be out-of-flow positioned, which may be missed, in which + // case we'll miss this fixed-positioned one as well (since we don't enter + // descendant OOFs when walking missed children) (example: fixedpos inside + // missed abspos in relpos in multicol). + pending_missables_.insert(child.fragment); + has_missable_children = true; + } + } + return has_missable_children; +} + +void PrePaintTreeWalk::WalkMissedChildren(const NGPhysicalBoxFragment& fragment, + PrePaintTreeWalkContext& context) { + if (pending_missables_.IsEmpty()) + return; + + for (const NGLink& child : fragment.Children()) { + if (!child->IsOutOfFlowPositioned() && !child->IsFloating()) + continue; + if (!pending_missables_.Contains(child.fragment)) + continue; + const LayoutObject& descendant_object = *child->GetLayoutObject(); + PrePaintTreeWalkContext descendant_context( + context, NeedsTreeBuilderContextUpdate(descendant_object, context)); + if (child->IsOutOfFlowPositioned() && + descendant_context.tree_builder_context) { + PaintPropertyTreeBuilderFragmentContext& fragment_context = + descendant_context.tree_builder_context->fragments[0]; + // Reset the relevant OOF context to this fragmentainer, since this is its + // containing block, as far as the NG fragment structure is concerned. + // Note that when walking a missed child OOF fragment, we'll also + // forcefully miss any OOF descendant nodes, which is why we only set the + // context for the OOF type we're dealing with here. + if (child->IsFixedPositioned()) + fragment_context.fixed_position = fragment_context.current; + else + fragment_context.absolute_position = fragment_context.current; + } + descendant_context.is_inside_orphaned_object = true; + + NGPrePaintInfo pre_paint_info = + CreatePrePaintInfo(child, descendant_context); + Walk(descendant_object, descendant_context, &pre_paint_info); + } +} + LocalFrameView* FindWebViewPluginContentFrameView( const LayoutEmbeddedContent& embedded_content) { for (Frame* frame = embedded_content.GetFrame()->Tree().FirstChild(); frame; @@ -685,92 +741,133 @@ return nullptr; } -void PrePaintTreeWalk::WalkNGChildren(const LayoutObject* parent, - PrePaintTreeWalkContext& parent_context, - NGFragmentChildIterator* iterator) { +void PrePaintTreeWalk::WalkFragmentationContextRootChildren( + const LayoutObject& object, + const NGPhysicalBoxFragment& fragment, + PrePaintTreeWalkContext& context) { + // The actual children are inside the flow thread child of |object|. + const auto* flow_thread = + To<LayoutBlockFlow>(&object)->MultiColumnFlowThread(); + const LayoutObject& actual_parent = flow_thread ? *flow_thread : object; + FragmentData* fragmentainer_fragment_data = nullptr; #if DCHECK_IS_ON() const LayoutObject* fragmentainer_owner_box = nullptr; #endif - for (; !iterator->IsAtEnd(); iterator->Advance()) { - const LayoutObject* object = (*iterator)->GetLayoutObject(); - if (const auto* fragment_item = (*iterator)->FragmentItem()) { - // Line boxes are not interesting. They have no paint effects. Descend - // directly into children. - if (fragment_item->Type() == NGFragmentItem::kLine) { - WalkChildren(/* parent */ nullptr, parent_context, iterator); - continue; - } - } else if (!object) { - const NGPhysicalBoxFragment* box_fragment = (*iterator)->BoxFragment(); - if (UNLIKELY(box_fragment->IsLayoutObjectDestroyedOrMoved())) + + DCHECK(fragment.IsFragmentationContextRoot()); + + const auto outer_fragmentainer = context.current_fragmentainer; + absl::optional<wtf_size_t> inner_fragmentainer_idx; + + for (NGLink child : fragment.Children()) { + const auto* box_fragment = To<NGPhysicalBoxFragment>(child.fragment); + if (UNLIKELY(box_fragment->IsLayoutObjectDestroyedOrMoved())) + continue; + + if (box_fragment->GetLayoutObject()) { + // OOFs contained by a multicol container will be visited during object + // tree traversal. + if (box_fragment->IsOutOfFlowPositioned()) continue; - // Check |box_fragment| and the |LayoutBox| that produced it are in sync. - // |OwnerLayoutBox()| has a few DCHECKs for this purpose. - DCHECK(box_fragment->OwnerLayoutBox()); + // We'll walk all other non-fragmentainer children directly now, entering + // them from the fragment tree, rather than from the LayoutObject tree. + // One consequence of this is that paint effects on any ancestors between + // a column spanner and its multicol container will not be applied on the + // spanner. This is fixable, but it would require non-trivial amounts of + // special-code for such a special case. If anyone complains, we can + // revisit this decision. + if (box_fragment->IsColumnSpanAll()) + context.current_fragmentainer = outer_fragmentainer; - // A fragmentainer doesn't paint anything itself. Just include its offset - // and descend into children. - DCHECK((*iterator)->BoxFragment()->IsFragmentainerBox()); - if (UNLIKELY(!parent_context.tree_builder_context)) { - WalkChildren(/* parent */ nullptr, parent_context, iterator); - continue; - } - - PaintPropertyTreeBuilderContext& tree_builder_context = - *parent_context.tree_builder_context; - PaintPropertyTreeBuilderFragmentContext& context = - tree_builder_context.fragments[0]; - PaintPropertyTreeBuilderFragmentContext::ContainingBlockContext* - containing_block_context = &context.current; - const PhysicalOffset offset = (*iterator)->Link().offset; - containing_block_context->paint_offset += offset; - const PhysicalOffset paint_offset = - containing_block_context->paint_offset; - - // Create corresponding |FragmentData|. Hit-testing needs - // |FragmentData.PaintOffset|. - if (fragmentainer_fragment_data) { - DCHECK(!box_fragment->IsFirstForNode()); -#if DCHECK_IS_ON() - DCHECK_EQ(fragmentainer_owner_box, box_fragment->OwnerLayoutBox()); -#endif - fragmentainer_fragment_data = - &fragmentainer_fragment_data->EnsureNextFragment(); - } else { - const LayoutBox* owner_box = box_fragment->OwnerLayoutBox(); -#if DCHECK_IS_ON() - DCHECK(!fragmentainer_owner_box); - fragmentainer_owner_box = owner_box; -#endif - fragmentainer_fragment_data = - &owner_box->GetMutableForPainting().FirstFragment(); - if (box_fragment->IsFirstForNode()) { - fragmentainer_fragment_data->ClearNextFragment(); - } else { - // |box_fragment| is nested in another fragmentainer, and that it is - // the first one in this loop, but not the first one for the - // |LayoutObject|. Append a new |FragmentData| to the last one. - fragmentainer_fragment_data = - &fragmentainer_fragment_data->LastFragment().EnsureNextFragment(); - } - } - fragmentainer_fragment_data->SetPaintOffset(paint_offset); - - WalkChildren(/* parent */ nullptr, parent_context, iterator); - containing_block_context->paint_offset -= offset; + NGPrePaintInfo pre_paint_info = CreatePrePaintInfo(child, context); + Walk(*box_fragment->GetLayoutObject(), context, &pre_paint_info); continue; } - Walk(*object, parent_context, iterator); + + // Check |box_fragment| and the |LayoutBox| that produced it are in sync. + // |OwnerLayoutBox()| has a few DCHECKs for this purpose. + DCHECK(box_fragment->OwnerLayoutBox()); + + // A fragmentainer doesn't paint anything itself. Just include its offset + // and descend into children. + DCHECK(box_fragment->IsFragmentainerBox()); + + // Always keep track of the current innermost fragmentainer we're handling, + // as they may serve as containing blocks for OOF descendants. + context.current_fragmentainer.fragment = box_fragment; + + // Set up |inner_fragmentainer_idx| lazily, as it's O(n) (n == number of + // multicol container fragments). + if (!inner_fragmentainer_idx) + inner_fragmentainer_idx = PreviousInnerFragmentainerIndex(fragment); + context.current_fragmentainer.fragmentainer_idx = *inner_fragmentainer_idx; + + if (UNLIKELY(!context.tree_builder_context)) { + WalkChildren(actual_parent, box_fragment, context); + continue; + } + + PaintPropertyTreeBuilderContext& tree_builder_context = + *context.tree_builder_context; + PaintPropertyTreeBuilderFragmentContext& fragment_context = + tree_builder_context.fragments[0]; + PaintPropertyTreeBuilderFragmentContext::ContainingBlockContext* + containing_block_context = &fragment_context.current; + containing_block_context->paint_offset += child.offset; + + const PhysicalOffset paint_offset = containing_block_context->paint_offset; + // Keep track of the paint offset at the fragmentainer, and also reset the + // offset adjustment tracker. This is needed when entering OOF + // descendants. OOFs have the nearest fragmentainer as their containing + // block, so when entering them during LayoutObject tree traversal, we have + // to compensate for this. + fragment_context.fragmentainer_paint_offset = paint_offset; + fragment_context.adjustment_for_oof_in_fragmentainer = PhysicalOffset(); + + // Create corresponding |FragmentData|. Hit-testing needs + // |FragmentData.PaintOffset|. + if (fragmentainer_fragment_data) { + DCHECK(!box_fragment->IsFirstForNode()); +#if DCHECK_IS_ON() + DCHECK_EQ(fragmentainer_owner_box, box_fragment->OwnerLayoutBox()); +#endif + fragmentainer_fragment_data = + &fragmentainer_fragment_data->EnsureNextFragment(); + } else { + const LayoutBox* owner_box = box_fragment->OwnerLayoutBox(); +#if DCHECK_IS_ON() + DCHECK(!fragmentainer_owner_box); + fragmentainer_owner_box = owner_box; +#endif + fragmentainer_fragment_data = + &owner_box->GetMutableForPainting().FirstFragment(); + if (box_fragment->IsFirstForNode()) { + fragmentainer_fragment_data->ClearNextFragment(); + } else { + // |box_fragment| is nested in another fragmentainer, and that it is + // the first one in this loop, but not the first one for the + // |LayoutObject|. Append a new |FragmentData| to the last one. + fragmentainer_fragment_data = + &fragmentainer_fragment_data->LastFragment().EnsureNextFragment(); + } + } + fragmentainer_fragment_data->SetPaintOffset(paint_offset); + + WalkChildren(actual_parent, box_fragment, context); + + containing_block_context->paint_offset -= child.offset; + (*inner_fragmentainer_idx)++; } - const LayoutBlockFlow* parent_block = DynamicTo<LayoutBlockFlow>(parent); - if (!parent_block || !parent_block->MultiColumnFlowThread()) + if (!flow_thread) return; // Multicol containers only contain special legacy children invisible to // LayoutNG, so we need to clean them manually. - for (const LayoutObject* child = parent->SlowFirstChild(); child; + if (fragment.BreakToken()) + return; // Wait until we've reached the end. + for (const LayoutObject* child = object.SlowFirstChild(); child; child = child->NextSibling()) { DCHECK(child->IsLayoutFlowThread() || child->IsLayoutMultiColumnSet() || child->IsLayoutMultiColumnSpannerPlaceholder()); @@ -778,139 +875,287 @@ } } -void PrePaintTreeWalk::WalkLegacyChildren(const LayoutObject& object, - PrePaintTreeWalkContext& context) { - if (const auto* layout_box = DynamicTo<LayoutBox>(&object)) { - if (layout_box->CanTraversePhysicalFragments()) { - // Enter NG child fragment traversal. We'll stay in this mode for all - // descendants that support fragment traversal. We'll re-enter - // LayoutObject traversal for descendants that don't support it. This only - // works correctly if we're not block-fragmented, though, so DCHECK for - // that. - DCHECK_EQ(layout_box->PhysicalFragmentCount(), 1u); - const NGPhysicalBoxFragment& fragment = - To<NGPhysicalBoxFragment>(*layout_box->GetPhysicalFragment(0)); - DCHECK(!fragment.BreakToken()); - NGFragmentChildIterator child_iterator(fragment); - WalkNGChildren(&object, context, &child_iterator); - return; - } - } - - for (const LayoutObject* child = object.SlowFirstChild(); child; +void PrePaintTreeWalk::WalkLayoutObjectChildren( + const LayoutObject& parent_object, + const NGPhysicalBoxFragment* parent_fragment, + PrePaintTreeWalkContext& context) { + for (const LayoutObject* child = parent_object.SlowFirstChild(); child; child = child->NextSibling()) { - if (child->IsLayoutMultiColumnSpannerPlaceholder()) { - child->GetMutableForPainting().ClearPaintFlags(); + if (!parent_fragment) { + // If we haven't found a fragment tree to accompany us in our walk, + // perform a pure LayoutObject tree walk. This is needed for legacy block + // fragmentation, and it also works fine if there's no block fragmentation + // involved at all (in such cases we can either to do this, or perform the + // NGPhysicalBoxFragment-accompanied walk that we do further down). + + if (child->IsLayoutMultiColumnSpannerPlaceholder()) { + child->GetMutableForPainting().ClearPaintFlags(); + continue; + } + + Walk(*child, context, /* pre_paint_info */ nullptr); continue; } - // Skip out-of-flow positioned children lest they be walked twice. If |this| - // is an NG object, but it still walks its children the legacy way (this may - // happen to table-cells; see LayoutObject::CanTraversePhysicalFragments()), - // we're either going to handle it in the code below after the loop - if - // |this| is actually the containing block. Otherwise it will be handled by - // some ancestor - either in the same code below (if it's a legacy-walking - // object) or via regular child fragment traversal. If we walk it here as - // well, we'd end up walking it twice. This is both bad for performance, and - // also correctness, as fragment items are sensitive to how they're walked - // (see SetupFragmentData()). - if (UNLIKELY(RuntimeEnabledFeatures::LayoutNGFragmentTraversalEnabled() && - child->IsOutOfFlowPositioned() && object.IsLayoutNGObject())) + + // If we're in the middle of walking a missed OOF, don't enter nested OOFs + // (but miss those as well, and handle them via fragment traversal). + if (context.is_inside_orphaned_object && child->IsOutOfFlowPositioned()) continue; - Walk(*child, context, /* iterator */ nullptr); - } + // Perform an NGPhysicalBoxFragment-accompanied walk of the child + // LayoutObject tree. + // + // We'll map each child LayoutObject to a corresponding + // NGPhysicalBoxFragment. For text and non-atomic inlines this will be the + // fragment of their containing block, while for all other objects, it will + // be a fragment generated by the object itself. Even when we have LayoutNG + // fragments, we'll try to do the pre-paint walk it in LayoutObject tree + // order. This will ensure that paint properties are applied correctly (the + // LayoutNG fragment tree follows the containing block structure closely, + // but for paint effects, it's actually the LayoutObject / DOM tree + // structure that matters, e.g. when there's a relpos with a child with + // opacity, which has an absolutely positioned child, the absolutely + // positioned child should be affected by opacity, even if the object that + // establishes the opacity layer isn't in the containing block + // chain). Furthermore, culled inlines have no fragments, but they still + // need to be visited, since the invalidation code marks them for pre-paint. + const NGPhysicalBoxFragment* box_fragment = nullptr; + wtf_size_t fragmentainer_idx = + context.current_fragmentainer.fragmentainer_idx; + PhysicalOffset paint_offset; + const auto* child_box = DynamicTo<LayoutBox>(child); + bool is_first_for_node = true; + bool is_last_for_node = true; + bool is_inside_fragment_child = false; + if (parent_fragment->Items() && child->FirstInlineFragmentItemIndex()) { + for (const NGFragmentItem& item : parent_fragment->Items()->Items()) { + if (item.GetLayoutObject() != child) + continue; - if (!RuntimeEnabledFeatures::LayoutNGFragmentTraversalEnabled()) - return; + is_last_for_node = item.IsLastForNode(); + if (box_fragment) { + if (is_last_for_node) + break; + continue; + } - const LayoutBlock* block = DynamicTo<LayoutBlock>(&object); - if (!block) - return; - const auto* positioned_objects = block->PositionedObjects(); - if (!positioned_objects) - return; + paint_offset = item.OffsetInContainerFragment(); + is_first_for_node = item.IsFirstForNode(); - // If we have performed NG fragment traversal in any part of the subtree, we - // may have missed certain out-of-flow positioned objects. LayoutNG fragments - // are always children of their containing block, while the structure of the - // LayoutObject tree corresponds more closely to that of the DOM tree. - // - // Example: if we assume that flexbox isn't natively supported in LayoutNG: - // - // <div id="flex" style="display:flex; position:relative;"> - // <div id="flexitem"> - // <div id="abs" style="position:absolute;"></div> - // <div id="regular"></div> - // - // If we let |object| be #flex, it will be handled by legacy LayoutObject - // traversal, while #flexitem, on the other hand, can traverse its NG child - // fragments. However, #regular will be the only child fragment of #flexitem, - // since the containing block for #abs is #flex. So we'd miss it, unless we - // walk it now. - for (const LayoutBox* box : *positioned_objects) { - // It's important that objects that have already been walked be left alone. - // Otherwise, we might calculate the wrong offsets (and overwrite the - // correct ones) in case of out-of-flow positioned objects whose containing - // block is a relatively positioned non-atomic inline (such objects will - // already have been properly walked, since we don't switch engines within - // an inline formatting context). Put differently, the code here will only - // do the right thing if |object| is truly the containing block of the - // positioned objects in its list (which isn't the case if the containing - // block is a non-atomic inline). - if (!ObjectRequiresPrePaint(*box) && - !ObjectRequiresTreeBuilderContext(*box)) - continue; - DCHECK_EQ(box->Container(), &object); - Walk(*box, context, /* iterator */ nullptr); + if (item.BoxFragment() && !item.BoxFragment()->IsInlineBox()) { + box_fragment = item.BoxFragment(); + is_last_for_node = !box_fragment->BreakToken(); + break; + } else { + // Inlines will pass their containing block fragment (and its incoming + // break token). + box_fragment = parent_fragment; + is_inside_fragment_child = true; + } + + if (is_last_for_node) + break; + + // Keep looking for the end. We need to know whether this is the last + // time we're going to visit this object. + } + if (!box_fragment) + continue; + } else if (child->IsInline() && !child_box) { + // Deal with inline-level objects not searched for above. + // + // Needed for fragment-less objects that have children. This is the case + // for culled inlines. We're going to have to enter them for every + // fragment in the parent. + // + // The child is inline-level even if the parent fragment doesn't establish + // an inline formatting context. This may happen if there's only collapsed + // text, or if we had to insert a break in a block before we got to any + // inline content. Make sure that we visit such objects once. + + // Inlines will pass their containing block fragment (and its incoming + // break token). + box_fragment = parent_fragment; + is_inside_fragment_child = true; + + is_first_for_node = parent_fragment->IsFirstForNode(); + is_last_for_node = !parent_fragment->BreakToken(); + } else if (child_box && child_box->PhysicalFragmentCount()) { + // Figure out which fragment the child may be found inside. The fragment + // tree follows the structure of containing blocks closely, while here + // we're walking the LayoutObject tree (which follows the structure of the + // flat DOM tree, more or less). This means that for out-of-flow + // positioned objects, the fragment of the parent LayoutObject might not + // be the right place to search. + const NGPhysicalBoxFragment* search_fragment = parent_fragment; + if (child_box->IsOutOfFlowPositioned()) { + if (child_box->IsFixedPositioned()) { + search_fragment = context.fixed_positioned_container.fragment; + fragmentainer_idx = + context.fixed_positioned_container.fragmentainer_idx; + } else { + search_fragment = context.absolute_positioned_container.fragment; + fragmentainer_idx = + context.absolute_positioned_container.fragmentainer_idx; + } + if (!search_fragment) { + // Only walk unfragmented legacy-contained OOFs once. + if (context.is_inside_orphaned_object || + (context.current_fragmentainer.fragment && + !context.current_fragmentainer.fragment->IsFirstForNode())) + continue; + } + } + + if (search_fragment) { + // See if we can find a fragment for the child. + for (NGLink link : search_fragment->Children()) { + if (link->GetLayoutObject() != child) + continue; + // We found it! + box_fragment = To<NGPhysicalBoxFragment>(link.get()); + paint_offset = link.offset; + is_first_for_node = box_fragment->IsFirstForNode(); + is_last_for_node = !box_fragment->BreakToken(); + break; + } + // If we didn't find a fragment for the child, it means that the child + // doesn't occur inside the fragmentainer that we're currently handling. + if (!box_fragment) + continue; + } + } + + if (box_fragment) { + NGPrePaintInfo pre_paint_info( + *box_fragment, paint_offset, fragmentainer_idx, is_first_for_node, + is_last_for_node, context.is_inside_orphaned_object, + is_inside_fragment_child); + Walk(*child, context, &pre_paint_info); + } else { + Walk(*child, context, /* pre_paint_info */ nullptr); + } } } -void PrePaintTreeWalk::WalkChildren(const LayoutObject* object, +void PrePaintTreeWalk::WalkChildren(const LayoutObject& object, + const NGPhysicalBoxFragment* fragment, PrePaintTreeWalkContext& context, - const NGFragmentChildIterator* iterator) { - DCHECK(iterator || object); + bool is_inside_fragment_child) { + const LayoutBox* box = DynamicTo<LayoutBox>(&object); + if (box) { + if (fragment) { + if (!box->IsLayoutFlowThread() && (!box->CanTraversePhysicalFragments() || + !box->PhysicalFragmentCount())) { + // Leave LayoutNGBoxFragment-accompanied child LayoutObject traversal, + // since this object doesn't support that (or has no fragments (happens + // for table columns)). We need to switch back to legacy LayoutObject + // traversal for its children. We're then also assuming that we're + // either not block-fragmenting, or that this is monolithic content. We + // may re-enter LayoutNGBoxFragment-accompanied traversal if we get to a + // descendant that supports that. + DCHECK( + !box->FlowThreadContainingBlock() || + (box->GetNGPaginationBreakability() == LayoutBox::kForbidBreaks)); - if (!iterator) { - // We're not doing LayoutNG fragment traversal of this object. - WalkLegacyChildren(*object, context); - return; + fragment = nullptr; + context.oof_container_candidate_fragment = nullptr; + } + } else { + // There may be fragment-less objects, such as table columns or table + // column groups. + if (box->CanTraversePhysicalFragments() && box->PhysicalFragmentCount()) { + // Enter LayoutNGBoxFragment-accompanied child LayoutObject traversal. + // We'll stay in this mode for all descendants that support fragment + // traversal. We'll re-enter legacy traversal for descendants that don't + // support it. This only works correctly if we're not block-fragmented, + // though, so DCHECK for that. + // + // TODO(mstensho): Before shipping LayoutNGFragmentTraversal: Only enter + // this mode at block fragmentation roots (multicol containers), as + // LayoutNGBoxFragment-accompanied child LayoutObject traversal is more + // expensive than pure LayoutObject traversal: we need to search for + // each object among child fragments (NGLink) to find the offset, also + // when not fragmented at all. For now, though enter this mode as often + // as we can, for increased test coverage (when running with + // LayoutNGFragmentTraversal enabled). + DCHECK_EQ(box->PhysicalFragmentCount(), 1u); + fragment = To<NGPhysicalBoxFragment>(box->GetPhysicalFragment(0)); + DCHECK(!fragment->BreakToken()); + } + } + + // Inline-contained OOFs are placed in the containing block of the + // containing inline in NG, not an anonymous block that's part of a + // continuation, if any. We need to know where these might be stored, so + // that we eventually search the right ancestor fragment for them. + if (fragment && !box->IsAnonymousBlock()) + context.oof_container_candidate_fragment = fragment; } - // If we are performing LayoutNG fragment traversal, but this object doesn't - // support that, we need to switch back to legacy LayoutObject traversal for - // its children. We're then also assuming that we're either not - // block-fragmenting, or that this is monolithic content. We may re-enter - // LayoutNG fragment traversal if we get to a descendant that supports that. - if (object && !object->CanTraversePhysicalFragments()) { - DCHECK(!object->FlowThreadContainingBlock() || - (object->IsBox() && - To<LayoutBox>(object)->GetNGPaginationBreakability() == - LayoutBox::kForbidBreaks)); - WalkLegacyChildren(*object, context); - return; + // Keep track of fragments that act as containers for OOFs, so that we can + // search their children when looking for an OOF further down in the tree. + if (object.CanContainAbsolutePositionObjects()) { + if (context.current_fragmentainer.fragment && box && + box->GetNGPaginationBreakability() == LayoutBox::kForbidBreaks) { + // If we're in a fragmentation context, the parent fragment of OOFs is the + // fragmentainer, unless the object is monolithic, in which case nothing + // inside the object participates in the current block fragmentation + // context. This means that this object (and not the nearest + // fragmentainer) acts as a containing block for OOF descendants, + context.current_fragmentainer = {}; + } + // The OOF containing block structure is special under block fragmentation: + // A fragmentable OOF is always a direct child of a fragmentainer. + const auto* container_fragment = context.current_fragmentainer.fragment; + if (!container_fragment) + container_fragment = context.oof_container_candidate_fragment; + context.absolute_positioned_container = { + container_fragment, context.current_fragmentainer.fragmentainer_idx}; + if (object.CanContainFixedPositionObjects()) { + context.fixed_positioned_container = { + container_fragment, context.current_fragmentainer.fragmentainer_idx}; + } } - // Traverse child NG fragments. - NGFragmentChildIterator child_iterator(iterator->Descend()); - WalkNGChildren(object, context, &child_iterator); + if (fragment) { + bool has_missable_children = false; + // If we are at a block fragment, collect any missable children. + DCHECK(!is_inside_fragment_child || !object.IsBox()); + if (!is_inside_fragment_child) + has_missable_children = CollectMissableChildren(context, *fragment); + + // We'll always walk the LayoutObject tree when possible, but if this is a + // fragmentation context root (such as a multicol container), we need to + // enter each fragmentainer child and then walk all the LayoutObject + // children. + if (fragment->IsFragmentationContextRoot()) + WalkFragmentationContextRootChildren(object, *fragment, context); + else + WalkLayoutObjectChildren(object, fragment, context); + + if (has_missable_children) + WalkMissedChildren(*fragment, context); + } else { + WalkLayoutObjectChildren(object, fragment, context); + } } void PrePaintTreeWalk::Walk(const LayoutObject& object, const PrePaintTreeWalkContext& parent_context, - const NGFragmentChildIterator* iterator) { + NGPrePaintInfo* pre_paint_info) { const NGPhysicalBoxFragment* physical_fragment = nullptr; - bool is_last_fragment = true; - if (iterator) { - physical_fragment = (*iterator)->BoxFragment(); - if (const auto* fragment_item = (*iterator)->FragmentItem()) - is_last_fragment = fragment_item->IsLastForNode(); - else if (physical_fragment) - is_last_fragment = !physical_fragment->BreakToken(); + bool is_inside_fragment_child = false; + if (pre_paint_info) { + physical_fragment = &pre_paint_info->box_fragment; + if (physical_fragment && (physical_fragment->IsOutOfFlowPositioned() || + physical_fragment->IsFloating())) + pending_missables_.erase(physical_fragment); + is_inside_fragment_child = pre_paint_info->is_inside_fragment_child; } bool needs_tree_builder_context_update = - ContextRequiresChildTreeBuilderContext(parent_context) || - ObjectRequiresTreeBuilderContext(object); + NeedsTreeBuilderContextUpdate(object, parent_context); #if DCHECK_IS_ON() CheckTreeBuilderContextState(object, parent_context); @@ -932,7 +1177,7 @@ context.tree_builder_context->clip_changed = false; } - WalkInternal(object, context, iterator); + WalkInternal(object, context, pre_paint_info); bool child_walk_blocked = object.ChildPrePaintBlockedByDisplayLock(); // If we need a subtree walk due to context flags, we need to store that @@ -952,7 +1197,7 @@ } if (!child_walk_blocked) { - WalkChildren(&object, context, iterator); + WalkChildren(object, physical_fragment, context, is_inside_fragment_child); if (const auto* layout_embedded_content = DynamicTo<LayoutEmbeddedContent>(object)) { @@ -981,7 +1226,7 @@ } } } - if (is_last_fragment) + if (!pre_paint_info || pre_paint_info->is_last_for_node) object.GetMutableForPainting().ClearPaintFlags(); }
diff --git a/third_party/blink/renderer/core/paint/pre_paint_tree_walk.h b/third_party/blink/renderer/core/paint/pre_paint_tree_walk.h index 5ea8502..a311b0e4 100644 --- a/third_party/blink/renderer/core/paint/pre_paint_tree_walk.h +++ b/third_party/blink/renderer/core/paint/pre_paint_tree_walk.h
@@ -10,12 +10,15 @@ #include "third_party/blink/renderer/core/paint/paint_invalidator.h" #include "third_party/blink/renderer/core/paint/paint_property_tree_builder.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" +#include "third_party/blink/renderer/platform/wtf/hash_set.h" namespace blink { class LayoutObject; class LocalFrameView; -class NGFragmentChildIterator; +struct NGLink; +class NGPhysicalBoxFragment; +class NGPhysicalFragment; // This class walks the whole layout tree, beginning from the root // LocalFrameView, across frame boundaries. Helper classes are called for each @@ -31,6 +34,11 @@ static bool ObjectRequiresPrePaint(const LayoutObject&); static bool ObjectRequiresTreeBuilderContext(const LayoutObject&); + struct ContainingFragment { + const NGPhysicalBoxFragment* fragment = nullptr; + wtf_size_t fragmentainer_idx = WTF::kNotFound; + }; + // This provides a default base copy constructor for PrePaintTreeWalkContext. // It contains all fields except for tree_builder_context which needs special // treatment in the copy constructor. @@ -68,9 +76,29 @@ // enabled. bool clip_changed = false; + // True if we're fragment-traversing an object whose fragment wasn't found + // and walked when walking the layout object tree. This may happen for + // out-of-flow positioned and floated fragments inside block fragmentation, + // when an ancestor object doesn't have a fragment representation in a + // fragmentainer even if the OOF / float is there. + bool is_inside_orphaned_object = false; + const LayoutBoxModelObject* paint_invalidation_container = nullptr; const LayoutBoxModelObject* paint_invalidation_container_for_stacked_contents = nullptr; + + ContainingFragment current_fragmentainer; + ContainingFragment absolute_positioned_container; + ContainingFragment fixed_positioned_container; + + // When walking down the tree and discovering containers for OOFs, not every + // such container has the fragment actually containing OOF descendants; they + // may instead be inside a fragment generated by a parent (this happens for + // inline continuations, for instance). So keep track of the innermost valid + // container fragment for OOFs, and set + // absolute_positioned_container_fragment and + // fixed_positioned_container_fragment to this one as appropriate. + const NGPhysicalBoxFragment* oof_container_candidate_fragment = nullptr; }; struct PrePaintTreeWalkContext : public PrePaintTreeWalkContextBase { @@ -113,6 +141,19 @@ const PrePaintTreeWalkContext&); #endif + // Upon entering a child LayoutObject, create an NGPrePaintInfo, and populate + // everything except its FragmentData. We need to get a bit further inside the + // child (WalkInternal()) before we can set up FragmentData (if we get there + // at all). + NGPrePaintInfo CreatePrePaintInfo(const NGLink& child, + const PrePaintTreeWalkContext& context); + + // Locate and/or set up a FragmentData object for the current object / + // physical fragment. + FragmentData* GetOrCreateFragmentData(const LayoutObject&, + const PrePaintTreeWalkContext&, + const NGPrePaintInfo&); + void Walk(LocalFrameView&, const PrePaintTreeWalkContext& parent_context); // This is to minimize stack frame usage during recursion. Modern compilers @@ -122,20 +163,44 @@ // See https://crbug.com/781301 . NOINLINE void WalkInternal(const LayoutObject&, PrePaintTreeWalkContext&, - const NGFragmentChildIterator*); - void WalkNGChildren(const LayoutObject* parent, - PrePaintTreeWalkContext& parent_context, - NGFragmentChildIterator*); - void WalkLegacyChildren(const LayoutObject&, PrePaintTreeWalkContext&); - void WalkChildren(const LayoutObject*, + NGPrePaintInfo*); + + // Add any "missable" children to a list. Missable children are children that + // we might not find during LayoutObject traversal. This happens when an + // ancestor LayoutObject (of the missable child) has no fragment inside a + // given fragmentainer, e.g. when there's an OOF fragment, but its containing + // block has no fragment inside that fragmentainer. Later, during the child + // walk, when a missable child is actually walked, it's removed from the + // list. + // + // Returns true if there are any missable children inside the fragment, false + // otherwise. + bool CollectMissableChildren(PrePaintTreeWalkContext&, + const NGPhysicalBoxFragment&); + + // Walk any missed children (i.e. those collected by CollectMissableChildren() + // and not walked by Walk()) after child object traversal. + void WalkMissedChildren(const NGPhysicalBoxFragment&, + PrePaintTreeWalkContext&); + + void WalkFragmentationContextRootChildren(const LayoutObject&, + const NGPhysicalBoxFragment&, + PrePaintTreeWalkContext&); + void WalkLayoutObjectChildren(const LayoutObject&, + const NGPhysicalBoxFragment*, + PrePaintTreeWalkContext&); + void WalkChildren(const LayoutObject&, + const NGPhysicalBoxFragment*, PrePaintTreeWalkContext&, - const NGFragmentChildIterator*); + bool is_inside_fragment_child = false); void Walk(const LayoutObject&, const PrePaintTreeWalkContext& parent_context, - const NGFragmentChildIterator*); + NGPrePaintInfo*); bool NeedsTreeBuilderContextUpdate(const LocalFrameView&, const PrePaintTreeWalkContext&); + bool NeedsTreeBuilderContextUpdate(const LayoutObject&, + const PrePaintTreeWalkContext&); void UpdateAuxiliaryObjectProperties(const LayoutObject&, PrePaintTreeWalkContext&); // Updates |LayoutObject::InsideBlockingTouchEventHandler|. Also ensures @@ -158,6 +223,10 @@ PaintInvalidator paint_invalidator_; + // List of fragments that may be missed during LayoutObject walking. See + // CollectMissableChildren() and WalkMissedChildren(). + HashSet<const NGPhysicalFragment*> pending_missables_; + // TODO(https://crbug.com/841364): Remove is_wheel_event_regions_enabled // argument once kWheelEventRegions feature flag is removed. bool is_wheel_event_regions_enabled_ = false;
diff --git a/third_party/blink/renderer/core/paint/table_section_painter.cc b/third_party/blink/renderer/core/paint/table_section_painter.cc index 15aced96..886e3ccd 100644 --- a/third_party/blink/renderer/core/paint/table_section_painter.cc +++ b/third_party/blink/renderer/core/paint/table_section_painter.cc
@@ -48,8 +48,7 @@ for (const auto* fragment = &layout_table_section_.FirstFragment(); fragment; fragment = fragment->NextFragment()) { PaintInfo fragment_paint_info = paint_info; - fragment_paint_info.SetFragmentLogicalTopInFlowThread( - fragment->LogicalTopInFlowThread()); + fragment_paint_info.SetFragmentID(fragment->FragmentID()); ScopedDisplayItemFragment scoped_display_item_fragment( fragment_paint_info.context, fragment_index++); PaintSection(fragment_paint_info); @@ -110,8 +109,7 @@ for (const auto* fragment = &layout_table_section_.FirstFragment(); fragment; fragment = fragment->NextFragment()) { PaintInfo fragment_paint_info = paint_info; - fragment_paint_info.SetFragmentLogicalTopInFlowThread( - fragment->LogicalTopInFlowThread()); + fragment_paint_info.SetFragmentID(fragment->FragmentID()); ScopedDisplayItemFragment scoped_display_item_fragment( fragment_paint_info.context, fragment_index++); PaintCollapsedSectionBorders(fragment_paint_info);
diff --git a/third_party/blink/renderer/modules/webaudio/OWNERS b/third_party/blink/renderer/modules/webaudio/OWNERS index a837fc9b..5248064 100644 --- a/third_party/blink/renderer/modules/webaudio/OWNERS +++ b/third_party/blink/renderer/modules/webaudio/OWNERS
@@ -1,2 +1 @@ hongchan@chromium.org -rtoy@chromium.org
diff --git a/third_party/blink/renderer/modules/webgpu/dawn_conversions.cc b/third_party/blink/renderer/modules/webgpu/dawn_conversions.cc index 20e1456..596dac2 100644 --- a/third_party/blink/renderer/modules/webgpu/dawn_conversions.cc +++ b/third_party/blink/renderer/modules/webgpu/dawn_conversions.cc
@@ -218,4 +218,25 @@ return std::make_tuple(dawn_stage, std::move(entry_point_keepalive)); } +WGPUTextureFormat AsDawnType(SkColorType color_type) { + switch (color_type) { + case SkColorType::kRGBA_8888_SkColorType: + return WGPUTextureFormat_RGBA8Unorm; + case SkColorType::kBGRA_8888_SkColorType: + return WGPUTextureFormat_BGRA8Unorm; + case SkColorType::kRGBA_1010102_SkColorType: + return WGPUTextureFormat_RGB10A2Unorm; + case SkColorType::kRGBA_F16_SkColorType: + return WGPUTextureFormat_RGBA16Float; + case SkColorType::kRGBA_F32_SkColorType: + return WGPUTextureFormat_RGBA32Float; + case SkColorType::kR8G8_unorm_SkColorType: + return WGPUTextureFormat_RG8Unorm; + case SkColorType::kR16G16_float_SkColorType: + return WGPUTextureFormat_RG16Float; + default: + return WGPUTextureFormat_Undefined; + } +} + } // namespace blink
diff --git a/third_party/blink/renderer/modules/webgpu/dawn_conversions.h b/third_party/blink/renderer/modules/webgpu/dawn_conversions.h index 9965b965..b5356a35 100644 --- a/third_party/blink/renderer/modules/webgpu/dawn_conversions.h +++ b/third_party/blink/renderer/modules/webgpu/dawn_conversions.h
@@ -36,6 +36,8 @@ WGPUOrigin3D AsDawnType(const V8GPUOrigin3D* webgpu_extent); WGPUTextureCopyView AsDawnType(const GPUImageCopyTexture* webgpu_view, GPUDevice* device); +WGPUTextureFormat AsDawnType(SkColorType color_type); + const char* ValidateTextureDataLayout(const GPUImageDataLayout* webgpu_layout, WGPUTextureDataLayout* layout); using OwnedProgrammableStageDescriptor =
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_bind_group.cc b/third_party/blink/renderer/modules/webgpu/gpu_bind_group.cc index 78702b2..e3f1e16 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_bind_group.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_bind_group.cc
@@ -46,11 +46,14 @@ break; case V8GPUBindingResource::ContentType::kGPUExternalTexture: std::unique_ptr<WGPUExternalTextureBindingEntry> - externalTextureBindingEntry; + externalTextureBindingEntry = + std::make_unique<WGPUExternalTextureBindingEntry>(); externalTextureBindingEntry->externalTexture = AsDawnType(webgpu_binding->resource()->GetAsGPUExternalTexture()); - dawn_binding.nextInChain = - reinterpret_cast<WGPUChainedStruct*>(&externalTextureBindingEntry); + externalTextureBindingEntry->chain.sType = + WGPUSType_ExternalTextureBindingEntry; + dawn_binding.nextInChain = reinterpret_cast<WGPUChainedStruct*>( + externalTextureBindingEntry.get()); externalTextureBindingEntries->push_back( std::move(externalTextureBindingEntry)); break;
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout.cc b/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout.cc index dc7a4ae8..03aaf14 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout.cc
@@ -63,7 +63,10 @@ if (webgpu_binding->hasExternalTexture()) { std::unique_ptr<WGPUExternalTextureBindingLayout> - externalTextureBindingLayout; + externalTextureBindingLayout = + std::make_unique<WGPUExternalTextureBindingLayout>(); + externalTextureBindingLayout->chain.sType = + WGPUSType_ExternalTextureBindingLayout; dawn_binding.nextInChain = reinterpret_cast<WGPUChainedStruct*>( externalTextureBindingLayout.get()); externalTextureBindingLayouts->push_back(
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_device.cc b/third_party/blink/renderer/modules/webgpu/gpu_device.cc index cda9c57f5..d865e5d 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_device.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_device.cc
@@ -9,6 +9,7 @@ #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_compute_pipeline_descriptor.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_device_descriptor.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_external_texture_descriptor.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_feature_name.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_render_pipeline_descriptor.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_uncaptured_error_event_init.h" @@ -24,6 +25,7 @@ #include "third_party/blink/renderer/modules/webgpu/gpu_command_encoder.h" #include "third_party/blink/renderer/modules/webgpu/gpu_compute_pipeline.h" #include "third_party/blink/renderer/modules/webgpu/gpu_device_lost_info.h" +#include "third_party/blink/renderer/modules/webgpu/gpu_external_texture.h" #include "third_party/blink/renderer/modules/webgpu/gpu_out_of_memory_error.h" #include "third_party/blink/renderer/modules/webgpu/gpu_pipeline_layout.h" #include "third_party/blink/renderer/modules/webgpu/gpu_query_set.h" @@ -37,8 +39,8 @@ #include "third_party/blink/renderer/modules/webgpu/gpu_texture.h" #include "third_party/blink/renderer/modules/webgpu/gpu_uncaptured_error_event.h" #include "third_party/blink/renderer/modules/webgpu/gpu_validation_error.h" +#include "third_party/blink/renderer/platform/bindings/microtask.h" #include "third_party/blink/renderer/platform/graphics/gpu/webgpu_image_bitmap_handler.h" -#include "third_party/blink/renderer/platform/heap/heap.h" namespace blink { @@ -272,14 +274,6 @@ } GPUTexture* GPUDevice::experimentalImportTexture( - HTMLVideoElement* video, - unsigned int usage_flags, - ExceptionState& exception_state) { - return GPUTexture::FromVideo( - this, video, static_cast<WGPUTextureUsage>(usage_flags), exception_state); -} - -GPUTexture* GPUDevice::experimentalImportTexture( HTMLCanvasElement* canvas, unsigned int usage_flags, ExceptionState& exception_state) { @@ -292,6 +286,15 @@ return GPUSampler::Create(this, descriptor); } +GPUExternalTexture* GPUDevice::importExternalTexture( + const GPUExternalTextureDescriptor* descriptor, + ExceptionState& exception_state) { + GPUExternalTexture* externalTexture = + GPUExternalTexture::FromVideo(this, descriptor, exception_state); + EnsureExternalTextureDestroyed(externalTexture); + return externalTexture; +} + GPUBindGroup* GPUDevice::createBindGroup( const GPUBindGroupDescriptor* descriptor, ExceptionState& exception_state) { @@ -475,8 +478,29 @@ visitor->Trace(limits_); visitor->Trace(queue_); visitor->Trace(lost_property_); + visitor->Trace(external_textures_pending_destroy_); ExecutionContextClient::Trace(visitor); EventTargetWithInlineData::Trace(visitor); } +void GPUDevice::EnsureExternalTextureDestroyed( + GPUExternalTexture* externalTexture) { + external_textures_pending_destroy_.push_back(externalTexture); + if (has_pending_microtask_) + return; + + Microtask::EnqueueMicrotask(WTF::Bind( + &GPUDevice::DestroyExternalTexturesMicrotask, WrapWeakPersistent(this))); + has_pending_microtask_ = true; +} + +void GPUDevice::DestroyExternalTexturesMicrotask() { + has_pending_microtask_ = false; + + auto externalTextures = std::move(external_textures_pending_destroy_); + for (Member<GPUExternalTexture> externalTexture : externalTextures) { + externalTexture->Destroy(); + } +} + } // namespace blink
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_device.h b/third_party/blink/renderer/modules/webgpu/gpu_device.h index 624ea4c2..4237762 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_device.h +++ b/third_party/blink/renderer/modules/webgpu/gpu_device.h
@@ -12,12 +12,12 @@ #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/modules/webgpu/dawn_callback.h" #include "third_party/blink/renderer/modules/webgpu/dawn_object.h" +#include "third_party/blink/renderer/platform/heap/heap.h" namespace blink { class ExecutionContext; class HTMLCanvasElement; -class HTMLVideoElement; class GPUAdapter; class GPUAdapter; class GPUBuffer; @@ -32,6 +32,8 @@ class GPUComputePipelineDescriptor; class GPUDeviceDescriptor; class GPUDeviceLostInfo; +class GPUExternalTexture; +class GPUExternalTextureDescriptor; class GPUPipelineLayout; class GPUPipelineLayoutDescriptor; class GPUQuerySet; @@ -77,13 +79,13 @@ GPUBuffer* createBuffer(const GPUBufferDescriptor* descriptor); GPUTexture* createTexture(const GPUTextureDescriptor* descriptor, ExceptionState& exception_state); - GPUTexture* experimentalImportTexture(HTMLVideoElement* video, - unsigned int usage_flags, - ExceptionState& exception_state); GPUTexture* experimentalImportTexture(HTMLCanvasElement* canvas, unsigned int usage_flags, ExceptionState& exception_state); GPUSampler* createSampler(const GPUSamplerDescriptor* descriptor); + GPUExternalTexture* importExternalTexture( + const GPUExternalTextureDescriptor* descriptor, + ExceptionState& exception_state); GPUBindGroup* createBindGroup(const GPUBindGroupDescriptor* descriptor, ExceptionState& exception_state); @@ -128,10 +130,14 @@ void InjectError(WGPUErrorType type, const char* message); void AddConsoleWarning(const char* message); + void EnsureExternalTextureDestroyed(GPUExternalTexture* externalTexture); + private: using LostProperty = ScriptPromiseProperty<Member<GPUDeviceLostInfo>, ToV8UndefinedGenerator>; + void DestroyExternalTexturesMicrotask(); + void OnUncapturedError(WGPUErrorType errorType, const char* message); void OnLogging(WGPULoggingType loggingType, const char* message); void OnDeviceLostError(const char* message); @@ -171,6 +177,9 @@ static constexpr int kMaxAllowedConsoleWarnings = 500; int allowed_console_warnings_remaining_ = kMaxAllowedConsoleWarnings; + bool has_pending_microtask_ = false; + HeapVector<Member<GPUExternalTexture>> external_textures_pending_destroy_; + DISALLOW_COPY_AND_ASSIGN(GPUDevice); };
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_device.idl b/third_party/blink/renderer/modules/webgpu/gpu_device.idl index bb4616e0..d2e72fb 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_device.idl +++ b/third_party/blink/renderer/modules/webgpu/gpu_device.idl
@@ -18,9 +18,9 @@ GPUBuffer createBuffer(GPUBufferDescriptor descriptor); [RaisesException] GPUTexture createTexture(GPUTextureDescriptor descriptor); - [RuntimeEnabled=WebGPUImportTexture, RaisesException] GPUTexture experimentalImportTexture(HTMLVideoElement video, GPUTextureUsageFlags usage); [RuntimeEnabled=WebGPUImportTexture, RaisesException] GPUTexture experimentalImportTexture(HTMLCanvasElement canvas, GPUTextureUsageFlags usage); GPUSampler createSampler(optional GPUSamplerDescriptor descriptor = {}); + [RaisesException] GPUExternalTexture importExternalTexture(GPUExternalTextureDescriptor descriptor); [RaisesException] GPUBindGroup createBindGroup(GPUBindGroupDescriptor descriptor); [RaisesException] GPUBindGroupLayout createBindGroupLayout(GPUBindGroupLayoutDescriptor descriptor);
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_external_texture.cc b/third_party/blink/renderer/modules/webgpu/gpu_external_texture.cc index 479b449..6841949 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_external_texture.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_external_texture.cc
@@ -4,12 +4,136 @@ #include "third_party/blink/renderer/modules/webgpu/gpu_external_texture.h" +#include "media/base/video_frame.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_external_texture_descriptor.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_texture_view_descriptor.h" +#include "third_party/blink/renderer/core/html/media/html_video_element.h" +#include "third_party/blink/renderer/modules/webgpu/dawn_conversions.h" #include "third_party/blink/renderer/modules/webgpu/gpu_device.h" +#include "third_party/blink/renderer/modules/webgpu/gpu_texture.h" +#include "third_party/blink/renderer/modules/webgpu/gpu_texture_view.h" +#include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h" +#include "third_party/blink/renderer/platform/graphics/gpu/webgpu_mailbox_texture.h" +#include "third_party/blink/renderer/platform/graphics/video_frame_image_util.h" namespace blink { -GPUExternalTexture::GPUExternalTexture(GPUDevice* device, - WGPUExternalTexture externalTexture) - : DawnObject<WGPUExternalTexture>(device, externalTexture) {} +// static +GPUExternalTexture* GPUExternalTexture::FromVideo( + GPUDevice* device, + const GPUExternalTextureDescriptor* webgpu_desc, + ExceptionState& exception_state) { + HTMLVideoElement* video = webgpu_desc->source(); + + if (!video || !video->videoWidth() || !video->videoHeight()) { + exception_state.ThrowDOMException(DOMExceptionCode::kOperationError, + "Missing video source"); + return nullptr; + } + + if (video->WouldTaintOrigin()) { + exception_state.ThrowSecurityError( + "Video element is tainted by cross-origin data and may not be loaded."); + return nullptr; + } + + media::PaintCanvasVideoRenderer* video_renderer = nullptr; + scoped_refptr<media::VideoFrame> media_video_frame; + if (auto* wmp = video->GetWebMediaPlayer()) { + media_video_frame = wmp->GetCurrentFrame(); + video_renderer = wmp->GetPaintCanvasVideoRenderer(); + } + + if (!media_video_frame || !video_renderer) { + exception_state.ThrowDOMException(DOMExceptionCode::kOperationError, + "Failed to import texture from video"); + return nullptr; + } + + // If the context is lost, the resource provider would be invalid. + auto context_provider_wrapper = SharedGpuContext::ContextProviderWrapper(); + if (!context_provider_wrapper || + context_provider_wrapper->ContextProvider()->IsContextLost()) + return nullptr; + + const CanvasResourceParams params(CanvasColorSpace::kSRGB, kN32_SkColorType, + kPremul_SkAlphaType); + const auto intrinsic_size = IntSize(media_video_frame->natural_size()); + + // Get a recyclable resource for producing WebGPU-compatible shared images. + std::unique_ptr<RecyclableCanvasResource> recyclable_canvas_resource = + device->GetDawnControlClient()->GetOrCreateCanvasResource( + intrinsic_size, params, /*is_origin_top_left=*/true); + if (!recyclable_canvas_resource) { + exception_state.ThrowDOMException(DOMExceptionCode::kOperationError, + "Failed to import texture from video"); + return nullptr; + } + + CanvasResourceProvider* resource_provider = + recyclable_canvas_resource->resource_provider(); + DCHECK(resource_provider); + + viz::RasterContextProvider* raster_context_provider = nullptr; + if (auto* context_provider = context_provider_wrapper->ContextProvider()) + raster_context_provider = context_provider->RasterContextProvider(); + + // TODO(crbug.com/1174809): This isn't efficient for VideoFrames which are + // already available as a shared image. A WebGPUMailboxTexture should be + // created directly from the VideoFrame instead. + const auto dest_rect = gfx::Rect(media_video_frame->natural_size()); + if (!DrawVideoFrameIntoResourceProvider( + std::move(media_video_frame), resource_provider, + raster_context_provider, dest_rect, video_renderer)) { + exception_state.ThrowDOMException(DOMExceptionCode::kOperationError, + "Failed to import texture from video"); + return nullptr; + } + + // Extract the format. If this format is invalid, Dawn will emit an error upon + // ExternalTexture creation. + WGPUTextureFormat format = + AsDawnType(resource_provider->ColorParams().GetSkColorType()); + + scoped_refptr<WebGPUMailboxTexture> mailbox_texture = + WebGPUMailboxTexture::FromCanvasResource( + device->GetDawnControlClient(), device->GetHandle(), + WGPUTextureUsage::WGPUTextureUsage_Sampled, + std::move(recyclable_canvas_resource)); + + WGPUTextureViewDescriptor viewDesc = {}; + WGPUTextureView plane0 = device->GetProcs().textureCreateView( + mailbox_texture->GetTexture(), &viewDesc); + + WGPUExternalTextureDescriptor dawn_desc = {}; + dawn_desc.plane0 = plane0; + dawn_desc.format = format; + + GPUExternalTexture* externalTexture = + MakeGarbageCollected<GPUExternalTexture>( + device, + device->GetProcs().deviceCreateExternalTexture(device->GetHandle(), + &dawn_desc), + mailbox_texture); + + // The texture view will be referenced during external texture creation, so by + // calling release here we ensure this texture view will be destructed when + // the external texture is destructed. + device->GetProcs().textureViewRelease(plane0); + + return externalTexture; +} + +GPUExternalTexture::GPUExternalTexture( + GPUDevice* device, + WGPUExternalTexture externalTexture, + scoped_refptr<WebGPUMailboxTexture> mailbox_texture) + : DawnObject<WGPUExternalTexture>(device, externalTexture), + mailbox_texture_(mailbox_texture) {} + +void GPUExternalTexture::Destroy() { + GetProcs().textureDestroy(mailbox_texture_->GetTexture()); + mailbox_texture_.reset(); +} } // namespace blink
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_external_texture.h b/third_party/blink/renderer/modules/webgpu/gpu_external_texture.h index 448d337..6980dca 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_external_texture.h +++ b/third_party/blink/renderer/modules/webgpu/gpu_external_texture.h
@@ -6,17 +6,30 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_GPU_EXTERNAL_TEXTURE_H_ #include "third_party/blink/renderer/modules/webgpu/dawn_object.h" +#include "third_party/blink/renderer/platform/wtf/ref_counted.h" namespace blink { +class ExceptionState; +class GPUExternalTextureDescriptor; +class WebGPUMailboxTexture; + class GPUExternalTexture : public DawnObject<WGPUExternalTexture> { DEFINE_WRAPPERTYPEINFO(); public: - explicit GPUExternalTexture(GPUDevice* device, - WGPUExternalTexture externalTexture); + static GPUExternalTexture* FromVideo( + GPUDevice* device, + const GPUExternalTextureDescriptor* webgpu_desc, + ExceptionState& exception_state); + explicit GPUExternalTexture( + GPUDevice* device, + WGPUExternalTexture externalTexture, + scoped_refptr<WebGPUMailboxTexture> mailbox_texture); + void Destroy(); private: + scoped_refptr<WebGPUMailboxTexture> mailbox_texture_; DISALLOW_COPY_AND_ASSIGN(GPUExternalTexture); };
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_texture.cc b/third_party/blink/renderer/modules/webgpu/gpu_texture.cc index e94e305..37e0e03b 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_texture.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_texture.cc
@@ -5,12 +5,10 @@ #include "third_party/blink/renderer/modules/webgpu/gpu_texture.h" #include "gpu/command_buffer/client/webgpu_interface.h" -#include "media/base/video_frame.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_texture_descriptor.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_texture_view_descriptor.h" #include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h" #include "third_party/blink/renderer/core/html/canvas/html_canvas_element.h" -#include "third_party/blink/renderer/core/html/media/html_video_element.h" #include "third_party/blink/renderer/modules/webgpu/dawn_conversions.h" #include "third_party/blink/renderer/modules/webgpu/gpu_device.h" #include "third_party/blink/renderer/modules/webgpu/gpu_texture_usage.h" @@ -20,7 +18,6 @@ #include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h" #include "third_party/blink/renderer/platform/graphics/gpu/webgpu_mailbox_texture.h" #include "third_party/blink/renderer/platform/graphics/gpu/webgpu_resource_provider_cache.h" -#include "third_party/blink/renderer/platform/graphics/video_frame_image_util.h" namespace blink { @@ -79,27 +76,6 @@ return dawn_desc; } -WGPUTextureFormat SkColorTypeToWGPUTextureFormat(SkColorType color_type) { - switch (color_type) { - case SkColorType::kRGBA_8888_SkColorType: - return WGPUTextureFormat_RGBA8Unorm; - case SkColorType::kBGRA_8888_SkColorType: - return WGPUTextureFormat_BGRA8Unorm; - case SkColorType::kRGBA_1010102_SkColorType: - return WGPUTextureFormat_RGB10A2Unorm; - case SkColorType::kRGBA_F16_SkColorType: - return WGPUTextureFormat_RGBA16Float; - case SkColorType::kRGBA_F32_SkColorType: - return WGPUTextureFormat_RGBA32Float; - case SkColorType::kR8G8_unorm_SkColorType: - return WGPUTextureFormat_RG8Unorm; - case SkColorType::kR16G16_float_SkColorType: - return WGPUTextureFormat_RG16Float; - default: - return WGPUTextureFormat_Undefined; - } -} - void popErrorDiscardCallback(WGPUErrorType, const char*, void*) { // This callback is used to silently consume expected error messages } @@ -148,99 +124,6 @@ } // static -GPUTexture* GPUTexture::FromVideo(GPUDevice* device, - HTMLVideoElement* video, - WGPUTextureUsage usage, - ExceptionState& exception_state) { - if (!video || !video->videoWidth() || !video->videoHeight()) { - exception_state.ThrowDOMException(DOMExceptionCode::kOperationError, - "Missing video source"); - return nullptr; - } - - if (video->WouldTaintOrigin()) { - exception_state.ThrowSecurityError( - "Video element is tainted by cross-origin data and may not be loaded."); - return nullptr; - } - - media::PaintCanvasVideoRenderer* video_renderer = nullptr; - scoped_refptr<media::VideoFrame> media_video_frame; - if (auto* wmp = video->GetWebMediaPlayer()) { - media_video_frame = wmp->GetCurrentFrame(); - video_renderer = wmp->GetPaintCanvasVideoRenderer(); - } - - if (!media_video_frame || !video_renderer) { - exception_state.ThrowDOMException(DOMExceptionCode::kOperationError, - "Failed to import texture from video"); - return nullptr; - } - - // If the context is lost, the resource provider would be invalid. - auto context_provider_wrapper = SharedGpuContext::ContextProviderWrapper(); - if (!context_provider_wrapper || - context_provider_wrapper->ContextProvider()->IsContextLost()) - return nullptr; - - const CanvasResourceParams params(CanvasColorSpace::kSRGB, kN32_SkColorType, - kPremul_SkAlphaType); - const auto intrinsic_size = IntSize(media_video_frame->natural_size()); - - // Get a recyclable resource for producing WebGPU-compatible shared images. - std::unique_ptr<RecyclableCanvasResource> recyclable_canvas_resource = - device->GetDawnControlClient()->GetOrCreateCanvasResource( - intrinsic_size, params, /*is_origin_top_left=*/true); - if (!recyclable_canvas_resource) { - exception_state.ThrowDOMException(DOMExceptionCode::kOperationError, - "Failed to import texture from video"); - return nullptr; - } - - CanvasResourceProvider* resource_provider = - recyclable_canvas_resource->resource_provider(); - DCHECK(resource_provider); - - viz::RasterContextProvider* raster_context_provider = nullptr; - if (auto* context_provider = context_provider_wrapper->ContextProvider()) - raster_context_provider = context_provider->RasterContextProvider(); - - // TODO(crbug.com/1174809): This isn't efficient for VideoFrames which are - // already available as a shared image. A WebGPUMailboxTexture should be - // created directly from the VideoFrame instead. - const auto dest_rect = gfx::Rect(media_video_frame->natural_size()); - if (!DrawVideoFrameIntoResourceProvider( - std::move(media_video_frame), resource_provider, - raster_context_provider, dest_rect, video_renderer)) { - exception_state.ThrowDOMException(DOMExceptionCode::kOperationError, - "Failed to import texture from video"); - return nullptr; - } - - // Extract the format. This is only used to validate experimentalImportTexture - // right now. We may want to reflect it from this function or validate it - // against some input parameters. - WGPUTextureFormat format = SkColorTypeToWGPUTextureFormat( - resource_provider->ColorParams().GetSkColorType()); - if (format == WGPUTextureFormat_Undefined) { - exception_state.ThrowDOMException( - DOMExceptionCode::kOperationError, - "Failed to import texture from video. Unsupported format."); - return nullptr; - } - - scoped_refptr<WebGPUMailboxTexture> mailbox_texture = - WebGPUMailboxTexture::FromCanvasResource( - device->GetDawnControlClient(), device->GetHandle(), usage, - std::move(recyclable_canvas_resource)); - - DCHECK(mailbox_texture->GetTexture() != nullptr); - - return MakeGarbageCollected<GPUTexture>(device, format, usage, - std::move(mailbox_texture)); -} - -// static GPUTexture* GPUTexture::FromCanvas(GPUDevice* device, HTMLCanvasElement* canvas, WGPUTextureUsage usage, @@ -297,8 +180,8 @@ // Extract the format. This is only used to validate experimentalImportTexture // right now. We may want to reflect it from this function or validate it // against some input parameters. - WGPUTextureFormat format = SkColorTypeToWGPUTextureFormat( - resource_provider->ColorParams().GetSkColorType()); + WGPUTextureFormat format = + AsDawnType(resource_provider->ColorParams().GetSkColorType()); if (format == WGPUTextureFormat_Undefined) { exception_state.ThrowDOMException(DOMExceptionCode::kOperationError, "Unsupported format for import texture"); @@ -355,6 +238,10 @@ mailbox_texture_(std::move(mailbox_texture)) { // Mailbox textures are all 2d texture. dimension_ = WGPUTextureDimension_2D; + + // The mailbox texture releases the texture on destruction, so reference it + // here. + GetProcs().textureReference(GetHandle()); } GPUTextureView* GPUTexture::createView(
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_texture.h b/third_party/blink/renderer/modules/webgpu/gpu_texture.h index 46499bbb..b2507d6 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_texture.h +++ b/third_party/blink/renderer/modules/webgpu/gpu_texture.h
@@ -12,7 +12,6 @@ class ExceptionState; class HTMLCanvasElement; -class HTMLVideoElement; class GPUTextureDescriptor; class GPUTextureView; class GPUTextureViewDescriptor; @@ -27,10 +26,6 @@ const GPUTextureDescriptor* webgpu_desc, ExceptionState& exception_state); static GPUTexture* CreateError(GPUDevice* device); - static GPUTexture* FromVideo(GPUDevice* device, - HTMLVideoElement* video, - WGPUTextureUsage usage, - ExceptionState& exception_state); static GPUTexture* FromCanvas(GPUDevice* device, HTMLCanvasElement* canvas, WGPUTextureUsage usage,
diff --git a/third_party/blink/renderer/modules/webid/web_id.cc b/third_party/blink/renderer/modules/webid/web_id.cc index 2ef8db4c..be1f270 100644 --- a/third_party/blink/renderer/modules/webid/web_id.cc +++ b/third_party/blink/renderer/modules/webid/web_id.cc
@@ -134,16 +134,6 @@ ScriptPromise WebId::get(ScriptState* script_state, const WebIdRequestOptions* options, ExceptionState& exception_state) { - if (!options->hasProvider()) { - exception_state.ThrowTypeError("Invalid parameters: provider required."); - return ScriptPromise(); - } - - if (!options->hasRequest()) { - exception_state.ThrowTypeError("Invalid parameters: request required."); - return ScriptPromise(); - } - DCHECK(options->hasMode()); // TODO(kenrb): Add some renderer-side validation here, such as validating @@ -161,8 +151,11 @@ auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); ScriptPromise promise = resolver->Promise(); + String client_id = options->hasClientId() ? options->clientId() : ""; + String nonce = options->hasNonce() ? options->nonce() : ""; + auth_request_->RequestIdToken( - provider, options->request(), ToRequestMode(options->mode()), + provider, client_id, nonce, ToRequestMode(options->mode()), WTF::Bind(&OnRequestIdToken, WrapPersistent(resolver))); return promise;
diff --git a/third_party/blink/renderer/modules/webid/web_id_request_options.idl b/third_party/blink/renderer/modules/webid/web_id_request_options.idl index 8d3dc870..591aecf 100644 --- a/third_party/blink/renderer/modules/webid/web_id_request_options.idl +++ b/third_party/blink/renderer/modules/webid/web_id_request_options.idl
@@ -11,8 +11,8 @@ dictionary WebIdRequestOptions { // URL for the Identity Provider. - USVString provider; - // Serialized request parameters. - USVString request; + required USVString provider; + USVString client_id; + USVString nonce; Mode mode = "permission"; };
diff --git a/third_party/blink/renderer/platform/OWNERS b/third_party/blink/renderer/platform/OWNERS index 37e78833..c7b8717 100644 --- a/third_party/blink/renderer/platform/OWNERS +++ b/third_party/blink/renderer/platform/OWNERS
@@ -15,7 +15,6 @@ mkwst@chromium.org noel@chromium.org pdr@chromium.org -rtoy@chromium.org schenney@chromium.org senorblanco@chromium.org skyostil@chromium.org
diff --git a/third_party/blink/renderer/platform/audio/OWNERS b/third_party/blink/renderer/platform/audio/OWNERS index a837fc9b..5248064 100644 --- a/third_party/blink/renderer/platform/audio/OWNERS +++ b/third_party/blink/renderer/platform/audio/OWNERS
@@ -1,2 +1 @@ hongchan@chromium.org -rtoy@chromium.org
diff --git a/third_party/blink/renderer/platform/bindings/trace_wrapper_v8_string.h b/third_party/blink/renderer/platform/bindings/trace_wrapper_v8_string.h index 67114790f..128672cb 100644 --- a/third_party/blink/renderer/platform/bindings/trace_wrapper_v8_string.h +++ b/third_party/blink/renderer/platform/bindings/trace_wrapper_v8_string.h
@@ -15,15 +15,14 @@ // Small shim around TraceWrapperReference<v8::String> with a few // utility methods. Internally, v8::String is represented as string // rope. -class GC_PLUGIN_IGNORE("crbug.com/841830") - PLATFORM_EXPORT TraceWrapperV8String final : public NameClient { +class PLATFORM_EXPORT TraceWrapperV8String final { DISALLOW_NEW(); public: TraceWrapperV8String() = default; TraceWrapperV8String(const TraceWrapperV8String&) = delete; TraceWrapperV8String& operator=(const TraceWrapperV8String&) = delete; - ~TraceWrapperV8String() final = default; + ~TraceWrapperV8String() = default; bool IsEmpty() const { return string_.IsEmpty(); } void Clear() { string_.Clear(); } @@ -35,11 +34,7 @@ void Concat(v8::Isolate*, const String&); String Flatten(v8::Isolate*) const; - virtual void Trace(Visitor* visitor) const { visitor->Trace(string_); } - - const char* NameInHeapSnapshot() const override { - return "TraceWrapperV8String"; - } + void Trace(Visitor* visitor) const { visitor->Trace(string_); } private: TraceWrapperV8Reference<v8::String> string_;
diff --git a/third_party/blink/renderer/platform/graphics/gpu/webgpu_image_bitmap_handler_test.cc b/third_party/blink/renderer/platform/graphics/gpu/webgpu_image_bitmap_handler_test.cc index c316f80..15ff68fa 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/webgpu_image_bitmap_handler_test.cc +++ b/third_party/blink/renderer/platform/graphics/gpu/webgpu_image_bitmap_handler_test.cc
@@ -65,6 +65,7 @@ // real WebGPU device. procs_.deviceReference = [](WGPUDevice) {}; procs_.deviceRelease = [](WGPUDevice) {}; + procs_.textureRelease = [](WGPUTexture) {}; } MOCK_METHOD(gpu::webgpu::ReservedTexture,
diff --git a/third_party/blink/renderer/platform/graphics/gpu/webgpu_mailbox_texture.cc b/third_party/blink/renderer/platform/graphics/gpu/webgpu_mailbox_texture.cc index 4651c0b..24ac27d 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/webgpu_mailbox_texture.cc +++ b/third_party/blink/renderer/platform/graphics/gpu/webgpu_mailbox_texture.cc
@@ -92,7 +92,7 @@ webgpu->GenUnverifiedSyncTokenCHROMIUM(finished_access_token.GetData()); std::move(destroy_callback_).Run(finished_access_token); } - + dawn_control_client_->GetProcs().textureRelease(texture_); dawn_control_client_->GetProcs().deviceRelease(device_); }
diff --git a/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc b/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc index d69c077a..f8e1c8b9 100644 --- a/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc +++ b/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc
@@ -126,6 +126,10 @@ const PropertyTreeState& destination) { FloatClipRect clip_rect = GeometryMapper::LocalToAncestorClipRect(destination, source); + if (clip_rect.Rect().IsEmpty()) { + rect_ = IntRect(); + return false; + } if (!clip_rect.IsInfinite()) { rect_.Intersect(EnclosingIntRect(clip_rect.Rect())); if (rect_.IsEmpty())
diff --git a/third_party/blink/renderer/platform/graphics/paint/cull_rect_test.cc b/third_party/blink/renderer/platform/graphics/paint/cull_rect_test.cc index 2e13e75f..964f3b78 100644 --- a/third_party/blink/renderer/platform/graphics/paint/cull_rect_test.cc +++ b/third_party/blink/renderer/platform/graphics/paint/cull_rect_test.cc
@@ -799,6 +799,17 @@ EXPECT_EQ(IntRect(0, 0, 100, 2000), cull_rect.Rect()); } +TEST_F(CullRectTest, ClipWithNonIntegralOffsetAndZeroSize) { + ScopedCullRectUpdateForTest cull_rect_update(true); + + auto clip = CreateClip(c0(), t0(), FloatRoundedRect(0.4, 0.6, 0, 0)); + PropertyTreeState source = PropertyTreeState::Root(); + PropertyTreeState destination(t0(), *clip, e0()); + CullRect cull_rect(IntRect(0, 0, 800, 600)); + cull_rect.ApplyPaintProperties(source, source, destination, absl::nullopt); + EXPECT_TRUE(cull_rect.Rect().IsEmpty()); +} + TEST_F(CullRectTest, IntersectsVerticalRange) { CullRect cull_rect(IntRect(0, 0, 50, 100));
diff --git a/third_party/blink/renderer/platform/media/cache_util.h b/third_party/blink/renderer/platform/media/cache_util.h index e7db731..70d94ebd 100644 --- a/third_party/blink/renderer/platform/media/cache_util.h +++ b/third_party/blink/renderer/platform/media/cache_util.h
@@ -31,14 +31,14 @@ // Return the logical OR of the reasons "response" cannot be used for a future // request (using the disk cache), or 0 if it might be useful. PLATFORM_EXPORT uint32_t -GetReasonsForUncacheability(const blink::WebURLResponse& response); +GetReasonsForUncacheability(const WebURLResponse& response); // Returns when we should evict data from this response from our // memory cache. Note that we may still cache data longer if // a audio/video tag is currently using it. Returns a TimeDelta // which is should be added to base::Time::Now() or base::TimeTicks::Now(). PLATFORM_EXPORT base::TimeDelta GetCacheValidUntil( - const blink::WebURLResponse& response); + const WebURLResponse& response); } // namespace blink
diff --git a/third_party/blink/renderer/platform/media/cdm_result_promise.h b/third_party/blink/renderer/platform/media/cdm_result_promise.h index 6a5b7be..0a69723 100644 --- a/third_party/blink/renderer/platform/media/cdm_result_promise.h +++ b/third_party/blink/renderer/platform/media/cdm_result_promise.h
@@ -29,7 +29,7 @@ class PLATFORM_EXPORT CdmResultPromise : public media::CdmPromiseTemplate<T...> { public: - CdmResultPromise(const blink::WebContentDecryptionModuleResult& result, + CdmResultPromise(const WebContentDecryptionModuleResult& result, const std::string& key_system_uma_prefix, const std::string& uma_name); CdmResultPromise(const CdmResultPromise&) = delete; @@ -47,7 +47,7 @@ using media::CdmPromiseTemplate<T...>::MarkPromiseSettled; using media::CdmPromiseTemplate<T...>::RejectPromiseOnDestruction; - blink::WebContentDecryptionModuleResult web_cdm_result_; + WebContentDecryptionModuleResult web_cdm_result_; // UMA prefix and name to report result and time to. std::string key_system_uma_prefix_; @@ -59,7 +59,7 @@ template <typename... T> CdmResultPromise<T...>::CdmResultPromise( - const blink::WebContentDecryptionModuleResult& result, + const WebContentDecryptionModuleResult& result, const std::string& key_system_uma_prefix, const std::string& uma_name) : web_cdm_result_(result), @@ -112,7 +112,7 @@ ConvertCdmExceptionToResultForUMA(exception_code)); web_cdm_result_.CompleteWithError(ConvertCdmException(exception_code), system_code, - blink::WebString::FromUTF8(error_message)); + WebString::FromUTF8(error_message)); } } // namespace blink
diff --git a/third_party/blink/renderer/platform/media/cdm_result_promise_helper.cc b/third_party/blink/renderer/platform/media/cdm_result_promise_helper.cc index a03c66e..76168f5 100644 --- a/third_party/blink/renderer/platform/media/cdm_result_promise_helper.cc +++ b/third_party/blink/renderer/platform/media/cdm_result_promise_helper.cc
@@ -25,44 +25,42 @@ return INVALID_STATE_ERROR; } -blink::WebContentDecryptionModuleException ConvertCdmException( +WebContentDecryptionModuleException ConvertCdmException( media::CdmPromise::Exception exception_code) { switch (exception_code) { case media::CdmPromise::Exception::NOT_SUPPORTED_ERROR: - return blink::kWebContentDecryptionModuleExceptionNotSupportedError; + return kWebContentDecryptionModuleExceptionNotSupportedError; case media::CdmPromise::Exception::INVALID_STATE_ERROR: - return blink::kWebContentDecryptionModuleExceptionInvalidStateError; + return kWebContentDecryptionModuleExceptionInvalidStateError; case media::CdmPromise::Exception::QUOTA_EXCEEDED_ERROR: - return blink::kWebContentDecryptionModuleExceptionQuotaExceededError; + return kWebContentDecryptionModuleExceptionQuotaExceededError; case media::CdmPromise::Exception::TYPE_ERROR: - return blink::kWebContentDecryptionModuleExceptionTypeError; + return kWebContentDecryptionModuleExceptionTypeError; } NOTREACHED(); - return blink::kWebContentDecryptionModuleExceptionInvalidStateError; + return kWebContentDecryptionModuleExceptionInvalidStateError; } -blink::WebEncryptedMediaKeyInformation::KeyStatus ConvertCdmKeyStatus( +WebEncryptedMediaKeyInformation::KeyStatus ConvertCdmKeyStatus( media::CdmKeyInformation::KeyStatus key_status) { switch (key_status) { case media::CdmKeyInformation::USABLE: - return blink::WebEncryptedMediaKeyInformation::KeyStatus::kUsable; + return WebEncryptedMediaKeyInformation::KeyStatus::kUsable; case media::CdmKeyInformation::INTERNAL_ERROR: - return blink::WebEncryptedMediaKeyInformation::KeyStatus::kInternalError; + return WebEncryptedMediaKeyInformation::KeyStatus::kInternalError; case media::CdmKeyInformation::EXPIRED: - return blink::WebEncryptedMediaKeyInformation::KeyStatus::kExpired; + return WebEncryptedMediaKeyInformation::KeyStatus::kExpired; case media::CdmKeyInformation::OUTPUT_RESTRICTED: - return blink::WebEncryptedMediaKeyInformation::KeyStatus:: - kOutputRestricted; + return WebEncryptedMediaKeyInformation::KeyStatus::kOutputRestricted; case media::CdmKeyInformation::OUTPUT_DOWNSCALED: - return blink::WebEncryptedMediaKeyInformation::KeyStatus:: - kOutputDownscaled; + return WebEncryptedMediaKeyInformation::KeyStatus::kOutputDownscaled; case media::CdmKeyInformation::KEY_STATUS_PENDING: - return blink::WebEncryptedMediaKeyInformation::KeyStatus::kStatusPending; + return WebEncryptedMediaKeyInformation::KeyStatus::kStatusPending; case media::CdmKeyInformation::RELEASED: - return blink::WebEncryptedMediaKeyInformation::KeyStatus::kReleased; + return WebEncryptedMediaKeyInformation::KeyStatus::kReleased; } NOTREACHED(); - return blink::WebEncryptedMediaKeyInformation::KeyStatus::kInternalError; + return WebEncryptedMediaKeyInformation::KeyStatus::kInternalError; } void ReportCdmResultUMA(const std::string& uma_name,
diff --git a/third_party/blink/renderer/platform/media/cdm_result_promise_helper.h b/third_party/blink/renderer/platform/media/cdm_result_promise_helper.h index 80a0161c..caf3bf5 100644 --- a/third_party/blink/renderer/platform/media/cdm_result_promise_helper.h +++ b/third_party/blink/renderer/platform/media/cdm_result_promise_helper.h
@@ -35,11 +35,11 @@ PLATFORM_EXPORT CdmResultForUMA ConvertCdmExceptionToResultForUMA(media::CdmPromise::Exception exception_code); -PLATFORM_EXPORT blink::WebContentDecryptionModuleException ConvertCdmException( - media::CdmPromise::Exception exception_code); +PLATFORM_EXPORT WebContentDecryptionModuleException +ConvertCdmException(media::CdmPromise::Exception exception_code); -PLATFORM_EXPORT blink::WebEncryptedMediaKeyInformation::KeyStatus -ConvertCdmKeyStatus(media::CdmKeyInformation::KeyStatus key_status); +PLATFORM_EXPORT WebEncryptedMediaKeyInformation::KeyStatus ConvertCdmKeyStatus( + media::CdmKeyInformation::KeyStatus key_status); PLATFORM_EXPORT void ReportCdmResultUMA(const std::string& uma_name, uint32_t system_code,
diff --git a/third_party/blink/renderer/platform/media/cdm_session_adapter.cc b/third_party/blink/renderer/platform/media/cdm_session_adapter.cc index 95b2c01..32be1b7a 100644 --- a/third_party/blink/renderer/platform/media/cdm_session_adapter.cc +++ b/third_party/blink/renderer/platform/media/cdm_session_adapter.cc
@@ -74,8 +74,7 @@ } std::unique_ptr<WebContentDecryptionModuleSessionImpl> -CdmSessionAdapter::CreateSession( - blink::WebEncryptedMediaSessionType session_type) { +CdmSessionAdapter::CreateSession(WebEncryptedMediaSessionType session_type) { return std::make_unique<WebContentDecryptionModuleSessionImpl>(this, session_type); }
diff --git a/third_party/blink/renderer/platform/media/cdm_session_adapter.h b/third_party/blink/renderer/platform/media/cdm_session_adapter.h index 650ff09..b74d194 100644 --- a/third_party/blink/renderer/platform/media/cdm_session_adapter.h +++ b/third_party/blink/renderer/platform/media/cdm_session_adapter.h
@@ -66,7 +66,7 @@ // Creates a new session and adds it to the internal map. RemoveSession() // must be called when destroying it, if RegisterSession() was called. std::unique_ptr<WebContentDecryptionModuleSessionImpl> CreateSession( - blink::WebEncryptedMediaSessionType session_type); + WebEncryptedMediaSessionType session_type); // Adds a session to the internal map. Called once the session is successfully // initialized. Returns true if the session was registered, false if there is
diff --git a/third_party/blink/renderer/platform/media/key_system_config_selector.cc b/third_party/blink/renderer/platform/media/key_system_config_selector.cc index 48b6b1f..86d68a4 100644 --- a/third_party/blink/renderer/platform/media/key_system_config_selector.cc +++ b/third_party/blink/renderer/platform/media/key_system_config_selector.cc
@@ -138,13 +138,13 @@ return EmeConfigRule::PERSISTENCE_REQUIRED; } -bool IsPersistentSessionType(blink::WebEncryptedMediaSessionType sessionType) { +bool IsPersistentSessionType(WebEncryptedMediaSessionType sessionType) { switch (sessionType) { - case blink::WebEncryptedMediaSessionType::kTemporary: + case WebEncryptedMediaSessionType::kTemporary: return false; - case blink::WebEncryptedMediaSessionType::kPersistentLicense: + case WebEncryptedMediaSessionType::kPersistentLicense: return true; - case blink::WebEncryptedMediaSessionType::kUnknown: + case WebEncryptedMediaSessionType::kUnknown: break; } @@ -207,9 +207,9 @@ } bool KeySystemConfigSelector::WebLocalFrameDelegate::AllowStorageAccessSync( - blink::WebContentSettingsClient::StorageType storage_type) { + WebContentSettingsClient::StorageType storage_type) { DCHECK(web_frame_); - blink::WebContentSettingsClient* content_settings_client = + WebContentSettingsClient* content_settings_client = web_frame_->GetContentSettingsClient(); return !content_settings_client || content_settings_client->AllowStorageAccessSync(storage_type); @@ -217,8 +217,7 @@ struct KeySystemConfigSelector::SelectionRequest { std::string key_system; - blink::WebVector<blink::WebMediaKeySystemConfiguration> - candidate_configurations; + WebVector<WebMediaKeySystemConfiguration> candidate_configurations; SelectConfigCB cb; bool was_permission_requested = false; bool is_permission_granted = false; @@ -467,11 +466,11 @@ bool KeySystemConfigSelector::GetSupportedCapabilities( const std::string& key_system, EmeMediaType media_type, - const blink::WebVector<blink::WebMediaKeySystemMediaCapability>& + const WebVector<WebMediaKeySystemMediaCapability>& requested_media_capabilities, // Corresponds to the partial configuration, plus restrictions. KeySystemConfigSelector::ConfigState* config_state, - std::vector<blink::WebMediaKeySystemMediaCapability>* + std::vector<WebMediaKeySystemMediaCapability>* supported_media_capabilities) { // From "3.1.1.3 Get Supported Capabilities for Audio/Video Type". // https://w3c.github.io/encrypted-media/#get-supported-capabilities-for-audio-video-type @@ -486,7 +485,7 @@ for (size_t i = 0; i < requested_media_capabilities.size(); i++) { // 3.1. Let content type be requested media capability's contentType member. // 3.2. Let robustness be requested media capability's robustness member. - const blink::WebMediaKeySystemMediaCapability& capability = + const WebMediaKeySystemMediaCapability& capability = requested_media_capabilities[i]; // 3.3. If contentType is the empty string, return null. if (capability.mime_type.IsEmpty()) { @@ -588,9 +587,9 @@ KeySystemConfigSelector::ConfigurationSupport KeySystemConfigSelector::GetSupportedConfiguration( const std::string& key_system, - const blink::WebMediaKeySystemConfiguration& candidate, + const WebMediaKeySystemConfiguration& candidate, ConfigState* config_state, - blink::WebMediaKeySystemConfiguration* accumulated_configuration) { + WebMediaKeySystemConfiguration* accumulated_configuration) { DVLOG(3) << __func__; // From @@ -711,7 +710,7 @@ // If preferences disallow local storage, then indicate persistent state is // not supported. if (!web_frame_delegate_->AllowStorageAccessSync( - blink::WebContentSettingsClient::StorageType::kLocalStorage)) { + WebContentSettingsClient::StorageType::kLocalStorage)) { if (persistent_state_support == EmeFeatureSupport::ALWAYS_ENABLED) return CONFIGURATION_NOT_SUPPORTED; persistent_state_support = EmeFeatureSupport::NOT_SUPPORTED; @@ -735,14 +734,14 @@ // let session types be candidate configuration's sessionTypes member. // - Otherwise, let session types be [ "temporary" ]. // (Done in MediaKeySystemAccessInitializer.) - blink::WebVector<blink::WebEncryptedMediaSessionType> session_types = + WebVector<WebEncryptedMediaSessionType> session_types = candidate.session_types; // 13. For each value in session types: for (size_t i = 0; i < session_types.size(); i++) { // 13.1. Let session type be the value. - blink::WebEncryptedMediaSessionType session_type = session_types[i]; - if (session_type == blink::WebEncryptedMediaSessionType::kUnknown) { + WebEncryptedMediaSessionType session_type = session_types[i]; + if (session_type == WebEncryptedMediaSessionType::kUnknown) { DVLOG(2) << "Rejecting requested configuration because " << "session type was not recognized."; return CONFIGURATION_NOT_SUPPORTED; @@ -764,13 +763,13 @@ // return NotSupported. EmeConfigRule session_type_rule = EmeConfigRule::NOT_SUPPORTED; switch (session_type) { - case blink::WebEncryptedMediaSessionType::kUnknown: + case WebEncryptedMediaSessionType::kUnknown: NOTREACHED(); return CONFIGURATION_NOT_SUPPORTED; - case blink::WebEncryptedMediaSessionType::kTemporary: + case WebEncryptedMediaSessionType::kTemporary: session_type_rule = EmeConfigRule::SUPPORTED; break; - case blink::WebEncryptedMediaSessionType::kPersistentLicense: + case WebEncryptedMediaSessionType::kPersistentLicense: session_type_rule = GetSessionTypeConfigRule( key_systems_->GetPersistentLicenseSessionSupport(key_system)); break; @@ -810,7 +809,7 @@ // 16. If the videoCapabilities member in candidate configuration is // non-empty: - std::vector<blink::WebMediaKeySystemMediaCapability> video_capabilities; + std::vector<WebMediaKeySystemMediaCapability> video_capabilities; if (!candidate.video_capabilities.empty()) { // 16.1. Let video capabilities be the result of executing the Get // Supported Capabilities for Audio/Video Type algorithm on Video, @@ -836,7 +835,7 @@ // 17. If the audioCapabilities member in candidate configuration is // non-empty: - std::vector<blink::WebMediaKeySystemMediaCapability> audio_capabilities; + std::vector<WebMediaKeySystemMediaCapability> audio_capabilities; if (!candidate.audio_capabilities.empty()) { // 17.1. Let audio capabilities be the result of executing the Get // Supported Capabilities for Audio/Video Type algorithm on Audio, @@ -980,9 +979,8 @@ } void KeySystemConfigSelector::SelectConfig( - const blink::WebString& key_system, - const blink::WebVector<blink::WebMediaKeySystemConfiguration>& - candidate_configurations, + const WebString& key_system, + const WebVector<WebMediaKeySystemConfiguration>& candidate_configurations, SelectConfigCB cb) { // Continued from requestMediaKeySystemAccess(), step 6, from // https://w3c.github.io/encrypted-media/#requestmediakeysystemaccess @@ -1053,7 +1051,7 @@ // and return a new MediaKeySystemAccess object.] ConfigState config_state(request->was_permission_requested, request->is_permission_granted); - blink::WebMediaKeySystemConfiguration accumulated_configuration; + WebMediaKeySystemConfiguration accumulated_configuration; media::CdmConfig cdm_config; ConfigurationSupport support = GetSupportedConfiguration( request->key_system, request->candidate_configurations[i],
diff --git a/third_party/blink/renderer/platform/media/key_system_config_selector_unittest.cc b/third_party/blink/renderer/platform/media/key_system_config_selector_unittest.cc index 22bc867..0b8394f 100644 --- a/third_party/blink/renderer/platform/media/key_system_config_selector_unittest.cc +++ b/third_party/blink/renderer/platform/media/key_system_config_selector_unittest.cc
@@ -381,9 +381,8 @@ : KeySystemConfigSelector::WebLocalFrameDelegate(nullptr) {} bool IsCrossOriginToMainFrame() override { return is_cross_origin_; } bool AllowStorageAccessSync( - blink::WebContentSettingsClient::StorageType storage_type) override { - if (storage_type == - blink::WebContentSettingsClient::StorageType::kLocalStorage) { + WebContentSettingsClient::StorageType storage_type) override { + if (storage_type == WebContentSettingsClient::StorageType::kLocalStorage) { return local_storage_allowed_; } return true; @@ -1275,13 +1274,13 @@ TEST_F(KeySystemConfigSelectorTest, VideoCapabilities_EncryptionScheme_Supported) { - std::vector<blink::WebMediaKeySystemMediaCapability> video_capabilities(1); + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(1); video_capabilities[0].content_type = "a"; video_capabilities[0].mime_type = kSupportedVideoContainer; video_capabilities[0].codecs = kSupportedVideoCodec; video_capabilities[0].encryption_scheme = kSupportedEncryptionScheme; - blink::WebMediaKeySystemConfiguration config = EmptyConfiguration(); + WebMediaKeySystemConfiguration config = EmptyConfiguration(); config.video_capabilities = video_capabilities; configs_.push_back(config); @@ -1293,14 +1292,14 @@ TEST_F(KeySystemConfigSelectorTest, VideoCapabilities_EncryptionScheme_DisallowHwSecureCodec) { - std::vector<blink::WebMediaKeySystemMediaCapability> video_capabilities(1); + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(1); video_capabilities[0].content_type = "a"; video_capabilities[0].mime_type = kSupportedVideoContainer; video_capabilities[0].codecs = kSupportedVideoCodec; video_capabilities[0].encryption_scheme = kDisallowHwSecureCodecEncryptionScheme; - blink::WebMediaKeySystemConfiguration config = EmptyConfiguration(); + WebMediaKeySystemConfiguration config = EmptyConfiguration(); config.video_capabilities = video_capabilities; configs_.push_back(config); @@ -1488,13 +1487,13 @@ } TEST_F(KeySystemConfigSelectorTest, HwSecureCodec_EncryptionScheme_Supported) { - std::vector<blink::WebMediaKeySystemMediaCapability> video_capabilities(1); + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(1); video_capabilities[0].content_type = "a"; video_capabilities[0].mime_type = kSupportedVideoContainer; video_capabilities[0].codecs = kRequireHwSecureCodec; video_capabilities[0].encryption_scheme = kSupportedEncryptionScheme; - blink::WebMediaKeySystemConfiguration config = EmptyConfiguration(); + WebMediaKeySystemConfiguration config = EmptyConfiguration(); config.video_capabilities = video_capabilities; configs_.push_back(config); @@ -1507,14 +1506,14 @@ TEST_F(KeySystemConfigSelectorTest, HwSecureCodec_EncryptionScheme_DisallowHwSecureCodec) { - std::vector<blink::WebMediaKeySystemMediaCapability> video_capabilities(1); + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(1); video_capabilities[0].content_type = "a"; video_capabilities[0].mime_type = kSupportedVideoContainer; video_capabilities[0].codecs = kRequireHwSecureCodec; video_capabilities[0].encryption_scheme = kDisallowHwSecureCodecEncryptionScheme; - blink::WebMediaKeySystemConfiguration config = EmptyConfiguration(); + WebMediaKeySystemConfiguration config = EmptyConfiguration(); config.video_capabilities = video_capabilities; configs_.push_back(config);
diff --git a/third_party/blink/renderer/platform/media/multi_buffer_data_source_unittest.cc b/third_party/blink/renderer/platform/media/multi_buffer_data_source_unittest.cc index b8d8b40..472735c 100644 --- a/third_party/blink/renderer/platform/media/multi_buffer_data_source_unittest.cc +++ b/third_party/blink/renderer/platform/media/multi_buffer_data_source_unittest.cc
@@ -238,7 +238,7 @@ public: MultiBufferDataSourceTest() : preload_(MultiBufferDataSource::AUTO) { ON_CALL(fetch_context_, CreateUrlLoader(_)) - .WillByDefault(Invoke([](const blink::WebAssociatedURLLoaderOptions&) { + .WillByDefault(Invoke([](const WebAssociatedURLLoaderOptions&) { return std::make_unique<NiceMock<MockWebAssociatedURLLoader>>(); })); } @@ -438,13 +438,13 @@ TestMultiBufferDataProvider* data_provider() { return multibuffer()->GetProvider(); } - blink::WebAssociatedURLLoader* active_loader() { + WebAssociatedURLLoader* active_loader() { EXPECT_TRUE(data_provider()); if (!data_provider()) return nullptr; return data_provider()->active_loader_.get(); } - blink::WebAssociatedURLLoader* active_loader_allownull() { + WebAssociatedURLLoader* active_loader_allownull() { TestMultiBufferDataProvider* data_provider = multibuffer()->GetProvider_allownull(); if (!data_provider) @@ -770,7 +770,7 @@ WebURLResponse response1 = response_generator_->GeneratePartial206(0, kDataSize - 1); response1.SetWasFetchedViaServiceWorker(true); - std::vector<blink::WebURL> url_list = {GURL(kHttpUrl)}; + std::vector<WebURL> url_list = {GURL(kHttpUrl)}; response1.SetUrlListViaServiceWorker(url_list); WebURLResponse response2 = response_generator_->GeneratePartial206(kDataSize, kDataSize * 2 - 1); @@ -785,7 +785,7 @@ WebURLResponse response1 = response_generator_->GeneratePartial206(0, kDataSize - 1); response1.SetWasFetchedViaServiceWorker(true); - std::vector<blink::WebURL> url_list = {GURL(kHttpDifferentPathUrl)}; + std::vector<WebURL> url_list = {GURL(kHttpDifferentPathUrl)}; response1.SetUrlListViaServiceWorker(url_list); WebURLResponse response2 = response_generator_->GeneratePartial206(kDataSize, kDataSize * 2 - 1); @@ -800,7 +800,7 @@ WebURLResponse response1 = response_generator_->GeneratePartial206(0, kDataSize - 1); response1.SetWasFetchedViaServiceWorker(true); - std::vector<blink::WebURL> url_list = {GURL(kHttpDifferentOriginUrl)}; + std::vector<WebURL> url_list = {GURL(kHttpDifferentOriginUrl)}; response1.SetUrlListViaServiceWorker(url_list); WebURLResponse response2 = response_generator_->GeneratePartial206(kDataSize, kDataSize * 2 - 1); @@ -815,7 +815,7 @@ WebURLResponse response1 = response_generator_->GeneratePartial206(0, kDataSize - 1); response1.SetWasFetchedViaServiceWorker(true); - std::vector<blink::WebURL> url_list = {GURL(kHttpDifferentOriginUrl)}; + std::vector<WebURL> url_list = {GURL(kHttpDifferentOriginUrl)}; response1.SetUrlListViaServiceWorker(url_list); WebURLResponse response2 = response_generator_->GeneratePartial206(kDataSize, kDataSize * 2 - 1); @@ -1436,8 +1436,8 @@ run_loop.Run(); // Server responds with a redirect. - blink::WebURL url{GURL(kHttpDifferentPathUrl)}; - blink::WebURLResponse response((GURL(kHttpUrl))); + WebURL url{GURL(kHttpDifferentPathUrl)}; + WebURLResponse response((GURL(kHttpUrl))); response.SetHttpStatusCode(307); data_provider()->WillFollowRedirect(url, response); @@ -1454,8 +1454,8 @@ Initialize(kHttpUrl, true); // Server responds with a redirect. - blink::WebURL url{GURL(kHttpDifferentPathUrl)}; - blink::WebURLResponse response((GURL(kHttpUrl))); + WebURL url{GURL(kHttpDifferentPathUrl)}; + WebURLResponse response((GURL(kHttpUrl))); response.SetHttpStatusCode(307); data_provider()->WillFollowRedirect(url, response); @@ -1476,8 +1476,8 @@ Initialize(kHttpUrl, true); // Server responds with a redirect. - blink::WebURL url{GURL(kHttpDifferentPathUrl)}; - blink::WebURLResponse response((GURL(kHttpUrl))); + WebURL url{GURL(kHttpDifferentPathUrl)}; + WebURLResponse response((GURL(kHttpUrl))); response.SetHttpStatusCode(307); data_provider()->WillFollowRedirect(url, response); @@ -1490,8 +1490,8 @@ Initialize(kHttpUrl, false); // Server responds with a redirect. - blink::WebURL url{GURL(kHttpDifferentPathUrl)}; - blink::WebURLResponse response((GURL(kHttpUrl))); + WebURL url{GURL(kHttpDifferentPathUrl)}; + WebURLResponse response((GURL(kHttpUrl))); response.SetHttpStatusCode(307); data_provider()->WillFollowRedirect(url, response); @@ -1529,7 +1529,7 @@ TEST_F(MultiBufferDataSourceTest, FileSizeLessThanBlockSize) { Initialize(kHttpUrl, true); GURL gurl(kHttpUrl); - blink::WebURLResponse response(gurl); + WebURLResponse response(gurl); response.SetHttpStatusCode(200); response.SetHttpHeaderField( WebString::FromUTF8("Content-Length"),
diff --git a/third_party/blink/renderer/platform/media/new_session_cdm_result_promise.cc b/third_party/blink/renderer/platform/media/new_session_cdm_result_promise.cc index 7783e43..1c09abb 100644 --- a/third_party/blink/renderer/platform/media/new_session_cdm_result_promise.cc +++ b/third_party/blink/renderer/platform/media/new_session_cdm_result_promise.cc
@@ -32,24 +32,24 @@ } // namespace -static blink::WebContentDecryptionModuleResult::SessionStatus ConvertStatus( +static WebContentDecryptionModuleResult::SessionStatus ConvertStatus( SessionInitStatus status) { switch (status) { case SessionInitStatus::UNKNOWN_STATUS: break; case SessionInitStatus::NEW_SESSION: - return blink::WebContentDecryptionModuleResult::kNewSession; + return WebContentDecryptionModuleResult::kNewSession; case SessionInitStatus::SESSION_NOT_FOUND: - return blink::WebContentDecryptionModuleResult::kSessionNotFound; + return WebContentDecryptionModuleResult::kSessionNotFound; case SessionInitStatus::SESSION_ALREADY_EXISTS: - return blink::WebContentDecryptionModuleResult::kSessionAlreadyExists; + return WebContentDecryptionModuleResult::kSessionAlreadyExists; } NOTREACHED(); - return blink::WebContentDecryptionModuleResult::kSessionNotFound; + return WebContentDecryptionModuleResult::kSessionNotFound; } NewSessionCdmResultPromise::NewSessionCdmResultPromise( - const blink::WebContentDecryptionModuleResult& result, + const WebContentDecryptionModuleResult& result, const std::string& key_system_uma_prefix, const std::string& uma_name, SessionInitializedCB new_session_created_cb, @@ -102,7 +102,7 @@ ConvertCdmExceptionToResultForUMA(exception_code)); web_cdm_result_.CompleteWithError(ConvertCdmException(exception_code), system_code, - blink::WebString::FromUTF8(error_message)); + WebString::FromUTF8(error_message)); } } // namespace blink
diff --git a/third_party/blink/renderer/platform/media/new_session_cdm_result_promise.h b/third_party/blink/renderer/platform/media/new_session_cdm_result_promise.h index d9ee42d..fe2a297 100644 --- a/third_party/blink/renderer/platform/media/new_session_cdm_result_promise.h +++ b/third_party/blink/renderer/platform/media/new_session_cdm_result_promise.h
@@ -46,7 +46,7 @@ : public media::CdmPromiseTemplate<std::string> { public: NewSessionCdmResultPromise( - const blink::WebContentDecryptionModuleResult& result, + const WebContentDecryptionModuleResult& result, const std::string& key_system_uma_prefix, const std::string& uma_name, SessionInitializedCB new_session_created_cb, @@ -63,7 +63,7 @@ const std::string& error_message) override; private: - blink::WebContentDecryptionModuleResult web_cdm_result_; + WebContentDecryptionModuleResult web_cdm_result_; // UMA prefix and name to report result and time to. std::string key_system_uma_prefix_;
diff --git a/third_party/blink/renderer/platform/media/remote_playback_client_wrapper_impl.cc b/third_party/blink/renderer/platform/media/remote_playback_client_wrapper_impl.cc index 5724d224..09516ef 100644 --- a/third_party/blink/renderer/platform/media/remote_playback_client_wrapper_impl.cc +++ b/third_party/blink/renderer/platform/media/remote_playback_client_wrapper_impl.cc
@@ -11,7 +11,7 @@ namespace blink { RemotePlaybackClientWrapperImpl::RemotePlaybackClientWrapperImpl( - blink::WebMediaPlayerClient* client) + WebMediaPlayerClient* client) : remote_playback_client_(client->RemotePlaybackClient()) {} RemotePlaybackClientWrapperImpl::~RemotePlaybackClientWrapperImpl() = default;
diff --git a/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider.cc b/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider.cc index b5f4b15..27c045a7 100644 --- a/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider.cc +++ b/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider.cc
@@ -78,8 +78,8 @@ // Prepare the request. WebURLRequest request(url_data_->url()); request.SetRequestContext(is_client_audio_element_ - ? blink::mojom::RequestContextType::AUDIO - : blink::mojom::RequestContextType::VIDEO); + ? mojom::RequestContextType::AUDIO + : mojom::RequestContextType::VIDEO); request.SetRequestDestination( is_client_audio_element_ ? network::mojom::RequestDestination::kAudio : network::mojom::RequestDestination::kVideo); @@ -90,14 +90,14 @@ if (url_data_->length() == kPositionNotSpecified && url_data_->CachedSize() == 0 && url_data_->BytesReadFromCache() == 0 && - blink::WebNetworkStateNotifier::SaveDataEnabled() && + WebNetworkStateNotifier::SaveDataEnabled() && (url_data_->url().SchemeIs(url::kHttpScheme) || url_data_->url().SchemeIs(url::kHttpsScheme))) { // This lets the data reduction proxy know that we don't have any previously // cached data for this resource. We can only send it if this is the first // request for this resource. request.SetPreviewsState(request.GetPreviewsState() | - blink::PreviewsTypes::kSrcVideoRedirectOn); + PreviewsTypes::kSrcVideoRedirectOn); } // We would like to send an if-match header with the request to @@ -112,7 +112,7 @@ WebString::FromUTF8("identity;q=1, *;q=0")); // Start resource loading. - blink::WebAssociatedURLLoaderOptions options; + WebAssociatedURLLoaderOptions options; if (url_data_->cors_mode() != UrlData::CORS_UNSPECIFIED) { options.expose_all_response_headers = true; // The author header set is empty, no preflight should go ahead. @@ -173,7 +173,7 @@ // WebAssociatedURLLoaderClient implementation. bool ResourceMultiBufferDataProvider::WillFollowRedirect( - const blink::WebURL& new_url, + const WebURL& new_url, const WebURLResponse& redirect_response) { DVLOG(1) << "willFollowRedirect"; redirects_to_ = new_url;
diff --git a/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider.h b/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider.h index 14a3920..888eafe 100644 --- a/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider.h +++ b/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider.h
@@ -30,7 +30,7 @@ class PLATFORM_EXPORT ResourceMultiBufferDataProvider : public MultiBuffer::DataProvider, - public blink::WebAssociatedURLLoaderClient { + public WebAssociatedURLLoaderClient { public: // NUmber of times we'll retry if the connection fails. enum { kMaxRetries = 30 }; @@ -52,16 +52,15 @@ scoped_refptr<media::DataBuffer> Read() override; void SetDeferred(bool defer) override; - // blink::WebAssociatedURLLoaderClient implementation. - bool WillFollowRedirect( - const blink::WebURL& new_url, - const blink::WebURLResponse& redirect_response) override; + // WebAssociatedURLLoaderClient implementation. + bool WillFollowRedirect(const WebURL& new_url, + const WebURLResponse& redirect_response) override; void DidSendData(uint64_t bytesSent, uint64_t totalBytesToBeSent) override; - void DidReceiveResponse(const blink::WebURLResponse& response) override; + void DidReceiveResponse(const WebURLResponse& response) override; void DidDownloadData(uint64_t data_length) override; void DidReceiveData(const char* data, int data_length) override; void DidFinishLoading() override; - void DidFail(const blink::WebURLError&) override; + void DidFail(const WebURLError&) override; // Use protected instead of private for testing purposes. protected: @@ -86,7 +85,7 @@ int64_t block_size() const; // If we have made a range request, verify the response from the server. - bool VerifyPartialResponse(const blink::WebURLResponse& response, + bool VerifyPartialResponse(const WebURLResponse& response, const scoped_refptr<UrlData>& url_data); // Current Position. @@ -114,7 +113,7 @@ // Keeps track of an active WebAssociatedURLLoader. // Only valid while loading resource. - std::unique_ptr<blink::WebAssociatedURLLoader> active_loader_; + std::unique_ptr<WebAssociatedURLLoader> active_loader_; // When we encounter a redirect, this is the source of the redirect. GURL redirects_to_;
diff --git a/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider_unittest.cc b/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider_unittest.cc index 1a9f727..e9dc878 100644 --- a/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider_unittest.cc +++ b/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider_unittest.cc
@@ -55,9 +55,9 @@ // Predicate that checks the Accept-Encoding request header and FRFR previews // state. static bool CorrectAcceptEncodingAndPreviewsState( - const blink::WebURLRequest& request) { + const WebURLRequest& request) { bool has_frfr = - request.GetPreviewsState() & blink::PreviewsTypes::kSrcVideoRedirectOn; + request.GetPreviewsState() & PreviewsTypes::kSrcVideoRedirectOn; if (has_frfr != want_frfr) { return false; } @@ -171,8 +171,8 @@ } void Redirect(const char* url) { - blink::WebURL new_url{GURL(url)}; - blink::WebURLResponse redirect_response(gurl_); + WebURL new_url{GURL(url)}; + WebURLResponse redirect_response(gurl_); EXPECT_CALL(*this, RedirectCallback(_)) .WillOnce( @@ -210,8 +210,8 @@ } protected: - std::unique_ptr<blink::WebAssociatedURLLoader> CreateUrlLoader( - const blink::WebAssociatedURLLoaderOptions& options) { + std::unique_ptr<WebAssociatedURLLoader> CreateUrlLoader( + const WebAssociatedURLLoaderOptions& options) { auto url_loader = std::make_unique<NiceMock<MockWebAssociatedURLLoader>>(); EXPECT_CALL(*url_loader.get(), LoadAsynchronously(Truly(CorrectAcceptEncodingAndPreviewsState), @@ -370,8 +370,7 @@ }; for (const TestCase& test_case : kTestCases) { SCOPED_TRACE(test_case.label); - blink::WebNetworkStateNotifier::SetSaveDataEnabled( - test_case.enable_save_data); + WebNetworkStateNotifier::SetSaveDataEnabled(test_case.enable_save_data); Initialize(test_case.url.c_str(), 0); want_frfr = test_case.want_frfr_previews_enabled;
diff --git a/third_party/blink/renderer/platform/media/testing/mock_resource_fetch_context.h b/third_party/blink/renderer/platform/media/testing/mock_resource_fetch_context.h index 23b0c69..90c312b 100644 --- a/third_party/blink/renderer/platform/media/testing/mock_resource_fetch_context.h +++ b/third_party/blink/renderer/platform/media/testing/mock_resource_fetch_context.h
@@ -18,8 +18,8 @@ ~MockResourceFetchContext() override; MOCK_METHOD1(CreateUrlLoader, - std::unique_ptr<blink::WebAssociatedURLLoader>( - const blink::WebAssociatedURLLoaderOptions&)); + std::unique_ptr<WebAssociatedURLLoader>( + const WebAssociatedURLLoaderOptions&)); }; } // namespace blink
diff --git a/third_party/blink/renderer/platform/media/testing/mock_web_associated_url_loader.h b/third_party/blink/renderer/platform/media/testing/mock_web_associated_url_loader.h index dd5bfb8..faef0ecb 100644 --- a/third_party/blink/renderer/platform/media/testing/mock_web_associated_url_loader.h +++ b/third_party/blink/renderer/platform/media/testing/mock_web_associated_url_loader.h
@@ -11,7 +11,7 @@ namespace blink { -class MockWebAssociatedURLLoader : public blink::WebAssociatedURLLoader { +class MockWebAssociatedURLLoader : public WebAssociatedURLLoader { public: MockWebAssociatedURLLoader(); MockWebAssociatedURLLoader(const MockWebAssociatedURLLoader&) = delete; @@ -20,8 +20,8 @@ ~MockWebAssociatedURLLoader() override; MOCK_METHOD2(LoadAsynchronously, - void(const blink::WebURLRequest& request, - blink::WebAssociatedURLLoaderClient* client)); + void(const WebURLRequest& request, + WebAssociatedURLLoaderClient* client)); MOCK_METHOD0(Cancel, void()); MOCK_METHOD1(SetDefersLoading, void(bool value)); MOCK_METHOD1(SetLoadingTaskRunner,
diff --git a/third_party/blink/renderer/platform/media/testing/test_response_generator.h b/third_party/blink/renderer/platform/media/testing/test_response_generator.h index c2ca2523..5152648 100644 --- a/third_party/blink/renderer/platform/media/testing/test_response_generator.h +++ b/third_party/blink/renderer/platform/media/testing/test_response_generator.h
@@ -31,44 +31,44 @@ TestResponseGenerator& operator=(const TestResponseGenerator&) = delete; // Generates a WebURLError object. - blink::WebURLError GenerateError(); + WebURLError GenerateError(); // Generates a regular HTTP 200 response. - blink::WebURLResponse Generate200(); + WebURLResponse Generate200(); // Generates a regular HTTP 206 response starting from |first_byte_offset| // until the end of the resource. - blink::WebURLResponse Generate206(int64_t first_byte_offset); + WebURLResponse Generate206(int64_t first_byte_offset); // Generates a custom HTTP 206 response starting from |first_byte_offset| // until the end of the resource. You can tweak what gets included in the // headers via |flags|. - blink::WebURLResponse Generate206(int64_t first_byte_offset, Flags flags); + WebURLResponse Generate206(int64_t first_byte_offset, Flags flags); // Generates a regular HTTP 206 response starting from |first_byte_offset| // until |last_byte_offset|. - blink::WebURLResponse GeneratePartial206(int64_t first_byte_offset, - int64_t last_byte_offset); + WebURLResponse GeneratePartial206(int64_t first_byte_offset, + int64_t last_byte_offset); // Generates a custom HTTP 206 response starting from |first_byte_offset| // until |last_byte_offset|. You can tweak what gets included in the // headers via |flags|. - blink::WebURLResponse GeneratePartial206(int64_t first_byte_offset, - int64_t last_byte_offset, - Flags flags); + WebURLResponse GeneratePartial206(int64_t first_byte_offset, + int64_t last_byte_offset, + Flags flags); // Generates a regular HTTP 404 response. - blink::WebURLResponse Generate404(); + WebURLResponse Generate404(); // Generate a HTTP response with specified code. - blink::WebURLResponse GenerateResponse(int code); + WebURLResponse GenerateResponse(int code); // Generates a file:// response starting from |first_byte_offset| until the // end of the resource. // // If |first_byte_offset| is negative a response containing no content length // will be returned. - blink::WebURLResponse GenerateFileResponse(int64_t first_byte_offset); + WebURLResponse GenerateFileResponse(int64_t first_byte_offset); int64_t content_length() { return content_length_; }
diff --git a/third_party/blink/renderer/platform/media/text_track_impl.cc b/third_party/blink/renderer/platform/media/text_track_impl.cc index 26939631..f6661c0 100644 --- a/third_party/blink/renderer/platform/media/text_track_impl.cc +++ b/third_party/blink/renderer/platform/media/text_track_impl.cc
@@ -18,7 +18,7 @@ TextTrackImpl::TextTrackImpl( const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, - blink::WebMediaPlayerClient* client, + WebMediaPlayerClient* client, std::unique_ptr<WebInbandTextTrackImpl> text_track) : task_runner_(task_runner), client_(client), @@ -48,16 +48,15 @@ const std::string& id, const std::string& content, const std::string& settings) { - if (blink::WebInbandTextTrackClient* client = text_track->Client()) { + if (WebInbandTextTrackClient* client = text_track->Client()) { client->AddWebVTTCue(start.InSecondsF(), end.InSecondsF(), - blink::WebString::FromUTF8(id), - blink::WebString::FromUTF8(content), - blink::WebString::FromUTF8(settings)); + WebString::FromUTF8(id), WebString::FromUTF8(content), + WebString::FromUTF8(settings)); } } void TextTrackImpl::OnRemoveTrack( - blink::WebMediaPlayerClient* client, + WebMediaPlayerClient* client, std::unique_ptr<WebInbandTextTrackImpl> text_track) { if (text_track->Client()) client->RemoveTextTrack(text_track.get());
diff --git a/third_party/blink/renderer/platform/media/text_track_impl.h b/third_party/blink/renderer/platform/media/text_track_impl.h index 14895bd..31bf37cf 100644 --- a/third_party/blink/renderer/platform/media/text_track_impl.h +++ b/third_party/blink/renderer/platform/media/text_track_impl.h
@@ -23,7 +23,7 @@ public: // Constructor assumes ownership of the |text_track| object. TextTrackImpl(const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, - blink::WebMediaPlayerClient* client, + WebMediaPlayerClient* client, std::unique_ptr<WebInbandTextTrackImpl> text_track); TextTrackImpl(const TextTrackImpl&) = delete; @@ -44,11 +44,11 @@ const std::string& content, const std::string& settings); - static void OnRemoveTrack(blink::WebMediaPlayerClient* client, + static void OnRemoveTrack(WebMediaPlayerClient* client, std::unique_ptr<WebInbandTextTrackImpl> text_track); scoped_refptr<base::SingleThreadTaskRunner> task_runner_; - blink::WebMediaPlayerClient* client_; + WebMediaPlayerClient* client_; std::unique_ptr<WebInbandTextTrackImpl> text_track_; };
diff --git a/third_party/blink/renderer/platform/media/video_frame_compositor.cc b/third_party/blink/renderer/platform/media/video_frame_compositor.cc index ad1bb0e..925ea37 100644 --- a/third_party/blink/renderer/platform/media/video_frame_compositor.cc +++ b/third_party/blink/renderer/platform/media/video_frame_compositor.cc
@@ -31,7 +31,7 @@ VideoFrameCompositor::VideoFrameCompositor( const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, - std::unique_ptr<blink::WebVideoFrameSubmitter> submitter) + std::unique_ptr<WebVideoFrameSubmitter> submitter) : task_runner_(task_runner), tick_clock_(base::DefaultTickClock::GetInstance()), background_rendering_timer_( @@ -313,10 +313,10 @@ submitter_->SetForceBeginFrames(false); } -std::unique_ptr<blink::WebMediaPlayer::VideoFramePresentationMetadata> +std::unique_ptr<WebMediaPlayer::VideoFramePresentationMetadata> VideoFrameCompositor::GetLastPresentedFrameMetadata() { auto frame_metadata = - std::make_unique<blink::WebMediaPlayer::VideoFramePresentationMetadata>(); + std::make_unique<WebMediaPlayer::VideoFramePresentationMetadata>(); scoped_refptr<media::VideoFrame> last_frame; {
diff --git a/third_party/blink/renderer/platform/media/video_frame_compositor_unittest.cc b/third_party/blink/renderer/platform/media/video_frame_compositor_unittest.cc index b63afd3..2c4c639 100644 --- a/third_party/blink/renderer/platform/media/video_frame_compositor_unittest.cc +++ b/third_party/blink/renderer/platform/media/video_frame_compositor_unittest.cc
@@ -31,9 +31,9 @@ using RenderingMode = ::media::VideoRendererSink::RenderCallback::RenderingMode; -class MockWebVideoFrameSubmitter : public blink::WebVideoFrameSubmitter { +class MockWebVideoFrameSubmitter : public WebVideoFrameSubmitter { public: - // blink::WebVideoFrameSubmitter implementation. + // WebVideoFrameSubmitter implementation. void StopUsingProvider() override {} MOCK_METHOD1(EnableSubmission, void(viz::SurfaceId)); MOCK_METHOD0(StartRendering, void());
diff --git a/third_party/blink/renderer/platform/media/watch_time_reporter_unittest.cc b/third_party/blink/renderer/platform/media/watch_time_reporter_unittest.cc index f09c75d..fddf4b96 100644 --- a/third_party/blink/renderer/platform/media/watch_time_reporter_unittest.cc +++ b/third_party/blink/renderer/platform/media/watch_time_reporter_unittest.cc
@@ -310,7 +310,7 @@ if (wtr_ && IsMonitoring()) EXPECT_WATCH_TIME_FINALIZED(); - wtr_ = std::make_unique<blink::WatchTimeReporter>( + wtr_ = std::make_unique<WatchTimeReporter>( media::mojom::PlaybackProperties::New( has_audio_, has_video_, false, false, is_mse, is_encrypted, false, media::mojom::MediaStreamType::kNone), @@ -319,8 +319,7 @@ base::Unretained(this)), base::BindRepeating(&WatchTimeReporterTest::GetPipelineStatistics, base::Unretained(this)), - &fake_metrics_provider_, - blink::scheduler::GetSequencedTaskRunnerForTesting(), + &fake_metrics_provider_, scheduler::GetSequencedTaskRunnerForTesting(), task_environment_.GetMockTickClock()); reporting_interval_ = wtr_->reporting_interval_; @@ -372,7 +371,7 @@ : wtr_->OnNativeControlsDisabled(); } - void OnDisplayTypeChanged(blink::DisplayType display_type) { + void OnDisplayTypeChanged(DisplayType display_type) { wtr_->OnDisplayTypeChanged(display_type); } @@ -443,7 +442,7 @@ if (TestFlags & kStartWithNativeControls) OnNativeControlsEnabled(true); if (TestFlags & kStartWithDisplayFullscreen) - OnDisplayTypeChanged(blink::DisplayType::kFullscreen); + OnDisplayTypeChanged(DisplayType::kFullscreen); // Setup all current time expectations first since they need to use the // InSequence macro for ease of use, but we don't want the watch time @@ -643,7 +642,7 @@ const bool has_audio_; FakeMediaMetricsProvider fake_metrics_provider_; - std::unique_ptr<blink::WatchTimeReporter> wtr_; + std::unique_ptr<WatchTimeReporter> wtr_; base::TimeDelta reporting_interval_; }; @@ -1444,7 +1443,7 @@ EXPECT_TRUE(IsBackgroundMonitoring()); EXPECT_FALSE(IsMonitoring()); - OnDisplayTypeChanged(blink::DisplayType::kFullscreen); + OnDisplayTypeChanged(DisplayType::kFullscreen); EXPECT_BACKGROUND_WATCH_TIME(Ac, kWatchTime1); EXPECT_BACKGROUND_WATCH_TIME(All, kWatchTime1); @@ -1578,7 +1577,7 @@ wtr_->OnPlaying(); EXPECT_TRUE(IsMonitoring()); - OnDisplayTypeChanged(blink::DisplayType::kFullscreen); + OnDisplayTypeChanged(DisplayType::kFullscreen); OnPowerStateChange(true); EXPECT_WATCH_TIME(Ac, kWatchTime1); @@ -1620,7 +1619,7 @@ OnNativeControlsEnabled(true); OnPowerStateChange(true); - OnDisplayTypeChanged(blink::DisplayType::kPictureInPicture); + OnDisplayTypeChanged(DisplayType::kPictureInPicture); EXPECT_WATCH_TIME(Ac, kWatchTime1); EXPECT_WATCH_TIME(All, kWatchTime1); @@ -1861,7 +1860,7 @@ .WillOnce(testing::Return(base::TimeDelta())) .WillOnce(testing::Return(kWatchTime)); Initialize(false, false, kSizeJustRight); - OnDisplayTypeChanged(blink::DisplayType::kFullscreen); + OnDisplayTypeChanged(DisplayType::kFullscreen); wtr_->OnPlaying(); SetOnBatteryPower(true); EXPECT_TRUE(IsMonitoring()); @@ -1879,7 +1878,7 @@ .WillOnce(testing::Return(kWatchTime)); Initialize(false, false, kSizeJustRight); OnNativeControlsEnabled(true); - OnDisplayTypeChanged(blink::DisplayType::kPictureInPicture); + OnDisplayTypeChanged(DisplayType::kPictureInPicture); wtr_->OnPlaying(); EXPECT_TRUE(IsMonitoring()); EXPECT_WATCH_TIME(Ac, kWatchTime); @@ -2010,8 +2009,8 @@ RunHysteresisTest<kAccumulationContinuesAfterTest | kFinalizeExitDoesNotRequireCurrentTime | kStartWithDisplayFullscreen>([this]() { - OnDisplayTypeChanged(blink::DisplayType::kInline); - OnDisplayTypeChanged(blink::DisplayType::kFullscreen); + OnDisplayTypeChanged(DisplayType::kInline); + OnDisplayTypeChanged(DisplayType::kFullscreen); }); } @@ -2019,15 +2018,15 @@ OnDisplayTypeChangeHysteresisNativeFinalized) { RunHysteresisTest<kAccumulationContinuesAfterTest | kFinalizeDisplayWatchTime | kStartWithDisplayFullscreen>( - [this]() { OnDisplayTypeChanged(blink::DisplayType::kInline); }); + [this]() { OnDisplayTypeChanged(DisplayType::kInline); }); } TEST_P(DisplayTypeWatchTimeReporterTest, OnDisplayTypeChangeHysteresisInlineContinuation) { RunHysteresisTest<kAccumulationContinuesAfterTest | kFinalizeExitDoesNotRequireCurrentTime>([this]() { - OnDisplayTypeChanged(blink::DisplayType::kFullscreen); - OnDisplayTypeChanged(blink::DisplayType::kInline); + OnDisplayTypeChanged(DisplayType::kFullscreen); + OnDisplayTypeChanged(DisplayType::kInline); }); } @@ -2035,7 +2034,7 @@ OnDisplayTypeChangeHysteresisNativeOffFinalized) { RunHysteresisTest<kAccumulationContinuesAfterTest | kFinalizeDisplayWatchTime>( - [this]() { OnDisplayTypeChanged(blink::DisplayType::kFullscreen); }); + [this]() { OnDisplayTypeChanged(DisplayType::kFullscreen); }); } TEST_P(DisplayTypeWatchTimeReporterTest, @@ -2043,14 +2042,14 @@ RunHysteresisTest<kAccumulationContinuesAfterTest | kFinalizeDisplayWatchTime | kStartWithDisplayFullscreen | kTransitionDisplayWatchTime>( - [this]() { OnDisplayTypeChanged(blink::DisplayType::kInline); }); + [this]() { OnDisplayTypeChanged(DisplayType::kInline); }); } TEST_P(DisplayTypeWatchTimeReporterTest, OnDisplayTypeChangeFullscreenToInline) { RunHysteresisTest<kAccumulationContinuesAfterTest | kFinalizeDisplayWatchTime | kTransitionDisplayWatchTime>( - [this]() { OnDisplayTypeChanged(blink::DisplayType::kFullscreen); }); + [this]() { OnDisplayTypeChanged(DisplayType::kFullscreen); }); } // Tests that the first finalize is the only one that matters. @@ -2345,7 +2344,7 @@ EXPECT_TRUE(IsMutedMonitoring()); EXPECT_FALSE(IsMonitoring()); - OnDisplayTypeChanged(blink::DisplayType::kFullscreen); + OnDisplayTypeChanged(DisplayType::kFullscreen); EXPECT_MUTED_WATCH_TIME_IF_AUDIO_VIDEO(Ac, kWatchTime1); EXPECT_MUTED_WATCH_TIME_IF_AUDIO_VIDEO(All, kWatchTime1); EXPECT_MUTED_WATCH_TIME_IF_AUDIO_VIDEO(Eme, kWatchTime1);
diff --git a/third_party/blink/renderer/platform/media/web_content_decryption_module_access_impl.cc b/third_party/blink/renderer/platform/media/web_content_decryption_module_access_impl.cc index 767f8518..c9c7ca5d 100644 --- a/third_party/blink/renderer/platform/media/web_content_decryption_module_access_impl.cc +++ b/third_party/blink/renderer/platform/media/web_content_decryption_module_access_impl.cc
@@ -17,15 +17,15 @@ // The caller owns the created cdm (passed back using |result|). static void CreateCdm( const base::WeakPtr<WebEncryptedMediaClientImpl>& client, - const blink::WebString& key_system, - const blink::WebSecurityOrigin& security_origin, + const WebString& key_system, + const WebSecurityOrigin& security_origin, const media::CdmConfig& cdm_config, - std::unique_ptr<blink::WebContentDecryptionModuleResult> result) { + std::unique_ptr<WebContentDecryptionModuleResult> result) { // If |client| is gone (due to the frame getting destroyed), it is // impossible to create the CDM, so fail. if (!client) { result->CompleteWithError( - blink::kWebContentDecryptionModuleExceptionInvalidStateError, 0, + kWebContentDecryptionModuleExceptionInvalidStateError, 0, "Failed to create CDM."); return; } @@ -36,15 +36,15 @@ // static WebContentDecryptionModuleAccessImpl* WebContentDecryptionModuleAccessImpl::From( - blink::WebContentDecryptionModuleAccess* cdm_access) { + WebContentDecryptionModuleAccess* cdm_access) { return static_cast<WebContentDecryptionModuleAccessImpl*>(cdm_access); } std::unique_ptr<WebContentDecryptionModuleAccessImpl> WebContentDecryptionModuleAccessImpl::Create( - const blink::WebString& key_system, - const blink::WebSecurityOrigin& security_origin, - const blink::WebMediaKeySystemConfiguration& configuration, + const WebString& key_system, + const WebSecurityOrigin& security_origin, + const WebMediaKeySystemConfiguration& configuration, const media::CdmConfig& cdm_config, const base::WeakPtr<WebEncryptedMediaClientImpl>& client) { return std::make_unique<WebContentDecryptionModuleAccessImpl>( @@ -52,9 +52,9 @@ } WebContentDecryptionModuleAccessImpl::WebContentDecryptionModuleAccessImpl( - const blink::WebString& key_system, - const blink::WebSecurityOrigin& security_origin, - const blink::WebMediaKeySystemConfiguration& configuration, + const WebString& key_system, + const WebSecurityOrigin& security_origin, + const WebMediaKeySystemConfiguration& configuration, const media::CdmConfig& cdm_config, const base::WeakPtr<WebEncryptedMediaClientImpl>& client) : key_system_(key_system), @@ -66,24 +66,24 @@ WebContentDecryptionModuleAccessImpl::~WebContentDecryptionModuleAccessImpl() = default; -blink::WebString WebContentDecryptionModuleAccessImpl::GetKeySystem() { +WebString WebContentDecryptionModuleAccessImpl::GetKeySystem() { return key_system_; } -blink::WebMediaKeySystemConfiguration +WebMediaKeySystemConfiguration WebContentDecryptionModuleAccessImpl::GetConfiguration() { return configuration_; } void WebContentDecryptionModuleAccessImpl::CreateContentDecryptionModule( - blink::WebContentDecryptionModuleResult result, + WebContentDecryptionModuleResult result, scoped_refptr<base::SingleThreadTaskRunner> task_runner) { // This method needs to run asynchronously, as it may need to load the CDM. // As this object's lifetime is controlled by MediaKeySystemAccess on the // blink side, copy all values needed by CreateCdm() in case the blink object // gets garbage-collected. - std::unique_ptr<blink::WebContentDecryptionModuleResult> result_copy( - new blink::WebContentDecryptionModuleResult(result)); + std::unique_ptr<WebContentDecryptionModuleResult> result_copy( + new WebContentDecryptionModuleResult(result)); task_runner->PostTask( FROM_HERE, base::BindOnce(&CreateCdm, client_, key_system_, security_origin_,
diff --git a/third_party/blink/renderer/platform/media/web_content_decryption_module_access_impl.h b/third_party/blink/renderer/platform/media/web_content_decryption_module_access_impl.h index 19b6d0e51..f985fb3 100644 --- a/third_party/blink/renderer/platform/media/web_content_decryption_module_access_impl.h +++ b/third_party/blink/renderer/platform/media/web_content_decryption_module_access_impl.h
@@ -20,22 +20,22 @@ class WebEncryptedMediaClientImpl; class PLATFORM_EXPORT WebContentDecryptionModuleAccessImpl - : public blink::WebContentDecryptionModuleAccess { + : public WebContentDecryptionModuleAccess { public: // Allow typecasting from blink type as this is the only implementation. static WebContentDecryptionModuleAccessImpl* From( - blink::WebContentDecryptionModuleAccess* cdm_access); + WebContentDecryptionModuleAccess* cdm_access); static std::unique_ptr<WebContentDecryptionModuleAccessImpl> Create( - const blink::WebString& key_system, - const blink::WebSecurityOrigin& security_origin, - const blink::WebMediaKeySystemConfiguration& configuration, + const WebString& key_system, + const WebSecurityOrigin& security_origin, + const WebMediaKeySystemConfiguration& configuration, const media::CdmConfig& cdm_config, const base::WeakPtr<WebEncryptedMediaClientImpl>& client); WebContentDecryptionModuleAccessImpl( - const blink::WebString& key_system, - const blink::WebSecurityOrigin& security_origin, - const blink::WebMediaKeySystemConfiguration& configuration, + const WebString& key_system, + const WebSecurityOrigin& security_origin, + const WebMediaKeySystemConfiguration& configuration, const media::CdmConfig& cdm_config, const base::WeakPtr<WebEncryptedMediaClientImpl>& client); WebContentDecryptionModuleAccessImpl( @@ -44,18 +44,18 @@ const WebContentDecryptionModuleAccessImpl&) = delete; ~WebContentDecryptionModuleAccessImpl() override; - // blink::WebContentDecryptionModuleAccess interface. - blink::WebString GetKeySystem() override; - blink::WebMediaKeySystemConfiguration GetConfiguration() override; + // WebContentDecryptionModuleAccess interface. + WebString GetKeySystem() override; + WebMediaKeySystemConfiguration GetConfiguration() override; void CreateContentDecryptionModule( - blink::WebContentDecryptionModuleResult result, + WebContentDecryptionModuleResult result, scoped_refptr<base::SingleThreadTaskRunner> task_runner) override; bool UseHardwareSecureCodecs() const override; private: - const blink::WebString key_system_; - const blink::WebSecurityOrigin security_origin_; - const blink::WebMediaKeySystemConfiguration configuration_; + const WebString key_system_; + const WebSecurityOrigin security_origin_; + const WebMediaKeySystemConfiguration configuration_; const media::CdmConfig cdm_config_; // Keep a WeakPtr as client is owned by render_frame_impl.
diff --git a/third_party/blink/renderer/platform/media/web_content_decryption_module_impl.cc b/third_party/blink/renderer/platform/media/web_content_decryption_module_impl.cc index ed555ae..8f8b523 100644 --- a/third_party/blink/renderer/platform/media/web_content_decryption_module_impl.cc +++ b/third_party/blink/renderer/platform/media/web_content_decryption_module_impl.cc
@@ -31,7 +31,7 @@ const char kSetServerCertificateUMAName[] = "SetServerCertificate"; const char kGetStatusForPolicyUMAName[] = "GetStatusForPolicy"; -bool ConvertHdcpVersion(const blink::WebString& hdcp_version_string, +bool ConvertHdcpVersion(const WebString& hdcp_version_string, media::HdcpVersion* hdcp_version) { if (!hdcp_version_string.ContainsOnlyASCII()) return false; @@ -71,7 +71,7 @@ void WebContentDecryptionModuleImpl::Create( media::CdmFactory* cdm_factory, const std::u16string& key_system, - const blink::WebSecurityOrigin& security_origin, + const WebSecurityOrigin& security_origin, const media::CdmConfig& cdm_config, WebCdmCreatedCB web_cdm_created_cb) { DCHECK(!security_origin.IsNull()); @@ -118,9 +118,9 @@ WebContentDecryptionModuleImpl::~WebContentDecryptionModuleImpl() = default; -std::unique_ptr<blink::WebContentDecryptionModuleSession> +std::unique_ptr<WebContentDecryptionModuleSession> WebContentDecryptionModuleImpl::CreateSession( - blink::WebEncryptedMediaSessionType session_type) { + WebEncryptedMediaSessionType session_type) { base::UmaHistogramEnumeration( adapter_->GetKeySystemUMAPrefix() + kCreateSessionSessionTypeUMAName, session_type); @@ -130,7 +130,7 @@ void WebContentDecryptionModuleImpl::SetServerCertificate( const uint8_t* server_certificate, size_t server_certificate_length, - blink::WebContentDecryptionModuleResult result) { + WebContentDecryptionModuleResult result) { DCHECK(server_certificate); adapter_->SetServerCertificate( std::vector<uint8_t>(server_certificate, @@ -141,13 +141,12 @@ } void WebContentDecryptionModuleImpl::GetStatusForPolicy( - const blink::WebString& min_hdcp_version_string, - blink::WebContentDecryptionModuleResult result) { + const WebString& min_hdcp_version_string, + WebContentDecryptionModuleResult result) { media::HdcpVersion min_hdcp_version; if (!ConvertHdcpVersion(min_hdcp_version_string, &min_hdcp_version)) { - result.CompleteWithError( - blink::kWebContentDecryptionModuleExceptionTypeError, 0, - "Invalid HDCP version"); + result.CompleteWithError(kWebContentDecryptionModuleExceptionTypeError, 0, + "Invalid HDCP version"); return; }
diff --git a/third_party/blink/renderer/platform/media/web_content_decryption_module_impl.h b/third_party/blink/renderer/platform/media/web_content_decryption_module_impl.h index 3797a1e..3d53d9f 100644 --- a/third_party/blink/renderer/platform/media/web_content_decryption_module_impl.h +++ b/third_party/blink/renderer/platform/media/web_content_decryption_module_impl.h
@@ -28,15 +28,15 @@ class WebSecurityOrigin; using WebCdmCreatedCB = - base::OnceCallback<void(blink::WebContentDecryptionModule* cdm, + base::OnceCallback<void(WebContentDecryptionModule* cdm, const std::string& error_message)>; class PLATFORM_EXPORT WebContentDecryptionModuleImpl - : public blink::WebContentDecryptionModule { + : public WebContentDecryptionModule { public: static void Create(media::CdmFactory* cdm_factory, const std::u16string& key_system, - const blink::WebSecurityOrigin& security_origin, + const WebSecurityOrigin& security_origin, const media::CdmConfig& cdm_config, WebCdmCreatedCB web_cdm_created_cb); @@ -46,16 +46,14 @@ const WebContentDecryptionModuleImpl&) = delete; ~WebContentDecryptionModuleImpl() override; - // blink::WebContentDecryptionModule implementation. - std::unique_ptr<blink::WebContentDecryptionModuleSession> CreateSession( - blink::WebEncryptedMediaSessionType session_type) override; - void SetServerCertificate( - const uint8_t* server_certificate, - size_t server_certificate_length, - blink::WebContentDecryptionModuleResult result) override; - void GetStatusForPolicy( - const blink::WebString& min_hdcp_version_string, - blink::WebContentDecryptionModuleResult result) override; + // WebContentDecryptionModule implementation. + std::unique_ptr<WebContentDecryptionModuleSession> CreateSession( + WebEncryptedMediaSessionType session_type) override; + void SetServerCertificate(const uint8_t* server_certificate, + size_t server_certificate_length, + WebContentDecryptionModuleResult result) override; + void GetStatusForPolicy(const WebString& min_hdcp_version_string, + WebContentDecryptionModuleResult result) override; std::unique_ptr<media::CdmContextRef> GetCdmContextRef(); @@ -75,7 +73,7 @@ // Allow typecasting from blink type as this is the only implementation. PLATFORM_EXPORT inline WebContentDecryptionModuleImpl* ToWebContentDecryptionModuleImpl( - blink::WebContentDecryptionModule* cdm) { + WebContentDecryptionModule* cdm) { return static_cast<WebContentDecryptionModuleImpl*>(cdm); }
diff --git a/third_party/blink/renderer/platform/media/web_content_decryption_module_session_impl.cc b/third_party/blink/renderer/platform/media/web_content_decryption_module_session_impl.cc index 9f6cb4f..b4e53f5 100644 --- a/third_party/blink/renderer/platform/media/web_content_decryption_module_session_impl.cc +++ b/third_party/blink/renderer/platform/media/web_content_decryption_module_session_impl.cc
@@ -43,13 +43,13 @@ const char kKeyStatusSystemCodeUMAName[] = "KeyStatusSystemCode"; media::CdmSessionType ConvertSessionType( - blink::WebEncryptedMediaSessionType session_type) { + WebEncryptedMediaSessionType session_type) { switch (session_type) { - case blink::WebEncryptedMediaSessionType::kTemporary: + case WebEncryptedMediaSessionType::kTemporary: return media::CdmSessionType::kTemporary; - case blink::WebEncryptedMediaSessionType::kPersistentLicense: + case WebEncryptedMediaSessionType::kPersistentLicense: return media::CdmSessionType::kPersistentLicense; - case blink::WebEncryptedMediaSessionType::kUnknown: + case WebEncryptedMediaSessionType::kUnknown: break; } @@ -116,7 +116,7 @@ return false; } -bool SanitizeSessionId(const blink::WebString& session_id, +bool SanitizeSessionId(const WebString& session_id, std::string* sanitized_session_id) { // The user agent should thoroughly validate the sessionId value before // passing it to the CDM. At a minimum, this should include checking that @@ -185,7 +185,7 @@ WebContentDecryptionModuleSessionImpl::WebContentDecryptionModuleSessionImpl( const scoped_refptr<CdmSessionAdapter>& adapter, - blink::WebEncryptedMediaSessionType session_type) + WebEncryptedMediaSessionType session_type) : adapter_(adapter), session_type_(ConvertSessionType(session_type)), has_close_been_called_(false), @@ -220,15 +220,15 @@ client_ = client; } -blink::WebString WebContentDecryptionModuleSessionImpl::SessionId() const { - return blink::WebString::FromUTF8(session_id_); +WebString WebContentDecryptionModuleSessionImpl::SessionId() const { + return WebString::FromUTF8(session_id_); } void WebContentDecryptionModuleSessionImpl::InitializeNewSession( media::EmeInitDataType eme_init_data_type, const unsigned char* init_data, size_t init_data_length, - blink::WebContentDecryptionModuleResult result) { + WebContentDecryptionModuleResult result) { DCHECK(init_data); DCHECK(session_id_.empty()); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); @@ -243,8 +243,8 @@ std::string message = "The initialization data type is not supported by the key system."; result.CompleteWithError( - blink::kWebContentDecryptionModuleExceptionNotSupportedError, 0, - blink::WebString::FromUTF8(message)); + kWebContentDecryptionModuleExceptionNotSupportedError, 0, + WebString::FromUTF8(message)); return; } @@ -267,9 +267,8 @@ std::string message; if (!SanitizeInitData(eme_init_data_type, init_data, init_data_length, &sanitized_init_data, &message)) { - result.CompleteWithError( - blink::kWebContentDecryptionModuleExceptionTypeError, 0, - blink::WebString::FromUTF8(message)); + result.CompleteWithError(kWebContentDecryptionModuleExceptionTypeError, 0, + WebString::FromUTF8(message)); return; } @@ -277,7 +276,7 @@ // NotSupportedError. if (sanitized_init_data.empty()) { result.CompleteWithError( - blink::kWebContentDecryptionModuleExceptionNotSupportedError, 0, + kWebContentDecryptionModuleExceptionNotSupportedError, 0, "No initialization data provided."); return; } @@ -305,8 +304,8 @@ } void WebContentDecryptionModuleSessionImpl::Load( - const blink::WebString& session_id, - blink::WebContentDecryptionModuleResult result) { + const WebString& session_id, + WebContentDecryptionModuleResult result) { DCHECK(!session_id.IsEmpty()); DCHECK(session_id_.empty()); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); @@ -321,9 +320,8 @@ // reject promise with a newly created TypeError. std::string sanitized_session_id; if (!SanitizeSessionId(session_id, &sanitized_session_id)) { - result.CompleteWithError( - blink::kWebContentDecryptionModuleExceptionTypeError, 0, - "Invalid session ID."); + result.CompleteWithError(kWebContentDecryptionModuleExceptionTypeError, 0, + "Invalid session ID."); return; } @@ -342,7 +340,7 @@ void WebContentDecryptionModuleSessionImpl::Update( const uint8_t* response, size_t response_length, - blink::WebContentDecryptionModuleResult result) { + WebContentDecryptionModuleResult result) { DCHECK(response); DCHECK(!session_id_.empty()); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); @@ -360,9 +358,8 @@ std::vector<uint8_t> sanitized_response; if (!SanitizeResponse(adapter_->GetKeySystem(), response, response_length, &sanitized_response)) { - result.CompleteWithError( - blink::kWebContentDecryptionModuleExceptionTypeError, 0, - "Invalid response."); + result.CompleteWithError(kWebContentDecryptionModuleExceptionTypeError, 0, + "Invalid response."); return; } @@ -373,7 +370,7 @@ } void WebContentDecryptionModuleSessionImpl::Close( - blink::WebContentDecryptionModuleResult result) { + WebContentDecryptionModuleResult result) { DCHECK(!session_id_.empty()); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); @@ -395,7 +392,7 @@ } void WebContentDecryptionModuleSessionImpl::Remove( - blink::WebContentDecryptionModuleResult result) { + WebContentDecryptionModuleResult result) { DCHECK(!session_id_.empty()); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); @@ -417,12 +414,11 @@ bool has_additional_usable_key, media::CdmKeysInfo keys_info) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - blink::WebVector<blink::WebEncryptedMediaKeyInformation> keys( - keys_info.size()); + WebVector<WebEncryptedMediaKeyInformation> keys(keys_info.size()); for (size_t i = 0; i < keys_info.size(); ++i) { auto& key_info = keys_info[i]; - keys[i].SetId(blink::WebData(reinterpret_cast<char*>(&key_info->key_id[0]), - key_info->key_id.size())); + keys[i].SetId(WebData(reinterpret_cast<char*>(&key_info->key_id[0]), + key_info->key_id.size())); keys[i].SetStatus(ConvertCdmKeyStatus(key_info->status)); keys[i].SetSystemCode(key_info->system_code);
diff --git a/third_party/blink/renderer/platform/media/web_content_decryption_module_session_impl.h b/third_party/blink/renderer/platform/media/web_content_decryption_module_session_impl.h index 694b1bf..8586a5d9e 100644 --- a/third_party/blink/renderer/platform/media/web_content_decryption_module_session_impl.h +++ b/third_party/blink/renderer/platform/media/web_content_decryption_module_session_impl.h
@@ -25,33 +25,32 @@ class CdmSessionAdapter; class PLATFORM_EXPORT WebContentDecryptionModuleSessionImpl - : public blink::WebContentDecryptionModuleSession { + : public WebContentDecryptionModuleSession { public: WebContentDecryptionModuleSessionImpl( const scoped_refptr<CdmSessionAdapter>& adapter, - blink::WebEncryptedMediaSessionType session_type); + WebEncryptedMediaSessionType session_type); WebContentDecryptionModuleSessionImpl( const WebContentDecryptionModuleSessionImpl&) = delete; WebContentDecryptionModuleSessionImpl& operator=( const WebContentDecryptionModuleSessionImpl&) = delete; ~WebContentDecryptionModuleSessionImpl() override; - // blink::WebContentDecryptionModuleSession implementation. + // WebContentDecryptionModuleSession implementation. void SetClientInterface(Client* client) override; - blink::WebString SessionId() const override; + WebString SessionId() const override; - void InitializeNewSession( - media::EmeInitDataType init_data_type, - const unsigned char* initData, - size_t initDataLength, - blink::WebContentDecryptionModuleResult result) override; - void Load(const blink::WebString& session_id, - blink::WebContentDecryptionModuleResult result) override; + void InitializeNewSession(media::EmeInitDataType init_data_type, + const unsigned char* initData, + size_t initDataLength, + WebContentDecryptionModuleResult result) override; + void Load(const WebString& session_id, + WebContentDecryptionModuleResult result) override; void Update(const uint8_t* response, size_t response_length, - blink::WebContentDecryptionModuleResult result) override; - void Close(blink::WebContentDecryptionModuleResult result) override; - void Remove(blink::WebContentDecryptionModuleResult result) override; + WebContentDecryptionModuleResult result) override; + void Close(WebContentDecryptionModuleResult result) override; + void Remove(WebContentDecryptionModuleResult result) override; // Callbacks. void OnSessionMessage(media::CdmMessageType message_type,
diff --git a/third_party/blink/renderer/platform/media/web_encrypted_media_client_impl.cc b/third_party/blink/renderer/platform/media/web_encrypted_media_client_impl.cc index bc50a8511..a2602ab 100644 --- a/third_party/blink/renderer/platform/media/web_encrypted_media_client_impl.cc +++ b/third_party/blink/renderer/platform/media/web_encrypted_media_client_impl.cc
@@ -28,18 +28,18 @@ const char kKeySystemSupportUMAPrefix[] = "Media.EME.RequestMediaKeySystemAccess."; -// A helper function to complete blink::WebContentDecryptionModuleResult. Used -// to convert blink::WebContentDecryptionModuleResult to a callback. +// A helper function to complete WebContentDecryptionModuleResult. Used +// to convert WebContentDecryptionModuleResult to a callback. void CompleteWebContentDecryptionModuleResult( - std::unique_ptr<blink::WebContentDecryptionModuleResult> result, - blink::WebContentDecryptionModule* cdm, + std::unique_ptr<WebContentDecryptionModuleResult> result, + WebContentDecryptionModule* cdm, const std::string& error_message) { DCHECK(result); if (!cdm) { result->CompleteWithError( - blink::kWebContentDecryptionModuleExceptionNotSupportedError, 0, - blink::WebString::FromUTF8(error_message)); + kWebContentDecryptionModuleExceptionNotSupportedError, 0, + WebString::FromUTF8(error_message)); return; } @@ -109,7 +109,7 @@ WebEncryptedMediaClientImpl::~WebEncryptedMediaClientImpl() = default; void WebEncryptedMediaClientImpl::RequestMediaKeySystemAccess( - blink::WebEncryptedMediaRequest request) { + WebEncryptedMediaRequest request) { GetReporter(request.KeySystem())->ReportRequested(); key_system_config_selector_.SelectConfig( @@ -119,10 +119,10 @@ } void WebEncryptedMediaClientImpl::CreateCdm( - const blink::WebString& key_system, - const blink::WebSecurityOrigin& security_origin, + const WebString& key_system, + const WebSecurityOrigin& security_origin, const media::CdmConfig& cdm_config, - std::unique_ptr<blink::WebContentDecryptionModuleResult> result) { + std::unique_ptr<WebContentDecryptionModuleResult> result) { WebContentDecryptionModuleImpl::Create( cdm_factory_, key_system.Utf16(), security_origin, cdm_config, base::BindOnce(&CompleteWebContentDecryptionModuleResult, @@ -130,9 +130,9 @@ } void WebEncryptedMediaClientImpl::OnConfigSelected( - blink::WebEncryptedMediaRequest request, + WebEncryptedMediaRequest request, KeySystemConfigSelector::Status status, - blink::WebMediaKeySystemConfiguration* accumulated_configuration, + WebMediaKeySystemConfiguration* accumulated_configuration, media::CdmConfig* cdm_config) { // Update encrypted_media_supported_types_browsertest.cc if updating these // strings. @@ -159,7 +159,7 @@ // requestMediaKeySystemAccess request succeeding. However, the blink // objects may have been cleared, so check if this is the case and simply // reject the request. - blink::WebSecurityOrigin origin = request.GetSecurityOrigin(); + WebSecurityOrigin origin = request.GetSecurityOrigin(); if (origin.IsNull()) { request.RequestNotSupported("Unable to create MediaKeySystemAccess"); return; @@ -171,7 +171,7 @@ } WebEncryptedMediaClientImpl::Reporter* WebEncryptedMediaClientImpl::GetReporter( - const blink::WebString& key_system) { + const WebString& key_system) { // Assumes that empty will not be found by GetKeySystemNameForUMA(). // TODO(sandersd): Avoid doing ASCII conversion more than once. std::string key_system_ascii;
diff --git a/third_party/blink/renderer/platform/media/web_inband_text_track_impl.cc b/third_party/blink/renderer/platform/media/web_inband_text_track_impl.cc index d5d79bd..4aa2c060 100644 --- a/third_party/blink/renderer/platform/media/web_inband_text_track_impl.cc +++ b/third_party/blink/renderer/platform/media/web_inband_text_track_impl.cc
@@ -9,9 +9,9 @@ namespace blink { WebInbandTextTrackImpl::WebInbandTextTrackImpl(Kind kind, - const blink::WebString& label, - const blink::WebString& language, - const blink::WebString& id) + const WebString& label, + const WebString& language, + const WebString& id) : client_(nullptr), kind_(kind), label_(label), @@ -22,12 +22,11 @@ DCHECK(!client_); } -void WebInbandTextTrackImpl::SetClient( - blink::WebInbandTextTrackClient* client) { +void WebInbandTextTrackImpl::SetClient(WebInbandTextTrackClient* client) { client_ = client; } -blink::WebInbandTextTrackClient* WebInbandTextTrackImpl::Client() { +WebInbandTextTrackClient* WebInbandTextTrackImpl::Client() { return client_; } @@ -35,15 +34,15 @@ return kind_; } -blink::WebString WebInbandTextTrackImpl::Label() const { +WebString WebInbandTextTrackImpl::Label() const { return label_; } -blink::WebString WebInbandTextTrackImpl::Language() const { +WebString WebInbandTextTrackImpl::Language() const { return language_; } -blink::WebString WebInbandTextTrackImpl::Id() const { +WebString WebInbandTextTrackImpl::Id() const { return id_; }
diff --git a/third_party/blink/renderer/platform/media/web_inband_text_track_impl.h b/third_party/blink/renderer/platform/media/web_inband_text_track_impl.h index d697458..2612809 100644 --- a/third_party/blink/renderer/platform/media/web_inband_text_track_impl.h +++ b/third_party/blink/renderer/platform/media/web_inband_text_track_impl.h
@@ -11,32 +11,31 @@ namespace blink { -class PLATFORM_EXPORT WebInbandTextTrackImpl - : public blink::WebInbandTextTrack { +class PLATFORM_EXPORT WebInbandTextTrackImpl : public WebInbandTextTrack { public: WebInbandTextTrackImpl(Kind kind, - const blink::WebString& label, - const blink::WebString& language, - const blink::WebString& id); + const WebString& label, + const WebString& language, + const WebString& id); WebInbandTextTrackImpl(const WebInbandTextTrackImpl&) = delete; WebInbandTextTrackImpl& operator=(const WebInbandTextTrackImpl&) = delete; ~WebInbandTextTrackImpl() override; - void SetClient(blink::WebInbandTextTrackClient* client) override; - blink::WebInbandTextTrackClient* Client() override; + void SetClient(WebInbandTextTrackClient* client) override; + WebInbandTextTrackClient* Client() override; Kind GetKind() const override; - blink::WebString Label() const override; - blink::WebString Language() const override; - blink::WebString Id() const override; + WebString Label() const override; + WebString Language() const override; + WebString Id() const override; private: - blink::WebInbandTextTrackClient* client_; + WebInbandTextTrackClient* client_; Kind kind_; - blink::WebString label_; - blink::WebString language_; - blink::WebString id_; + WebString label_; + WebString language_; + WebString id_; }; } // namespace blink
diff --git a/third_party/blink/renderer/platform/media/web_media_player_impl.cc b/third_party/blink/renderer/platform/media/web_media_player_impl.cc index 3ececbd..1811469 100644 --- a/third_party/blink/renderer/platform/media/web_media_player_impl.cc +++ b/third_party/blink/renderer/platform/media/web_media_player_impl.cc
@@ -109,10 +109,9 @@ UMA_HISTOGRAM_ENUMERATION(kWatchTimeHistogram, type); } -void SetSinkIdOnMediaThread( - scoped_refptr<blink::WebAudioSourceProviderImpl> sink, - const std::string& device_id, - media::OutputDeviceStatusCB callback) { +void SetSinkIdOnMediaThread(scoped_refptr<WebAudioSourceProviderImpl> sink, + const std::string& device_id, + media::OutputDeviceStatusCB callback) { sink->SwitchOutputDevice(device_id, std::move(callback)); } @@ -132,11 +131,11 @@ return base::FeatureList::IsEnabled(media::kBackgroundVideoPauseOptimization); } -bool IsNetworkStateError(blink::WebMediaPlayer::NetworkState state) { - bool result = state == blink::WebMediaPlayer::kNetworkStateFormatError || - state == blink::WebMediaPlayer::kNetworkStateNetworkError || - state == blink::WebMediaPlayer::kNetworkStateDecodeError; - DCHECK_EQ(state > blink::WebMediaPlayer::kNetworkStateLoaded, result); +bool IsNetworkStateError(WebMediaPlayer::NetworkState state) { + bool result = state == WebMediaPlayer::kNetworkStateFormatError || + state == WebMediaPlayer::kNetworkStateNetworkError || + state == WebMediaPlayer::kNetworkStateDecodeError; + DCHECK_EQ(state > WebMediaPlayer::kNetworkStateLoaded, result); return result; } @@ -171,11 +170,11 @@ case media::MediaObserverClient::ReasonToSwitchToLocal::PIPELINE_ERROR: return IDS_MEDIA_REMOTING_STOP_BY_ERROR_TEXT; case media::MediaObserverClient::ReasonToSwitchToLocal::ROUTE_TERMINATED: - return blink::WebMediaPlayerClient::kMediaRemotingStopNoText; + return WebMediaPlayerClient::kMediaRemotingStopNoText; } NOTREACHED(); // To suppress compiler warning on Windows. - return blink::WebMediaPlayerClient::kMediaRemotingStopNoText; + return WebMediaPlayerClient::kMediaRemotingStopNoText; } // These values are persisted to UMA. Entries should not be renumbered and @@ -215,7 +214,7 @@ std::unique_ptr<media::CdmContextRef> cdm_context_2, std::unique_ptr<media::MediaLog> media_log, std::unique_ptr<media::RendererFactorySelector> renderer_factory_selector, - std::unique_ptr<blink::WebSurfaceLayerBridge> bridge, + std::unique_ptr<WebSurfaceLayerBridge> bridge, bool is_chunk_demuxer) { // We release |bridge| after pipeline stop to ensure layout tests receive // painted video frames before test harness exit. @@ -267,7 +266,7 @@ std::move(media_log))); } -std::string SanitizeUserStringProperty(blink::WebString value) { +std::string SanitizeUserStringProperty(WebString value) { std::string converted = value.Utf8(); return base::IsStringUTF8(converted) ? converted : "[invalid property]"; } @@ -338,17 +337,16 @@ UrlData::CORS_USE_CREDENTIALS); WebMediaPlayerImpl::WebMediaPlayerImpl( - blink::WebLocalFrame* frame, - blink::WebMediaPlayerClient* client, - blink::WebMediaPlayerEncryptedMediaClient* encrypted_client, - blink::WebMediaPlayerDelegate* delegate, + WebLocalFrame* frame, + WebMediaPlayerClient* client, + WebMediaPlayerEncryptedMediaClient* encrypted_client, + WebMediaPlayerDelegate* delegate, std::unique_ptr<media::RendererFactorySelector> renderer_factory_selector, UrlIndex* url_index, std::unique_ptr<VideoFrameCompositor> compositor, std::unique_ptr<WebMediaPlayerParams> params) : frame_(frame), - main_task_runner_( - frame->GetTaskRunner(blink::TaskType::kMediaElementEvent)), + main_task_runner_(frame->GetTaskRunner(TaskType::kMediaElementEvent)), media_task_runner_(params->media_task_runner()), worker_task_runner_(params->worker_task_runner()), media_log_(params->take_media_log()), @@ -445,7 +443,7 @@ auto on_audio_source_provider_set_client_callback = base::BindOnce( [](base::WeakPtr<WebMediaPlayerImpl> self, - blink::WebMediaPlayerClient* const client) { + WebMediaPlayerClient* const client) { if (!self) return; client->DidDisableAudioOutputSinkChanges(); @@ -454,7 +452,7 @@ // TODO(xhwang): When we use an external Renderer, many methods won't work, // e.g. GetCurrentFrameFromCompositor(). See http://crbug.com/434861 - audio_source_provider_ = new blink::WebAudioSourceProviderImpl( + audio_source_provider_ = new WebAudioSourceProviderImpl( params->audio_renderer_sink(), media_log_.get(), std::move(on_audio_source_provider_set_client_callback)); @@ -462,7 +460,7 @@ observer_->SetClient(this); memory_usage_reporting_timer_.SetTaskRunner( - frame_->GetTaskRunner(blink::TaskType::kInternalMedia)); + frame_->GetTaskRunner(TaskType::kInternalMedia)); main_thread_mem_dumper_ = std::make_unique<media::MemoryDumpProviderProxy>( "WebMediaPlayer_MainThread", main_task_runner_, @@ -522,8 +520,7 @@ // Destruct compositor resources in the proper order. client_->SetCcLayer(nullptr); - client_->MediaRemotingStopped( - blink::WebMediaPlayerClient::kMediaRemotingStopNoText); + client_->MediaRemotingStopped(WebMediaPlayerClient::kMediaRemotingStopNoText); if (!surface_layer_for_video_enabled_ && video_layer_) video_layer_->StopUsingProvider(); @@ -567,12 +564,12 @@ WebMediaPlayer::LoadTiming WebMediaPlayerImpl::Load( LoadType load_type, - const blink::WebMediaPlayerSource& source, + const WebMediaPlayerSource& source, CorsMode cors_mode, bool is_cache_disabled) { // Only URL or MSE blob URL is supported. DCHECK(source.IsURL()); - blink::WebURL url = source.GetAsURL(); + WebURL url = source.GetAsURL(); DVLOG(1) << __func__ << "(" << load_type << ", " << GURL(url) << ", " << cors_mode << ")"; @@ -684,13 +681,13 @@ } void WebMediaPlayerImpl::SetIsEffectivelyFullscreen( - blink::WebFullscreenVideoStatus fullscreen_video_status) { + WebFullscreenVideoStatus fullscreen_video_status) { if (power_status_helper_) { // We don't care about pip, so anything that's "not fullscreen" is good // enough for us. power_status_helper_->SetIsFullscreen( fullscreen_video_status != - blink::WebFullscreenVideoStatus::kNotEffectivelyFullscreen); + WebFullscreenVideoStatus::kNotEffectivelyFullscreen); } } @@ -704,26 +701,26 @@ watch_time_reporter_->OnNativeControlsDisabled(); } -void WebMediaPlayerImpl::OnDisplayTypeChanged(blink::DisplayType display_type) { +void WebMediaPlayerImpl::OnDisplayTypeChanged(DisplayType display_type) { if (surface_layer_for_video_enabled_) { vfc_task_runner_->PostTask( FROM_HERE, base::BindOnce(&VideoFrameCompositor::SetForceSubmit, base::Unretained(compositor_.get()), - display_type == blink::DisplayType::kPictureInPicture)); + display_type == DisplayType::kPictureInPicture)); } if (!watch_time_reporter_) return; switch (display_type) { - case blink::DisplayType::kInline: + case DisplayType::kInline: watch_time_reporter_->OnDisplayTypeInline(); break; - case blink::DisplayType::kFullscreen: + case DisplayType::kFullscreen: watch_time_reporter_->OnDisplayTypeFullscreen(); break; - case blink::DisplayType::kPictureInPicture: + case DisplayType::kPictureInPicture: watch_time_reporter_->OnDisplayTypePictureInPicture(); // Resumes playback if it was paused when hidden. @@ -736,7 +733,7 @@ } void WebMediaPlayerImpl::DoLoad(LoadType load_type, - const blink::WebURL& url, + const WebURL& url, CorsMode cors_mode, bool is_cache_disabled) { TRACE_EVENT1("media", "WebMediaPlayerImpl::DoLoad", "id", media_log_->id()); @@ -796,7 +793,7 @@ media_metrics_provider_->Initialize( load_type == kLoadTypeMediaSource, - load_type == kLoadTypeURL ? blink::GetMediaURLScheme(loaded_url_) + load_type == kLoadTypeURL ? GetMediaURLScheme(loaded_url_) : media::mojom::MediaURLScheme::kUnknown, media::mojom::MediaStreamType::kNone); @@ -1081,8 +1078,8 @@ } bool WebMediaPlayerImpl::SetSinkId( - const blink::WebString& sink_id, - blink::WebSetSinkIdCompleteCallback completion_callback) { + const WebString& sink_id, + WebSetSinkIdCompleteCallback completion_callback) { DCHECK(main_task_runner_->BelongsToCurrentThread()); DVLOG(1) << __func__; @@ -1122,7 +1119,7 @@ } void WebMediaPlayerImpl::EnabledAudioTracksChanged( - const blink::WebVector<blink::WebMediaPlayer::TrackId>& enabledTrackIds) { + const WebVector<WebMediaPlayer::TrackId>& enabledTrackIds) { DCHECK(main_task_runner_->BelongsToCurrentThread()); std::ostringstream logstr; @@ -1138,7 +1135,7 @@ } void WebMediaPlayerImpl::SelectedVideoTrackChanged( - blink::WebMediaPlayer::TrackId* selectedTrackId) { + WebMediaPlayer::TrackId* selectedTrackId) { DCHECK(main_task_runner_->BelongsToCurrentThread()); absl::optional<MediaTrack::Id> selected_video_track_id; @@ -1262,17 +1259,17 @@ return ready_state_; } -blink::WebMediaPlayer::SurfaceLayerMode -WebMediaPlayerImpl::GetVideoSurfaceLayerMode() const { +WebMediaPlayer::SurfaceLayerMode WebMediaPlayerImpl::GetVideoSurfaceLayerMode() + const { return surface_layer_mode_; } -blink::WebString WebMediaPlayerImpl::GetErrorMessage() const { +WebString WebMediaPlayerImpl::GetErrorMessage() const { DCHECK(main_task_runner_->BelongsToCurrentThread()); - return blink::WebString::FromUTF8(media_log_->GetErrorMessage()); + return WebString::FromUTF8(media_log_->GetErrorMessage()); } -blink::WebTimeRanges WebMediaPlayerImpl::Buffered() const { +WebTimeRanges WebMediaPlayerImpl::Buffered() const { DCHECK(main_task_runner_->BelongsToCurrentThread()); media::Ranges<base::TimeDelta> buffered_time_ranges = @@ -1283,14 +1280,14 @@ buffered_data_source_host_->AddBufferedTimeRanges(&buffered_time_ranges, duration); } - return blink::ConvertToWebTimeRanges(buffered_time_ranges); + return ConvertToWebTimeRanges(buffered_time_ranges); } -blink::WebTimeRanges WebMediaPlayerImpl::Seekable() const { +WebTimeRanges WebMediaPlayerImpl::Seekable() const { DCHECK(main_task_runner_->BelongsToCurrentThread()); if (ready_state_ < WebMediaPlayer::kReadyStateHaveMetadata) - return blink::WebTimeRanges(); + return WebTimeRanges(); const double seekable_end = Duration(); @@ -1308,9 +1305,9 @@ // TODO(dalecurtis): Technically this allows seeking on media which return an // infinite duration so long as DataSource::IsStreaming() is false. While not // expected, disabling this breaks semi-live players, http://crbug.com/427412. - const blink::WebTimeRange seekable_range( - 0.0, force_seeks_to_zero ? 0.0 : seekable_end); - return blink::WebTimeRanges(&seekable_range, 1); + const WebTimeRange seekable_range(0.0, + force_seeks_to_zero ? 0.0 : seekable_end); + return WebTimeRanges(&seekable_range, 1); } bool WebMediaPlayerImpl::IsPrerollAttemptNeeded() { @@ -1436,8 +1433,8 @@ } void WebMediaPlayerImpl::SetContentDecryptionModule( - blink::WebContentDecryptionModule* cdm, - blink::WebContentDecryptionModuleResult result) { + WebContentDecryptionModule* cdm, + WebContentDecryptionModuleResult result) { DVLOG(1) << __func__ << ": cdm = " << cdm; DCHECK(main_task_runner_->BelongsToCurrentThread()); @@ -1446,7 +1443,7 @@ // http://crbug.com/462365#c7. if (!cdm) { result.CompleteWithError( - blink::kWebContentDecryptionModuleExceptionInvalidStateError, 0, + kWebContentDecryptionModuleExceptionInvalidStateError, 0, "The existing ContentDecryptionModule object cannot be removed at this " "time."); return; @@ -1457,8 +1454,7 @@ // on the wrong thread in some failure conditions. Blink should prevent // multiple simultaneous calls. DCHECK(!set_cdm_result_); - set_cdm_result_ = - std::make_unique<blink::WebContentDecryptionModuleResult>(result); + set_cdm_result_ = std::make_unique<WebContentDecryptionModuleResult>(result); SetCdmInternal(cdm); } @@ -1503,20 +1499,18 @@ bool is_first_video_track = true; for (const auto& track : tracks->tracks()) { if (track->type() == MediaTrack::Audio) { - client_->AddAudioTrack( - blink::WebString::FromUTF8(track->id().value()), - blink::WebMediaPlayerClient::kAudioTrackKindMain, - blink::WebString::FromUTF8(track->label().value()), - blink::WebString::FromUTF8(track->language().value()), - is_first_audio_track); + client_->AddAudioTrack(WebString::FromUTF8(track->id().value()), + WebMediaPlayerClient::kAudioTrackKindMain, + WebString::FromUTF8(track->label().value()), + WebString::FromUTF8(track->language().value()), + is_first_audio_track); is_first_audio_track = false; } else if (track->type() == MediaTrack::Video) { - client_->AddVideoTrack( - blink::WebString::FromUTF8(track->id().value()), - blink::WebMediaPlayerClient::kVideoTrackKindMain, - blink::WebString::FromUTF8(track->label().value()), - blink::WebString::FromUTF8(track->language().value()), - is_first_video_track); + client_->AddVideoTrack(WebString::FromUTF8(track->id().value()), + WebMediaPlayerClient::kVideoTrackKindMain, + WebString::FromUTF8(track->label().value()), + WebString::FromUTF8(track->language().value()), + is_first_video_track); is_first_video_track = false; } else { // Text tracks are not supported through this code path yet. @@ -1525,8 +1519,7 @@ } } -void WebMediaPlayerImpl::SetCdmInternal( - blink::WebContentDecryptionModule* cdm) { +void WebMediaPlayerImpl::SetCdmInternal(WebContentDecryptionModule* cdm) { DCHECK(main_task_runner_->BelongsToCurrentThread()); DCHECK(cdm); @@ -1596,7 +1589,7 @@ pending_cdm_context_ref_.reset(); if (set_cdm_result_) { set_cdm_result_->CompleteWithError( - blink::kWebContentDecryptionModuleExceptionNotSupportedError, 0, + kWebContentDecryptionModuleExceptionNotSupportedError, 0, "Unable to set ContentDecryptionModule object"); set_cdm_result_.reset(); } @@ -1870,7 +1863,7 @@ // be considered a format error. SetNetworkState(WebMediaPlayer::kNetworkStateFormatError); } else { - SetNetworkState(blink::PipelineErrorToNetworkState(status)); + SetNetworkState(PipelineErrorToNetworkState(status)); } // PipelineController::Stop() is idempotent. @@ -1943,8 +1936,7 @@ DisableOverlay(); } - if (surface_layer_mode_ == - blink::WebMediaPlayer::SurfaceLayerMode::kAlways) { + if (surface_layer_mode_ == WebMediaPlayer::SurfaceLayerMode::kAlways) { ActivateSurfaceLayerForVideo(); } else { DCHECK(!video_layer_); @@ -2083,7 +2075,7 @@ base::Unretained(this)), pipeline_metadata_.video_decoder_config.profile(), pipeline_metadata_.natural_size, key_system_, cdm_config_, - frame_->GetTaskRunner(blink::TaskType::kInternalMedia)); + frame_->GetTaskRunner(TaskType::kInternalMedia)); if (delegate_->IsFrameHidden()) video_decode_stats_reporter_->OnHidden(); @@ -2270,10 +2262,9 @@ const WebInbandTextTrackImpl::Kind web_kind = static_cast<WebInbandTextTrackImpl::Kind>(config.kind()); - const blink::WebString web_label = blink::WebString::FromUTF8(config.label()); - const blink::WebString web_language = - blink::WebString::FromUTF8(config.language()); - const blink::WebString web_id = blink::WebString::FromUTF8(config.id()); + const WebString web_label = WebString::FromUTF8(config.label()); + const WebString web_language = WebString::FromUTF8(config.language()); + const WebString web_id = WebString::FromUTF8(config.id()); std::unique_ptr<WebInbandTextTrackImpl> web_inband_text_track( new WebInbandTextTrackImpl(web_kind, web_label, web_language, web_id)); @@ -2615,7 +2606,7 @@ } #endif // defined(OS_ANDROID) -void WebMediaPlayerImpl::SetPoster(const blink::WebURL& poster) { +void WebMediaPlayerImpl::SetPoster(const WebURL& poster) { has_poster_ = !poster.IsEmpty(); } @@ -2913,7 +2904,7 @@ client_->ReadyStateChanged(); } -scoped_refptr<blink::WebAudioSourceProviderImpl> +scoped_refptr<WebAudioSourceProviderImpl> WebMediaPlayerImpl::GetAudioSourceProvider() { return audio_source_provider_; } @@ -3337,8 +3328,7 @@ // Idle timeout chosen arbitrarily. background_pause_timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(5), - client_, - &blink::WebMediaPlayerClient::PausePlayback); + client_, &WebMediaPlayerClient::PausePlayback); } void WebMediaPlayerImpl::CreateWatchTimeReporter() { @@ -3353,7 +3343,7 @@ } // Create the watch time reporter and synchronize its initial state. - watch_time_reporter_ = std::make_unique<blink::WatchTimeReporter>( + watch_time_reporter_ = std::make_unique<WatchTimeReporter>( media::mojom::PlaybackProperties::New( pipeline_metadata_.has_audio, has_video, false, false, !!chunk_demuxer_, is_encrypted_, embedded_media_experience_enabled_, @@ -3364,7 +3354,7 @@ base::BindRepeating(&WebMediaPlayerImpl::GetPipelineStatistics, base::Unretained(this)), media_metrics_provider_.get(), - frame_->GetTaskRunner(blink::TaskType::kInternalMedia)); + frame_->GetTaskRunner(TaskType::kInternalMedia)); watch_time_reporter_->OnVolumeChange(volume_); watch_time_reporter_->OnDurationChanged(GetPipelineMediaDuration()); @@ -3379,13 +3369,13 @@ watch_time_reporter_->OnNativeControlsDisabled(); switch (client_->GetDisplayType()) { - case blink::DisplayType::kInline: + case DisplayType::kInline: watch_time_reporter_->OnDisplayTypeInline(); break; - case blink::DisplayType::kFullscreen: + case DisplayType::kFullscreen: watch_time_reporter_->OnDisplayTypeFullscreen(); break; - case blink::DisplayType::kPictureInPicture: + case DisplayType::kPictureInPicture: watch_time_reporter_->OnDisplayTypePictureInPicture(); break; } @@ -3478,7 +3468,7 @@ client_->OnRequestVideoFrameCallback(); } -std::unique_ptr<blink::WebMediaPlayer::VideoFramePresentationMetadata> +std::unique_ptr<WebMediaPlayer::VideoFramePresentationMetadata> WebMediaPlayerImpl::GetVideoFramePresentationMetadata() { return compositor_->GetLastPresentedFrameMetadata(); } @@ -3495,7 +3485,7 @@ VideoFrameCompositor::UpdateType::kBypassClient)); } -base::WeakPtr<blink::WebMediaPlayer> WebMediaPlayerImpl::AsWeakPtr() { +base::WeakPtr<WebMediaPlayer> WebMediaPlayerImpl::AsWeakPtr() { return weak_this_; } @@ -3817,7 +3807,7 @@ bool WebMediaPlayerImpl::IsInPictureInPicture() const { DCHECK(client_); - return client_->GetDisplayType() == blink::DisplayType::kPictureInPicture; + return client_->GetDisplayType() == DisplayType::kPictureInPicture; } void WebMediaPlayerImpl::MaybeSetContainerNameForMetrics() {
diff --git a/third_party/blink/renderer/platform/media/web_media_player_impl_unittest.cc b/third_party/blink/renderer/platform/media/web_media_player_impl_unittest.cc index ed48b089..a6312fe 100644 --- a/third_party/blink/renderer/platform/media/web_media_player_impl_unittest.cc +++ b/third_party/blink/renderer/platform/media/web_media_player_impl_unittest.cc
@@ -118,7 +118,7 @@ std::string(new_rate_string)); } -class MockWebMediaPlayerClient : public blink::WebMediaPlayerClient { +class MockWebMediaPlayerClient : public WebMediaPlayerClient { public: MockWebMediaPlayerClient() = default; @@ -130,34 +130,31 @@ MOCK_METHOD0(SizeChanged, void()); MOCK_METHOD1(SetCcLayer, void(cc::Layer*)); MOCK_METHOD5(AddAudioTrack, - blink::WebMediaPlayer::TrackId( - const blink::WebString&, - blink::WebMediaPlayerClient::AudioTrackKind, - const blink::WebString&, - const blink::WebString&, - bool)); - MOCK_METHOD1(RemoveAudioTrack, void(blink::WebMediaPlayer::TrackId)); + WebMediaPlayer::TrackId(const WebString&, + WebMediaPlayerClient::AudioTrackKind, + const WebString&, + const WebString&, + bool)); + MOCK_METHOD1(RemoveAudioTrack, void(WebMediaPlayer::TrackId)); MOCK_METHOD5(AddVideoTrack, - blink::WebMediaPlayer::TrackId( - const blink::WebString&, - blink::WebMediaPlayerClient::VideoTrackKind, - const blink::WebString&, - const blink::WebString&, - bool)); - MOCK_METHOD1(RemoveVideoTrack, void(blink::WebMediaPlayer::TrackId)); - MOCK_METHOD1(AddTextTrack, void(blink::WebInbandTextTrack*)); - MOCK_METHOD1(RemoveTextTrack, void(blink::WebInbandTextTrack*)); - MOCK_METHOD1(MediaSourceOpened, void(blink::WebMediaSource*)); - MOCK_METHOD2(RemotePlaybackCompatibilityChanged, - void(const blink::WebURL&, bool)); + WebMediaPlayer::TrackId(const WebString&, + WebMediaPlayerClient::VideoTrackKind, + const WebString&, + const WebString&, + bool)); + MOCK_METHOD1(RemoveVideoTrack, void(WebMediaPlayer::TrackId)); + MOCK_METHOD1(AddTextTrack, void(WebInbandTextTrack*)); + MOCK_METHOD1(RemoveTextTrack, void(WebInbandTextTrack*)); + MOCK_METHOD1(MediaSourceOpened, void(WebMediaSource*)); + MOCK_METHOD2(RemotePlaybackCompatibilityChanged, void(const WebURL&, bool)); MOCK_METHOD0(WasAlwaysMuted, bool()); MOCK_METHOD0(HasSelectedVideoTrack, bool()); - MOCK_METHOD0(GetSelectedVideoTrackId, blink::WebMediaPlayer::TrackId()); + MOCK_METHOD0(GetSelectedVideoTrackId, WebMediaPlayer::TrackId()); MOCK_METHOD0(HasNativeControls, bool()); MOCK_METHOD0(IsAudioElement, bool()); - MOCK_CONST_METHOD0(GetDisplayType, blink::DisplayType()); + MOCK_CONST_METHOD0(GetDisplayType, DisplayType()); MOCK_CONST_METHOD0(IsInAutoPIP, bool()); - MOCK_METHOD1(MediaRemotingStarted, void(const blink::WebString&)); + MOCK_METHOD1(MediaRemotingStarted, void(const WebString&)); MOCK_METHOD1(MediaRemotingStopped, void(int)); MOCK_METHOD0(PictureInPictureStopped, void()); MOCK_METHOD0(OnPictureInPictureStateChange, void()); @@ -181,7 +178,7 @@ MOCK_METHOD0(DidSeek, void()); MOCK_METHOD0(GetFeatures, Features(void)); MOCK_METHOD0(OnRequestVideoFrameCallback, void()); - MOCK_METHOD0(GetTextTrackMetadata, std::vector<blink::TextTrackMetadata>()); + MOCK_METHOD0(GetTextTrackMetadata, std::vector<TextTrackMetadata>()); bool was_always_muted_ = false; @@ -190,7 +187,7 @@ }; class MockWebMediaPlayerEncryptedMediaClient - : public blink::WebMediaPlayerEncryptedMediaClient { + : public WebMediaPlayerEncryptedMediaClient { public: MockWebMediaPlayerEncryptedMediaClient() = default; @@ -203,12 +200,12 @@ DISALLOW_COPY_AND_ASSIGN(MockWebMediaPlayerEncryptedMediaClient); }; -class MockWebMediaPlayerDelegate : public blink::WebMediaPlayerDelegate { +class MockWebMediaPlayerDelegate : public WebMediaPlayerDelegate { public: MockWebMediaPlayerDelegate() = default; ~MockWebMediaPlayerDelegate() override = default; - // blink::WebMediaPlayerDelegate implementation. + // WebMediaPlayerDelegate implementation. int AddObserver(Observer* observer) override { DCHECK_EQ(nullptr, observer_); observer_ = observer; @@ -283,7 +280,7 @@ bool is_hidden_ = false; }; -class MockSurfaceLayerBridge : public blink::WebSurfaceLayerBridge { +class MockSurfaceLayerBridge : public WebSurfaceLayerBridge { public: MOCK_CONST_METHOD0(GetCcLayer, cc::Layer*()); MOCK_CONST_METHOD0(GetFrameSinkId, const viz::FrameSinkId&()); @@ -306,7 +303,7 @@ MOCK_METHOD1(SetIsPageVisible, void(bool)); MOCK_METHOD0( GetLastPresentedFrameMetadata, - std::unique_ptr<blink::WebMediaPlayer::VideoFramePresentationMetadata>()); + std::unique_ptr<WebMediaPlayer::VideoFramePresentationMetadata>()); MOCK_METHOD0(GetCurrentFrameOnAnyThread, scoped_refptr<media::VideoFrame>()); MOCK_METHOD1(UpdateCurrentFrameIfStale, void(VideoFrameCompositor::UpdateType)); @@ -318,17 +315,16 @@ class WebMediaPlayerImplTest : public testing::Test, - private blink::WebTestingSupport::WebScopedMockScrollbars { + private WebTestingSupport::WebScopedMockScrollbars { public: WebMediaPlayerImplTest() : WebMediaPlayerImplTest( - blink::scheduler::WebThreadScheduler::MainThreadScheduler() + scheduler::WebThreadScheduler::MainThreadScheduler() ->CreateAgentGroupScheduler()) {} explicit WebMediaPlayerImplTest( - std::unique_ptr<blink::scheduler::WebAgentGroupScheduler> - agent_group_scheduler) + std::unique_ptr<scheduler::WebAgentGroupScheduler> agent_group_scheduler) : media_thread_("MediaThreadForTest"), - web_view_(blink::WebView::Create( + web_view_(WebView::Create( /*client=*/nullptr, /*is_hidden=*/false, /*is_inside_portal=*/false, @@ -339,12 +335,11 @@ *agent_group_scheduler, /*session_storage_namespace_id=*/base::EmptyString(), /*page_base_background_color=*/absl::nullopt)), - web_local_frame_( - blink::WebLocalFrame::CreateMainFrame(web_view_, - &web_frame_client_, - nullptr, - blink::LocalFrameToken(), - nullptr)), + web_local_frame_(WebLocalFrame::CreateMainFrame(web_view_, + &web_frame_client_, + nullptr, + LocalFrameToken(), + nullptr)), context_provider_(viz::TestContextProvider::Create()), audio_parameters_(media::TestAudioParameters::Normal()), memory_dump_manager_( @@ -452,7 +447,7 @@ base::BindOnce(&WebMediaPlayerImplTest::CreateMockSurfaceLayerBridge, base::Unretained(this)), viz::TestContextProvider::Create(), - blink::WebMediaPlayer::SurfaceLayerMode::kAlways, + WebMediaPlayer::SurfaceLayerMode::kAlways, is_background_suspend_enabled_, is_background_video_playback_enabled_, true, std::move(demuxer_override), nullptr); @@ -466,25 +461,25 @@ std::move(params)); } - std::unique_ptr<blink::WebSurfaceLayerBridge> CreateMockSurfaceLayerBridge( - blink::WebSurfaceLayerBridgeObserver*, + std::unique_ptr<WebSurfaceLayerBridge> CreateMockSurfaceLayerBridge( + WebSurfaceLayerBridgeObserver*, cc::UpdateSubmissionStateCB) { return std::move(surface_layer_bridge_); } - blink::WebLocalFrame* GetWebLocalFrame() { return web_local_frame_; } + WebLocalFrame* GetWebLocalFrame() { return web_local_frame_; } int64_t OnAdjustAllocatedMemory(int64_t delta) { reported_memory_ += delta; return 0; } - void SetNetworkState(blink::WebMediaPlayer::NetworkState state) { + void SetNetworkState(WebMediaPlayer::NetworkState state) { EXPECT_CALL(client_, NetworkStateChanged()); wmpi_->SetNetworkState(state); } - void SetReadyState(blink::WebMediaPlayer::ReadyState state) { + void SetReadyState(WebMediaPlayer::ReadyState state) { EXPECT_CALL(client_, ReadyStateChanged()); wmpi_->SetReadyState(state); } @@ -519,10 +514,10 @@ } void SetMetadata(bool has_audio, bool has_video) { - wmpi_->SetNetworkState(blink::WebMediaPlayer::kNetworkStateLoaded); + wmpi_->SetNetworkState(WebMediaPlayer::kNetworkStateLoaded); EXPECT_CALL(client_, ReadyStateChanged()); - wmpi_->SetReadyState(blink::WebMediaPlayer::kReadyStateHaveMetadata); + wmpi_->SetReadyState(WebMediaPlayer::kReadyStateHaveMetadata); wmpi_->pipeline_metadata_.has_audio = has_audio; wmpi_->pipeline_metadata_.has_video = has_video; @@ -648,7 +643,7 @@ wmpi_->SetSuspendState(is_suspended); } - void SetLoadType(blink::WebMediaPlayer::LoadType load_type) { + void SetLoadType(WebMediaPlayer::LoadType load_type) { wmpi_->load_type_ = load_type; } @@ -707,7 +702,7 @@ // the resource is fully buffered locally. We can use a fake one here since // we're injecting the response artificially. It's value is unknown to the // underlying demuxer. - const blink::KURL kTestURL( + const KURL kTestURL( String::FromUTF8(std::string(is_streaming ? "http" : "file") + "://example.com/sample.webm")); @@ -715,19 +710,19 @@ // to the WebAssociatedURLLoaderClient handed out by the DataSource after it // requests loading of a resource. We then use that client as if we are the // network stack and "serve" an in memory file to the DataSource. - blink::WebAssociatedURLLoaderClient* client = nullptr; + WebAssociatedURLLoaderClient* client = nullptr; EXPECT_CALL(mock_resource_fetch_context_, CreateUrlLoader(_)) .WillRepeatedly( - Invoke([&client](const blink::WebAssociatedURLLoaderOptions&) { + Invoke([&client](const WebAssociatedURLLoaderOptions&) { auto a = std::make_unique<NiceMock<MockWebAssociatedURLLoader>>(); EXPECT_CALL(*a, LoadAsynchronously(_, _)) .WillRepeatedly(testing::SaveArg<1>(&client)); return a; })); - wmpi_->Load(blink::WebMediaPlayer::kLoadTypeURL, - blink::WebMediaPlayerSource(blink::WebURL(kTestURL)), - blink::WebMediaPlayer::kCorsModeUnspecified, + wmpi_->Load(WebMediaPlayer::kLoadTypeURL, + WebMediaPlayerSource(WebURL(kTestURL)), + WebMediaPlayer::kCorsModeUnspecified, /*is_cache_disabled=*/false); base::RunLoop().RunUntilIdle(); @@ -739,10 +734,10 @@ // "Serve" the file to the DataSource. Note: We respond with 200 okay, which // will prevent range requests or partial responses from being used. For // streaming responses, we'll pretend we don't know the content length. - blink::WebURLResponse response(kTestURL); + WebURLResponse response(kTestURL); response.SetHttpHeaderField( - blink::WebString::FromUTF8("Content-Length"), - blink::WebString::FromUTF8( + WebString::FromUTF8("Content-Length"), + WebString::FromUTF8( is_streaming ? "-1" : base::NumberToString(data->data_size()))); response.SetExpectedContentLength(is_streaming ? -1 : data->data_size()); response.SetHttpStatusCode(200); @@ -763,7 +758,7 @@ // unreliable due to asynchronous execution of tasks on the // base::test:TaskEnvironment. void LoadAndWaitForReadyState(std::string data_file, - blink::WebMediaPlayer::ReadyState ready_state) { + WebMediaPlayer::ReadyState ready_state) { Load(data_file); while (wmpi_->GetReadyState() < ready_state) { base::RunLoop loop; @@ -779,13 +774,13 @@ EXPECT_TRUE(wmpi_->data_source_); EXPECT_TRUE(wmpi_->demuxer_); - if (ready_state > blink::WebMediaPlayer::kReadyStateHaveCurrentData) + if (ready_state > WebMediaPlayer::kReadyStateHaveCurrentData) EXPECT_FALSE(wmpi_->seeking_); } void LoadAndWaitForCurrentData(std::string data_file) { LoadAndWaitForReadyState(data_file, - blink::WebMediaPlayer::kReadyStateHaveCurrentData); + WebMediaPlayer::kReadyStateHaveCurrentData); } void CycleThreads() { @@ -802,7 +797,7 @@ void OnProgress() { wmpi_->OnProgress(); } void OnCdmCreated(base::RepeatingClosure quit_closure, - blink::WebContentDecryptionModule* cdm, + WebContentDecryptionModule* cdm, const std::string& error_message) { LOG_IF(ERROR, !error_message.empty()) << error_message; EXPECT_TRUE(cdm); @@ -813,8 +808,8 @@ void CreateCdm() { // Must use a supported key system on a secure context. std::u16string key_system = u"org.w3.clearkey"; - auto test_origin = blink::WebSecurityOrigin::CreateFromString( - blink::WebString::FromUTF8("https://test.origin")); + auto test_origin = WebSecurityOrigin::CreateFromString( + WebString::FromUTF8("https://test.origin")); base::RunLoop run_loop; WebContentDecryptionModuleImpl::Create( @@ -846,9 +841,9 @@ base::Thread media_thread_; // Blink state. - blink::WebLocalFrameClient web_frame_client_; - blink::WebView* web_view_; - blink::WebLocalFrame* web_local_frame_; + WebLocalFrameClient web_frame_client_; + WebView* web_view_; + WebLocalFrame* web_local_frame_; scoped_refptr<viz::TestContextProvider> context_provider_; NiceMock<MockVideoFrameCompositor>* compositor_; @@ -871,7 +866,7 @@ scoped_refptr<media::MockCdm> mock_cdm_ = base::MakeRefCounted<media::MockCdm>(); media::MockCdmFactory mock_cdm_factory_{mock_cdm_}; - std::unique_ptr<blink::WebContentDecryptionModule> web_cdm_; + std::unique_ptr<WebContentDecryptionModule> web_cdm_; media::MockCdmContext mock_cdm_context_; viz::FrameSinkId frame_sink_id_ = viz::FrameSinkId(1, 1); @@ -904,8 +899,7 @@ std::unique_ptr<base::trace_event::MemoryDumpManager> memory_dump_manager_; - std::unique_ptr<blink::scheduler::WebAgentGroupScheduler> - agent_group_scheduler_; + std::unique_ptr<scheduler::WebAgentGroupScheduler> agent_group_scheduler_; private: DISALLOW_COPY_AND_ASSIGN(WebMediaPlayerImplTest); @@ -920,7 +914,7 @@ TEST_F(WebMediaPlayerImplTest, LoadAndDestroy) { InitializeWebMediaPlayerImpl(); EXPECT_FALSE(IsSuspended()); - wmpi_->SetPreload(blink::WebMediaPlayer::kPreloadAuto); + wmpi_->SetPreload(WebMediaPlayer::kPreloadAuto); LoadAndWaitForCurrentData(kAudioOnlyTestFile); EXPECT_FALSE(IsSuspended()); CycleThreads(); @@ -936,9 +930,9 @@ TEST_F(WebMediaPlayerImplTest, LoadAndDestroyDataUrl) { InitializeWebMediaPlayerImpl(); EXPECT_FALSE(IsSuspended()); - wmpi_->SetPreload(blink::WebMediaPlayer::kPreloadAuto); + wmpi_->SetPreload(WebMediaPlayer::kPreloadAuto); - const blink::KURL kMp3DataUrl( + const KURL kMp3DataUrl( "data://audio/mp3;base64,SUQzAwAAAAAAFlRFTkMAAAAMAAAAQW1hZGV1cyBQcm//" "+5DEAAAAAAAAAAAAAAAAAAAAAABYaW5nAAAADwAAAAwAAAftABwcHBwcHBwcMTExMTExMTFG" "RkZGRkZGRlpaWlpaWlpaWm9vb29vb29vhISEhISEhISYmJiYmJiYmJitra2tra2trcLCwsLC" @@ -991,9 +985,9 @@ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" "AAAAAAAAAAAAAAAAAAP8="); - wmpi_->Load(blink::WebMediaPlayer::kLoadTypeURL, - blink::WebMediaPlayerSource(blink::WebURL(kMp3DataUrl)), - blink::WebMediaPlayer::kCorsModeUnspecified, + wmpi_->Load(WebMediaPlayer::kLoadTypeURL, + WebMediaPlayerSource(WebURL(kMp3DataUrl)), + WebMediaPlayer::kCorsModeUnspecified, /*is_cache_disabled=*/false); base::RunLoop().RunUntilIdle(); @@ -1001,8 +995,7 @@ // This runs until we reach the have current data state. Attempting to wait // for states < kReadyStateHaveCurrentData is unreliable due to asynchronous // execution of tasks on the base::test:TaskEnvironment. - while (wmpi_->GetReadyState() < - blink::WebMediaPlayer::kReadyStateHaveCurrentData) { + while (wmpi_->GetReadyState() < WebMediaPlayer::kReadyStateHaveCurrentData) { base::RunLoop loop; EXPECT_CALL(client_, ReadyStateChanged()) .WillRepeatedly(RunClosure(loop.QuitClosure())); @@ -1020,9 +1013,9 @@ TEST_F(WebMediaPlayerImplTest, LoadPreloadMetadataSuspend) { InitializeWebMediaPlayerImpl(); EXPECT_CALL(client_, CouldPlayIfEnoughData()).WillRepeatedly(Return(false)); - wmpi_->SetPreload(blink::WebMediaPlayer::kPreloadMetaData); + wmpi_->SetPreload(WebMediaPlayer::kPreloadMetaData); LoadAndWaitForReadyState(kAudioOnlyTestFile, - blink::WebMediaPlayer::kReadyStateHaveMetadata); + WebMediaPlayer::kReadyStateHaveMetadata); testing::Mock::VerifyAndClearExpectations(&client_); EXPECT_CALL(client_, ReadyStateChanged()).Times(AnyNumber()); CycleThreads(); @@ -1040,16 +1033,15 @@ TEST_F(WebMediaPlayerImplTest, NoBufferSizeIncreaseUntilHaveEnough) { InitializeWebMediaPlayerImpl(); EXPECT_CALL(client_, CouldPlayIfEnoughData()).WillRepeatedly(Return(true)); - wmpi_->SetPreload(blink::WebMediaPlayer::kPreloadAuto); + wmpi_->SetPreload(WebMediaPlayer::kPreloadAuto); LoadAndWaitForReadyState(kAudioOnlyTestFile, - blink::WebMediaPlayer::kReadyStateHaveMetadata); + WebMediaPlayer::kReadyStateHaveMetadata); testing::Mock::VerifyAndClearExpectations(&client_); EXPECT_CALL(client_, ReadyStateChanged()).Times(AnyNumber()); wmpi_->Play(); EXPECT_FALSE(IsDataSourceMarkedAsPlaying()); - while (wmpi_->GetReadyState() < - blink::WebMediaPlayer::kReadyStateHaveEnoughData) { + while (wmpi_->GetReadyState() < WebMediaPlayer::kReadyStateHaveEnoughData) { // Clear the mock so it doesn't have a stale QuitClosure. testing::Mock::VerifyAndClearExpectations(&client_); @@ -1066,7 +1058,7 @@ TEST_F(WebMediaPlayerImplTest, LoadPreloadMetadataSuspendNoStreaming) { InitializeWebMediaPlayerImpl(); EXPECT_CALL(client_, CouldPlayIfEnoughData()).WillRepeatedly(Return(false)); - wmpi_->SetPreload(blink::WebMediaPlayer::kPreloadMetaData); + wmpi_->SetPreload(WebMediaPlayer::kPreloadMetaData); // This test needs a file which is larger than the MultiBuffer block size; // otherwise we'll never complete initialization of the MultiBufferDataSource. @@ -1074,8 +1066,7 @@ Load(kLargeAudioOnlyTestFile, LoadType::kStreaming); // This runs until we reach the metadata state. - while (wmpi_->GetReadyState() < - blink::WebMediaPlayer::kReadyStateHaveMetadata) { + while (wmpi_->GetReadyState() < WebMediaPlayer::kReadyStateHaveMetadata) { base::RunLoop loop; EXPECT_CALL(client_, ReadyStateChanged()) .WillRepeatedly(RunClosure(loop.QuitClosure())); @@ -1097,12 +1088,12 @@ scoped_feature_list.InitAndEnableFeature(media::kPreloadMetadataLazyLoad); InitializeWebMediaPlayerImpl(); EXPECT_CALL(client_, CouldPlayIfEnoughData()).WillRepeatedly(Return(false)); - wmpi_->SetPreload(blink::WebMediaPlayer::kPreloadMetaData); + wmpi_->SetPreload(WebMediaPlayer::kPreloadMetaData); // Don't set poster, but ensure we still reach suspended state. LoadAndWaitForReadyState(kVideoOnlyTestFile, - blink::WebMediaPlayer::kReadyStateHaveMetadata); + WebMediaPlayer::kReadyStateHaveMetadata); testing::Mock::VerifyAndClearExpectations(&client_); EXPECT_CALL(client_, ReadyStateChanged()).Times(AnyNumber()); CycleThreads(); @@ -1123,11 +1114,11 @@ TEST_F(WebMediaPlayerImplTest, LoadPreloadMetadataSuspendNoVideoMemoryUsage) { InitializeWebMediaPlayerImpl(); EXPECT_CALL(client_, CouldPlayIfEnoughData()).WillRepeatedly(Return(false)); - wmpi_->SetPreload(blink::WebMediaPlayer::kPreloadMetaData); - wmpi_->SetPoster(blink::WebURL(blink::KURL("file://example.com/sample.jpg"))); + wmpi_->SetPreload(WebMediaPlayer::kPreloadMetaData); + wmpi_->SetPoster(WebURL(KURL("file://example.com/sample.jpg"))); LoadAndWaitForReadyState(kVideoOnlyTestFile, - blink::WebMediaPlayer::kReadyStateHaveMetadata); + WebMediaPlayer::kReadyStateHaveMetadata); testing::Mock::VerifyAndClearExpectations(&client_); EXPECT_CALL(client_, ReadyStateChanged()).Times(AnyNumber()); CycleThreads(); @@ -1147,7 +1138,7 @@ TEST_F(WebMediaPlayerImplTest, LoadPreloadMetadataSuspendCouldPlay) { InitializeWebMediaPlayerImpl(); EXPECT_CALL(client_, CouldPlayIfEnoughData()).WillRepeatedly(Return(true)); - wmpi_->SetPreload(blink::WebMediaPlayer::kPreloadMetaData); + wmpi_->SetPreload(WebMediaPlayer::kPreloadMetaData); LoadAndWaitForCurrentData(kAudioOnlyTestFile); testing::Mock::VerifyAndClearExpectations(&client_); EXPECT_CALL(client_, ReadyStateChanged()).Times(AnyNumber()); @@ -1177,7 +1168,7 @@ TEST_F(WebMediaPlayerImplTest, IdleSuspendIsEnabledIfLoadingHasStalled) { InitializeWebMediaPlayerImpl(); - SetNetworkState(blink::WebMediaPlayer::kNetworkStateLoading); + SetNetworkState(WebMediaPlayer::kNetworkStateLoading); base::SimpleTestTickClock clock; clock.Advance(base::TimeDelta::FromSeconds(1)); SetTickClock(&clock); @@ -1193,7 +1184,7 @@ TEST_F(WebMediaPlayerImplTest, DidLoadingProgressTriggersResume) { // Same setup as IdleSuspendIsEnabledBeforeLoadingBegins. InitializeWebMediaPlayerImpl(); - SetNetworkState(blink::WebMediaPlayer::kNetworkStateLoading); + SetNetworkState(WebMediaPlayer::kNetworkStateLoading); EXPECT_TRUE(delegate_.ExpireForTesting()); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(IsSuspended()); @@ -1266,7 +1257,7 @@ TEST_F(WebMediaPlayerImplTest, ComputePlayState_HaveFutureData) { InitializeWebMediaPlayerImpl(); SetMetadata(true, true); - SetReadyState(blink::WebMediaPlayer::kReadyStateHaveFutureData); + SetReadyState(WebMediaPlayer::kReadyStateHaveFutureData); WebMediaPlayerImpl::PlayState state = ComputePlayState(); EXPECT_EQ(WebMediaPlayerImpl::DelegateState::PAUSED, state.delegate_state); EXPECT_TRUE(state.is_idle); @@ -1278,7 +1269,7 @@ TEST_F(WebMediaPlayerImplTest, ComputePlayState_PlayingError) { InitializeWebMediaPlayerImpl(); SetMetadata(true, true); - SetReadyState(blink::WebMediaPlayer::kReadyStateHaveFutureData); + SetReadyState(WebMediaPlayer::kReadyStateHaveFutureData); SetPaused(false); WebMediaPlayerImpl::PlayState state = ComputePlayState(); EXPECT_EQ(WebMediaPlayerImpl::DelegateState::PLAYING, state.delegate_state); @@ -1295,7 +1286,7 @@ TEST_F(WebMediaPlayerImplTest, ComputePlayState_Playing) { InitializeWebMediaPlayerImpl(); SetMetadata(true, true); - SetReadyState(blink::WebMediaPlayer::kReadyStateHaveFutureData); + SetReadyState(WebMediaPlayer::kReadyStateHaveFutureData); SetPaused(false); WebMediaPlayerImpl::PlayState state = ComputePlayState(); EXPECT_EQ(WebMediaPlayerImpl::DelegateState::PLAYING, state.delegate_state); @@ -1307,7 +1298,7 @@ TEST_F(WebMediaPlayerImplTest, ComputePlayState_PlayingVideoOnly) { InitializeWebMediaPlayerImpl(); SetMetadata(false, true); - SetReadyState(blink::WebMediaPlayer::kReadyStateHaveFutureData); + SetReadyState(WebMediaPlayer::kReadyStateHaveFutureData); SetPaused(false); WebMediaPlayerImpl::PlayState state = ComputePlayState(); EXPECT_EQ(WebMediaPlayerImpl::DelegateState::PLAYING, state.delegate_state); @@ -1319,9 +1310,9 @@ TEST_F(WebMediaPlayerImplTest, ComputePlayState_Underflow) { InitializeWebMediaPlayerImpl(); SetMetadata(true, true); - SetReadyState(blink::WebMediaPlayer::kReadyStateHaveFutureData); + SetReadyState(WebMediaPlayer::kReadyStateHaveFutureData); SetPaused(false); - SetReadyState(blink::WebMediaPlayer::kReadyStateHaveCurrentData); + SetReadyState(WebMediaPlayer::kReadyStateHaveCurrentData); WebMediaPlayerImpl::PlayState state = ComputePlayState(); EXPECT_EQ(WebMediaPlayerImpl::DelegateState::PLAYING, state.delegate_state); EXPECT_FALSE(state.is_idle); @@ -1332,7 +1323,7 @@ TEST_F(WebMediaPlayerImplTest, ComputePlayState_FrameHidden) { InitializeWebMediaPlayerImpl(); SetMetadata(true, true); - SetReadyState(blink::WebMediaPlayer::kReadyStateHaveFutureData); + SetReadyState(WebMediaPlayer::kReadyStateHaveFutureData); SetPaused(false); WebMediaPlayerImpl::PlayState state = ComputePlayState_FrameHidden(); @@ -1345,7 +1336,7 @@ TEST_F(WebMediaPlayerImplTest, ComputePlayState_FrameHiddenAudioOnly) { InitializeWebMediaPlayerImpl(); SetMetadata(true, true); - SetReadyState(blink::WebMediaPlayer::kReadyStateHaveFutureData); + SetReadyState(WebMediaPlayer::kReadyStateHaveFutureData); SetPaused(false); SetMetadata(true, false); @@ -1363,7 +1354,7 @@ InitializeWebMediaPlayerImpl(); SetMetadata(true, true); - SetReadyState(blink::WebMediaPlayer::kReadyStateHaveFutureData); + SetReadyState(WebMediaPlayer::kReadyStateHaveFutureData); SetPaused(false); WebMediaPlayerImpl::PlayState state = ComputePlayState_FrameHidden(); EXPECT_EQ(WebMediaPlayerImpl::DelegateState::PLAYING, state.delegate_state); @@ -1386,7 +1377,7 @@ InitializeWebMediaPlayerImpl(); SetMetadata(true, true); - SetReadyState(blink::WebMediaPlayer::kReadyStateHaveFutureData); + SetReadyState(WebMediaPlayer::kReadyStateHaveFutureData); SetPaused(false); WebMediaPlayerImpl::PlayState state = ComputePlayState_FrameHidden(); @@ -1399,7 +1390,7 @@ TEST_F(WebMediaPlayerImplTest, ComputePlayState_FrameClosed) { InitializeWebMediaPlayerImpl(); SetMetadata(true, true); - SetReadyState(blink::WebMediaPlayer::kReadyStateHaveFutureData); + SetReadyState(WebMediaPlayer::kReadyStateHaveFutureData); SetPaused(false); SetWasSuspendedForFrameClosed(true); WebMediaPlayerImpl::PlayState state = ComputePlayState(); @@ -1412,7 +1403,7 @@ TEST_F(WebMediaPlayerImplTest, ComputePlayState_PausedSeek) { InitializeWebMediaPlayerImpl(); SetMetadata(true, true); - SetReadyState(blink::WebMediaPlayer::kReadyStateHaveFutureData); + SetReadyState(WebMediaPlayer::kReadyStateHaveFutureData); SetSeeking(true); WebMediaPlayerImpl::PlayState state = ComputePlayState(); EXPECT_EQ(WebMediaPlayerImpl::DelegateState::PAUSED, state.delegate_state); @@ -1424,7 +1415,7 @@ TEST_F(WebMediaPlayerImplTest, ComputePlayState_Ended) { InitializeWebMediaPlayerImpl(); SetMetadata(true, true); - SetReadyState(blink::WebMediaPlayer::kReadyStateHaveFutureData); + SetReadyState(WebMediaPlayer::kReadyStateHaveFutureData); SetPaused(false); SetEnded(true); @@ -1448,7 +1439,7 @@ TEST_F(WebMediaPlayerImplTest, ComputePlayState_DoesNotStaySuspended) { InitializeWebMediaPlayerImpl(); SetMetadata(true, true); - SetReadyState(blink::WebMediaPlayer::kReadyStateHaveMetadata); + SetReadyState(WebMediaPlayer::kReadyStateHaveMetadata); // Should stay suspended even though not stale or backgrounded. WebMediaPlayerImpl::PlayState state = ComputePlayState_Suspended(); @@ -1461,7 +1452,7 @@ TEST_F(WebMediaPlayerImplTest, ComputePlayState_StaysSuspended) { InitializeWebMediaPlayerImpl(); SetMetadata(true, true); - SetReadyState(blink::WebMediaPlayer::kReadyStateHaveFutureData); + SetReadyState(WebMediaPlayer::kReadyStateHaveFutureData); // Should stay suspended even though not stale or backgrounded. WebMediaPlayerImpl::PlayState state = ComputePlayState_Suspended(); @@ -1474,7 +1465,7 @@ TEST_F(WebMediaPlayerImplTest, ComputePlayState_ResumeForNeedFirstFrame) { InitializeWebMediaPlayerImpl(); SetMetadata(true, true); - SetReadyState(blink::WebMediaPlayer::kReadyStateHaveFutureData); + SetReadyState(WebMediaPlayer::kReadyStateHaveFutureData); // Should stay suspended even though not stale or backgrounded. WebMediaPlayerImpl::PlayState state = ComputePlayState_Suspended(); @@ -1494,7 +1485,7 @@ TEST_F(WebMediaPlayerImplTest, ComputePlayState_Flinging) { InitializeWebMediaPlayerImpl(); SetMetadata(true, true); - SetReadyState(blink::WebMediaPlayer::kReadyStateHaveFutureData); + SetReadyState(WebMediaPlayer::kReadyStateHaveFutureData); // Remote media via the FlingingRenderer should not be idle. WebMediaPlayerImpl::PlayState state = ComputePlayState_Flinging(); @@ -1507,7 +1498,7 @@ TEST_F(WebMediaPlayerImplTest, ComputePlayState_Fullscreen) { InitializeWebMediaPlayerImpl(); SetMetadata(true, true); - SetReadyState(blink::WebMediaPlayer::kReadyStateHaveFutureData); + SetReadyState(WebMediaPlayer::kReadyStateHaveFutureData); SetFullscreen(true); SetPaused(true); delegate_.SetStaleForTesting(true); @@ -1523,7 +1514,7 @@ TEST_F(WebMediaPlayerImplTest, ComputePlayState_Streaming) { InitializeWebMediaPlayerImpl(); SetMetadata(true, true); - SetReadyState(blink::WebMediaPlayer::kReadyStateHaveFutureData); + SetReadyState(WebMediaPlayer::kReadyStateHaveFutureData); SetPaused(true); delegate_.SetStaleForTesting(true); @@ -1558,7 +1549,7 @@ EXPECT_CALL(delegate_, DidMediaMetadataChange(_, true, true, _)).Times(2); OnMetadata(metadata); - SetReadyState(blink::WebMediaPlayer::kReadyStateHaveFutureData); + SetReadyState(WebMediaPlayer::kReadyStateHaveFutureData); Play(); // Cause PlayerGone Pause(); @@ -1598,7 +1589,7 @@ TEST_F(WebMediaPlayerImplTest, MediaPositionState_Playing) { InitializeWebMediaPlayerImpl(); LoadAndWaitForReadyState(kAudioOnlyTestFile, - blink::WebMediaPlayer::kReadyStateHaveFutureData); + WebMediaPlayer::kReadyStateHaveFutureData); wmpi_->SetRate(1.0); Play(); @@ -1611,7 +1602,7 @@ TEST_F(WebMediaPlayerImplTest, MediaPositionState_Paused) { InitializeWebMediaPlayerImpl(); LoadAndWaitForReadyState(kAudioOnlyTestFile, - blink::WebMediaPlayer::kReadyStateHaveFutureData); + WebMediaPlayer::kReadyStateHaveFutureData); wmpi_->SetRate(1.0); // The effective playback rate is 0.0 while paused. @@ -1624,7 +1615,7 @@ TEST_F(WebMediaPlayerImplTest, MediaPositionState_PositionChange) { InitializeWebMediaPlayerImpl(); LoadAndWaitForReadyState(kAudioOnlyTestFile, - blink::WebMediaPlayer::kReadyStateHaveFutureData); + WebMediaPlayer::kReadyStateHaveFutureData); wmpi_->SetRate(0.5); Play(); @@ -1643,7 +1634,7 @@ 0.5, kAudioOnlyTestFileDuration, base::TimeDelta::FromSecondsD(0.1), /*end_of_media=*/false)) .InSequence(sequence); - SetReadyState(blink::WebMediaPlayer::kReadyStateHaveFutureData); + SetReadyState(WebMediaPlayer::kReadyStateHaveFutureData); wmpi_->OnTimeUpdate(); // No media time progress -> no MediaPositionState change. @@ -1653,10 +1644,10 @@ TEST_F(WebMediaPlayerImplTest, MediaPositionState_EndOfMedia) { InitializeWebMediaPlayerImpl(); LoadAndWaitForReadyState(kAudioOnlyTestFile, - blink::WebMediaPlayer::kReadyStateHaveFutureData); + WebMediaPlayer::kReadyStateHaveFutureData); wmpi_->SetRate(1.0); Play(); - SetReadyState(blink::WebMediaPlayer::kReadyStateHaveFutureData); + SetReadyState(WebMediaPlayer::kReadyStateHaveFutureData); testing::Sequence sequence; EXPECT_CALL(client_, DidPlayerMediaPositionStateChange( @@ -1677,7 +1668,7 @@ TEST_F(WebMediaPlayerImplTest, MediaPositionState_Underflow) { InitializeWebMediaPlayerImpl(); LoadAndWaitForReadyState(kAudioOnlyTestFile, - blink::WebMediaPlayer::kReadyStateHaveFutureData); + WebMediaPlayer::kReadyStateHaveFutureData); wmpi_->SetRate(1.0); Play(); @@ -1685,7 +1676,7 @@ EXPECT_CALL(client_, DidPlayerMediaPositionStateChange( 0.0, kAudioOnlyTestFileDuration, base::TimeDelta(), /*end_of_media=*/false)); - SetReadyState(blink::WebMediaPlayer::kReadyStateHaveCurrentData); + SetReadyState(WebMediaPlayer::kReadyStateHaveCurrentData); wmpi_->OnTimeUpdate(); } @@ -1727,17 +1718,15 @@ // No assertions in the production code should fail. OnMetadata(metadata); - EXPECT_EQ(wmpi_->GetNetworkState(), - blink::WebMediaPlayer::kNetworkStateFormatError); - EXPECT_EQ(wmpi_->GetReadyState(), - blink::WebMediaPlayer::kReadyStateHaveNothing); + EXPECT_EQ(wmpi_->GetNetworkState(), WebMediaPlayer::kNetworkStateFormatError); + EXPECT_EQ(wmpi_->GetReadyState(), WebMediaPlayer::kReadyStateHaveNothing); } TEST_F(WebMediaPlayerImplTest, Encrypted) { InitializeWebMediaPlayerImpl(); // To avoid PreloadMetadataLazyLoad. - wmpi_->SetPreload(blink::WebMediaPlayer::kPreloadAuto); + wmpi_->SetPreload(WebMediaPlayer::kPreloadAuto); { base::RunLoop run_loop; @@ -1762,8 +1751,7 @@ // error. base::RunLoop run_loop; EXPECT_CALL(client_, NetworkStateChanged()).WillOnce(Invoke([&] { - if (wmpi_->GetNetworkState() == - blink::WebMediaPlayer::kNetworkStateFormatError) + if (wmpi_->GetNetworkState() == WebMediaPlayer::kNetworkStateFormatError) run_loop.QuitClosure().Run(); })); SetCdm(); @@ -1793,7 +1781,7 @@ TEST_F(WebMediaPlayerImplTest, FallbackToMediaFoundationRenderer) { InitializeWebMediaPlayerImpl(); // To avoid PreloadMetadataLazyLoad. - wmpi_->SetPreload(blink::WebMediaPlayer::kPreloadAuto); + wmpi_->SetPreload(WebMediaPlayer::kPreloadAuto); // Use MockRendererFactory for kMediaFoundation where the created Renderer // will take the CDM, complete Renderer initialization and report HAVE_ENOUGH @@ -1961,7 +1949,7 @@ // With a user gesture it does unlock the player. GetWebLocalFrame()->NotifyUserActivation( - blink::mojom::UserActivationNotificationType::kTest); + mojom::UserActivationNotificationType::kTest); Play(); EXPECT_FALSE(IsVideoLockedWhenPausedWhenHidden()); @@ -1972,7 +1960,7 @@ // With a user gesture, pause does lock the player. GetWebLocalFrame()->NotifyUserActivation( - blink::mojom::UserActivationNotificationType::kTest); + mojom::UserActivationNotificationType::kTest); Pause(); EXPECT_TRUE(IsVideoLockedWhenPausedWhenHidden()); @@ -2097,7 +2085,7 @@ OnMetadata(metadata); EXPECT_CALL(client_, GetDisplayType()) - .WillRepeatedly(Return(blink::DisplayType::kPictureInPicture)); + .WillRepeatedly(Return(DisplayType::kPictureInPicture)); EXPECT_CALL(client_, OnPictureInPictureStateChange()).Times(1); wmpi_->OnSurfaceIdUpdated(surface_id_); @@ -2109,15 +2097,14 @@ InitializeWebMediaPlayerImpl(); SetMetadata(true, true); - for (auto rs = blink::WebMediaPlayer::kReadyStateHaveNothing; - rs <= blink::WebMediaPlayer::kReadyStateHaveEnoughData; - rs = static_cast<blink::WebMediaPlayer::ReadyState>( - static_cast<int>(rs) + 1)) { + for (auto rs = WebMediaPlayer::kReadyStateHaveNothing; + rs <= WebMediaPlayer::kReadyStateHaveEnoughData; + rs = static_cast<WebMediaPlayer::ReadyState>(static_cast<int>(rs) + 1)) { SetReadyState(rs); delegate_.SetStaleForTesting(true); OnProgress(); EXPECT_EQ(delegate_.IsStale(delegate_.player_id()), - rs >= blink::WebMediaPlayer::kReadyStateHaveFutureData); + rs >= WebMediaPlayer::kReadyStateHaveFutureData); } } @@ -2131,7 +2118,7 @@ auto* dump_manager = base::trace_event::MemoryDumpManager::GetInstance(); InitializeWebMediaPlayerImpl(); - wmpi_->SetPreload(blink::WebMediaPlayer::kPreloadAuto); + wmpi_->SetPreload(WebMediaPlayer::kPreloadAuto); auto* main_dumper = GetMainThreadMemDumper(); EXPECT_TRUE(dump_manager->IsDumpProviderRegisteredForTesting(main_dumper)); LoadAndWaitForCurrentData(kVideoAudioTestFile); @@ -2150,7 +2137,7 @@ TEST_F(WebMediaPlayerImplTest, MemDumpReporting) { InitializeWebMediaPlayerImpl(); - wmpi_->SetPreload(blink::WebMediaPlayer::kPreloadAuto); + wmpi_->SetPreload(WebMediaPlayer::kPreloadAuto); LoadAndWaitForCurrentData(kVideoAudioTestFile); CycleThreads(); @@ -2240,11 +2227,10 @@ InitializeWebMediaPlayerImplInternal(std::move(demuxer)); EXPECT_FALSE(IsSuspended()); - wmpi_->Load( - blink::WebMediaPlayer::kLoadTypeURL, - blink::WebMediaPlayerSource(blink::WebURL(blink::KURL("data://test"))), - blink::WebMediaPlayer::kCorsModeUnspecified, - /*is_cache_disabled=*/false); + wmpi_->Load(WebMediaPlayer::kLoadTypeURL, + WebMediaPlayerSource(WebURL(KURL("data://test"))), + WebMediaPlayer::kCorsModeUnspecified, + /*is_cache_disabled=*/false); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(IsSuspended()); } @@ -2297,15 +2283,15 @@ InitializeWebMediaPlayerImpl(); bool is_media_source = std::get<kIsMediaSource>(GetParam()); - SetLoadType(is_media_source ? blink::WebMediaPlayer::kLoadTypeMediaSource - : blink::WebMediaPlayer::kLoadTypeURL); + SetLoadType(is_media_source ? WebMediaPlayer::kLoadTypeMediaSource + : WebMediaPlayer::kLoadTypeURL); SetVideoKeyframeDistanceAverage( base::TimeDelta::FromSeconds(GetAverageKeyframeDistanceSec())); SetDuration(base::TimeDelta::FromSeconds(GetDurationSec())); if (IsPictureInPictureOn()) { EXPECT_CALL(client_, GetDisplayType()) - .WillRepeatedly(Return(blink::DisplayType::kPictureInPicture)); + .WillRepeatedly(Return(DisplayType::kPictureInPicture)); wmpi_->OnSurfaceIdUpdated(surface_id_); }
diff --git a/third_party/blink/renderer/platform/media/web_media_player_params.cc b/third_party/blink/renderer/platform/media/web_media_player_params.cc index 2198aeef..ca72aba 100644 --- a/third_party/blink/renderer/platform/media/web_media_player_params.cc +++ b/third_party/blink/renderer/platform/media/web_media_player_params.cc
@@ -22,7 +22,7 @@ const scoped_refptr<base::SingleThreadTaskRunner>& video_frame_compositor_task_runner, const AdjustAllocatedMemoryCB& adjust_allocated_memory_cb, - blink::WebContentDecryptionModule* initial_cdm, + WebContentDecryptionModule* initial_cdm, media::RequestRoutingTokenCallback request_routing_token_cb, base::WeakPtr<media::MediaObserver> media_observer, bool enable_instant_source_buffer_gc, @@ -30,7 +30,7 @@ mojo::PendingRemote<media::mojom::MediaMetricsProvider> metrics_provider, CreateSurfaceLayerBridgeCB create_bridge_callback, scoped_refptr<viz::RasterContextProvider> raster_context_provider, - blink::WebMediaPlayer::SurfaceLayerMode use_surface_layer_for_video, + WebMediaPlayer::SurfaceLayerMode use_surface_layer_for_video, bool is_background_suspend_enabled, bool is_background_video_playback_enabled, bool is_background_video_track_optimization_supported,
diff --git a/third_party/blink/renderer/platform/media/web_media_source_impl.cc b/third_party/blink/renderer/platform/media/web_media_source_impl.cc index 80b8f0c..24b0a1a2 100644 --- a/third_party/blink/renderer/platform/media/web_media_source_impl.cc +++ b/third_party/blink/renderer/platform/media/web_media_source_impl.cc
@@ -30,9 +30,9 @@ WebMediaSourceImpl::~WebMediaSourceImpl() = default; -std::unique_ptr<blink::WebSourceBuffer> WebMediaSourceImpl::AddSourceBuffer( - const blink::WebString& content_type, - const blink::WebString& codecs, +std::unique_ptr<WebSourceBuffer> WebMediaSourceImpl::AddSourceBuffer( + const WebString& content_type, + const WebString& codecs, WebMediaSource::AddStatus& out_status /* out */) { std::string id = base::GenerateGUID(); @@ -45,7 +45,7 @@ return nullptr; } -std::unique_ptr<blink::WebSourceBuffer> WebMediaSourceImpl::AddSourceBuffer( +std::unique_ptr<WebSourceBuffer> WebMediaSourceImpl::AddSourceBuffer( std::unique_ptr<media::AudioDecoderConfig> audio_config, WebMediaSource::AddStatus& out_status /* out */) { std::string id = base::GenerateGUID(); @@ -59,7 +59,7 @@ return nullptr; } -std::unique_ptr<blink::WebSourceBuffer> WebMediaSourceImpl::AddSourceBuffer( +std::unique_ptr<WebSourceBuffer> WebMediaSourceImpl::AddSourceBuffer( std::unique_ptr<media::VideoDecoderConfig> video_config, WebMediaSource::AddStatus& out_status /* out */) { std::string id = base::GenerateGUID();
diff --git a/third_party/blink/renderer/platform/media/web_media_source_impl.h b/third_party/blink/renderer/platform/media/web_media_source_impl.h index f308fdab..efc0e46 100644 --- a/third_party/blink/renderer/platform/media/web_media_source_impl.h +++ b/third_party/blink/renderer/platform/media/web_media_source_impl.h
@@ -18,22 +18,22 @@ namespace blink { -class PLATFORM_EXPORT WebMediaSourceImpl : public blink::WebMediaSource { +class PLATFORM_EXPORT WebMediaSourceImpl : public WebMediaSource { public: WebMediaSourceImpl(media::ChunkDemuxer* demuxer); WebMediaSourceImpl(const WebMediaSourceImpl&) = delete; WebMediaSourceImpl& operator=(const WebMediaSourceImpl&) = delete; ~WebMediaSourceImpl() override; - // blink::WebMediaSource implementation. - std::unique_ptr<blink::WebSourceBuffer> AddSourceBuffer( - const blink::WebString& content_type, - const blink::WebString& codecs, + // WebMediaSource implementation. + std::unique_ptr<WebSourceBuffer> AddSourceBuffer( + const WebString& content_type, + const WebString& codecs, AddStatus& out_status /* out */) override; - std::unique_ptr<blink::WebSourceBuffer> AddSourceBuffer( + std::unique_ptr<WebSourceBuffer> AddSourceBuffer( std::unique_ptr<media::AudioDecoderConfig> audio_config, AddStatus& out_status /* out */) override; - std::unique_ptr<blink::WebSourceBuffer> AddSourceBuffer( + std::unique_ptr<WebSourceBuffer> AddSourceBuffer( std::unique_ptr<media::VideoDecoderConfig> video_config, AddStatus& out_status /* out */) override; double Duration() override;
diff --git a/third_party/blink/renderer/platform/media/web_source_buffer_impl.cc b/third_party/blink/renderer/platform/media/web_source_buffer_impl.cc index 765d34a76..d5792123 100644 --- a/third_party/blink/renderer/platform/media/web_source_buffer_impl.cc +++ b/third_party/blink/renderer/platform/media/web_source_buffer_impl.cc
@@ -22,11 +22,11 @@ namespace blink { -static blink::WebSourceBufferClient::ParseWarning ParseWarningToBlink( +static WebSourceBufferClient::ParseWarning ParseWarningToBlink( const media::SourceBufferParseWarning warning) { #define CHROMIUM_PARSE_WARNING_TO_BLINK_ENUM_CASE(name) \ case media::SourceBufferParseWarning::name: \ - return blink::WebSourceBufferClient::ParseWarning::name + return WebSourceBufferClient::ParseWarning::name switch (warning) { CHROMIUM_PARSE_WARNING_TO_BLINK_ENUM_CASE( @@ -37,8 +37,7 @@ } NOTREACHED(); - return blink::WebSourceBufferClient::ParseWarning:: - kKeyframeTimeGreaterThanDependant; + return WebSourceBufferClient::ParseWarning::kKeyframeTimeGreaterThanDependant; #undef CHROMIUM_PARSE_WARNING_TO_BLINK_ENUM_CASE } @@ -77,7 +76,7 @@ WebSourceBufferImpl::~WebSourceBufferImpl() = default; -void WebSourceBufferImpl::SetClient(blink::WebSourceBufferClient* client) { +void WebSourceBufferImpl::SetClient(WebSourceBufferClient* client) { DCHECK(client); DCHECK(!client_); client_ = client; @@ -104,9 +103,9 @@ return false; } -blink::WebTimeRanges WebSourceBufferImpl::Buffered() { +WebTimeRanges WebSourceBufferImpl::Buffered() { media::Ranges<base::TimeDelta> ranges = demuxer_->GetBufferedRanges(id_); - blink::WebTimeRanges result(ranges.size()); + WebTimeRanges result(ranges.size()); for (size_t i = 0; i < ranges.size(); i++) { result[i].start = ranges.start(i).InSecondsF(); result[i].end = ranges.end(i).InSecondsF(); @@ -177,13 +176,13 @@ demuxer_->Remove(id_, DoubleToTimeDelta(start), DoubleToTimeDelta(end)); } -bool WebSourceBufferImpl::CanChangeType(const blink::WebString& content_type, - const blink::WebString& codecs) { +bool WebSourceBufferImpl::CanChangeType(const WebString& content_type, + const WebString& codecs) { return demuxer_->CanChangeType(id_, content_type.Utf8(), codecs.Utf8()); } -void WebSourceBufferImpl::ChangeType(const blink::WebString& content_type, - const blink::WebString& codecs) { +void WebSourceBufferImpl::ChangeType(const WebString& content_type, + const WebString& codecs) { // Caller must first call ResetParserState() to flush any pending frames. DCHECK(!demuxer_->IsParsingMediaSegment(id_)); @@ -219,18 +218,17 @@ client_ = nullptr; } -blink::WebMediaPlayer::TrackType mediaTrackTypeToBlink( - media::MediaTrack::Type type) { +WebMediaPlayer::TrackType mediaTrackTypeToBlink(media::MediaTrack::Type type) { switch (type) { case media::MediaTrack::Audio: - return blink::WebMediaPlayer::kAudioTrack; + return WebMediaPlayer::kAudioTrack; case media::MediaTrack::Text: - return blink::WebMediaPlayer::kTextTrack; + return WebMediaPlayer::kTextTrack; case media::MediaTrack::Video: - return blink::WebMediaPlayer::kVideoTrack; + return WebMediaPlayer::kVideoTrack; } NOTREACHED(); - return blink::WebMediaPlayer::kAudioTrack; + return WebMediaPlayer::kAudioTrack; } void WebSourceBufferImpl::InitSegmentReceived( @@ -238,16 +236,16 @@ DCHECK(tracks.get()); DVLOG(1) << __func__ << " tracks=" << tracks->tracks().size(); - std::vector<blink::WebSourceBufferClient::MediaTrackInfo> trackInfoVector; + std::vector<WebSourceBufferClient::MediaTrackInfo> trackInfoVector; for (const auto& track : tracks->tracks()) { - blink::WebSourceBufferClient::MediaTrackInfo trackInfo; + WebSourceBufferClient::MediaTrackInfo trackInfo; trackInfo.track_type = mediaTrackTypeToBlink(track->type()); - trackInfo.id = blink::WebString::FromUTF8(track->id().value()); - trackInfo.byte_stream_track_id = blink::WebString::FromUTF8( - base::NumberToString(track->bytestream_track_id())); - trackInfo.kind = blink::WebString::FromUTF8(track->kind().value()); - trackInfo.label = blink::WebString::FromUTF8(track->label().value()); - trackInfo.language = blink::WebString::FromUTF8(track->language().value()); + trackInfo.id = WebString::FromUTF8(track->id().value()); + trackInfo.byte_stream_track_id = + WebString::FromUTF8(base::NumberToString(track->bytestream_track_id())); + trackInfo.kind = WebString::FromUTF8(track->kind().value()); + trackInfo.label = WebString::FromUTF8(track->label().value()); + trackInfo.language = WebString::FromUTF8(track->language().value()); trackInfoVector.push_back(trackInfo); }
diff --git a/third_party/blink/renderer/platform/media/web_source_buffer_impl.h b/third_party/blink/renderer/platform/media/web_source_buffer_impl.h index 00f82ec..2e8b3b54 100644 --- a/third_party/blink/renderer/platform/media/web_source_buffer_impl.h +++ b/third_party/blink/renderer/platform/media/web_source_buffer_impl.h
@@ -23,18 +23,18 @@ namespace blink { -class PLATFORM_EXPORT WebSourceBufferImpl : public blink::WebSourceBuffer { +class PLATFORM_EXPORT WebSourceBufferImpl : public WebSourceBuffer { public: WebSourceBufferImpl(const std::string& id, media::ChunkDemuxer* demuxer); WebSourceBufferImpl(const WebSourceBufferImpl&) = delete; WebSourceBufferImpl& operator=(const WebSourceBufferImpl&) = delete; ~WebSourceBufferImpl() override; - // blink::WebSourceBuffer implementation. - void SetClient(blink::WebSourceBufferClient* client) override; + // WebSourceBuffer implementation. + void SetClient(WebSourceBufferClient* client) override; bool GetGenerateTimestampsFlag() override; bool SetMode(AppendMode mode) override; - blink::WebTimeRanges Buffered() override; + WebTimeRanges Buffered() override; double HighestPresentationTimestamp() override; bool EvictCodedFrames(double currentPlaybackTime, size_t newDataSize) override; @@ -46,10 +46,10 @@ double* timestamp_offset) override; void ResetParserState() override; void Remove(double start, double end) override; - bool CanChangeType(const blink::WebString& content_type, - const blink::WebString& codecs) override; - void ChangeType(const blink::WebString& content_type, - const blink::WebString& codecs) override; + bool CanChangeType(const WebString& content_type, + const WebString& codecs) override; + void ChangeType(const WebString& content_type, + const WebString& codecs) override; bool SetTimestampOffset(double offset) override; void SetAppendWindowStart(double start) override; void SetAppendWindowEnd(double end) override; @@ -66,7 +66,7 @@ std::string id_; media::ChunkDemuxer* demuxer_; // Owned by WebMediaPlayerImpl. - blink::WebSourceBufferClient* client_; + WebSourceBufferClient* client_; // Controls the offset applied to timestamps when processing appended media // segments. It is initially 0, which indicates that no offset is being
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 001562d..e6a3edb 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -1022,6 +1022,7 @@ crbug.com/982194 [ Win10 ] fast/writing-mode/border-image-vertical-lr.html [ Failure Pass ] ### Tests passing with LayoutNGBlockFragmentation enabled: +virtual/layout_ng_block_frag/external/wpt/css/css-break/abspos-in-opacity-001.html [ Pass ] virtual/layout_ng_block_frag/external/wpt/css/css-break/avoid-border-break.html [ Pass ] virtual/layout_ng_block_frag/external/wpt/css/css-break/borders-000.html [ Pass ] virtual/layout_ng_block_frag/external/wpt/css/css-break/borders-001.html [ Pass ] @@ -1047,6 +1048,7 @@ virtual/layout_ng_block_frag/external/wpt/css/css-break/out-of-flow-in-multicolumn-030.html [ Pass ] virtual/layout_ng_block_frag/external/wpt/css/css-break/out-of-flow-in-multicolumn-032.html [ Pass ] virtual/layout_ng_block_frag/external/wpt/css/css-break/out-of-flow-in-multicolumn-034.html [ Pass ] +virtual/layout_ng_block_frag/external/wpt/css/css-break/out-of-flow-in-multicolumn-035.html [ Pass ] virtual/layout_ng_block_frag/external/wpt/css/css-break/out-of-flow-in-multicolumn-036.html [ Pass ] virtual/layout_ng_block_frag/external/wpt/css/css-break/out-of-flow-in-multicolumn-038.html [ Pass ] virtual/layout_ng_block_frag/external/wpt/css/css-break/out-of-flow-in-multicolumn-039.html [ Pass ] @@ -1074,6 +1076,7 @@ virtual/layout_ng_block_frag/external/wpt/css/css-break/trailing-child-margin-000.html [ Pass ] virtual/layout_ng_block_frag/external/wpt/css/css-break/trailing-child-margin-002.html [ Pass ] virtual/layout_ng_block_frag/external/wpt/css/css-break/transform-006.html [ Pass ] +virtual/layout_ng_block_frag/external/wpt/css/css-break/transform-008.html [ Pass ] virtual/layout_ng_block_frag/external/wpt/css/css-contain/contain-size-monolithic-002.html [ Pass ] virtual/layout_ng_block_frag/external/wpt/css/css-multicol/abspos-containing-block-outside-spanner.html [ Pass ] virtual/layout_ng_block_frag/external/wpt/css/css-multicol/balance-break-avoidance-001.html [ Pass ] @@ -1151,11 +1154,12 @@ crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/nested-with-padding.html [ Failure ] crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/span/outer-column-break-after-inner-spanner-2.html [ Failure ] crbug.com/1079031 virtual/layout_ng_block_frag/fast/multicol/tall-line-in-short-block.html [ Failure ] -crbug.com/1079031 virtual/layout_ng_block_frag/fast/multicol/transform-with-fixedpos.html [ Failure ] crbug.com/1058792 virtual/layout_ng_block_frag/fast/multicol/vertical-rl/composited-relpos-overlapping-will-change.html [ Failure ] ### With LayoutNGFragmentTraversal (and LayoutNGFragmentItem) enabled: +crbug.com/1225304 virtual/layout_ng_fragment_traversal/external/wpt/css/CSS2/positioning/toogle-abspos-on-relpos-inline-child.html [ Failure ] + # Lots of manual tests here; just skip everything - not too interesting for LayoutNGFragmentTraversal anyway: virtual/layout_ng_fragment_traversal/external/wpt/css/CSS2/cascade/* [ Skip ] virtual/layout_ng_fragment_traversal/external/wpt/css/CSS2/text/* [ Skip ] @@ -3726,6 +3730,7 @@ # Failure due to on-going off-thread paint worklet project. crbug.com/957457 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/invalid-image-pending-script.https.html [ Crash ] +crbug.com/829028 external/wpt/css/css-break/abspos-in-opacity-001.html [ Failure ] crbug.com/829028 external/wpt/css/css-break/avoid-border-break.html [ Failure ] crbug.com/829028 external/wpt/css/css-break/borders-000.html [ Failure ] crbug.com/829028 external/wpt/css/css-break/borders-001.html [ Failure ] @@ -3751,6 +3756,7 @@ crbug.com/829028 external/wpt/css/css-break/out-of-flow-in-multicolumn-030.html [ Failure ] crbug.com/829028 external/wpt/css/css-break/out-of-flow-in-multicolumn-032.html [ Failure ] crbug.com/829028 external/wpt/css/css-break/out-of-flow-in-multicolumn-034.html [ Failure ] +crbug.com/829028 external/wpt/css/css-break/out-of-flow-in-multicolumn-035.html [ Failure ] crbug.com/829028 external/wpt/css/css-break/out-of-flow-in-multicolumn-036.html [ Failure ] crbug.com/829028 external/wpt/css/css-break/out-of-flow-in-multicolumn-038.html [ Failure ] crbug.com/829028 external/wpt/css/css-break/out-of-flow-in-multicolumn-039.html [ Failure ] @@ -3785,6 +3791,8 @@ crbug.com/1058792 external/wpt/css/css-break/transform-005.html [ Failure ] crbug.com/829028 external/wpt/css/css-break/transform-006.html [ Failure ] crbug.com/1058792 external/wpt/css/css-break/transform-007.html [ Failure ] +crbug.com/829028 external/wpt/css/css-break/transform-008.html [ Failure ] +crbug.com/1224888 external/wpt/css/css-break/transform-009.html [ Failure ] crbug.com/1156312 external/wpt/css/css-break/widows-orphans-017.html [ Failure ] crbug.com/829028 external/wpt/css/css-multicol/abspos-containing-block-outside-spanner.html [ Failure ] crbug.com/967329 external/wpt/css/css-multicol/columnfill-auto-max-height-001.html [ Failure ] @@ -3842,6 +3850,7 @@ crbug.com/829028 external/wpt/css/css-multicol/spanner-fragmentation-010.html [ Failure ] crbug.com/829028 external/wpt/css/css-multicol/spanner-fragmentation-011.html [ Failure ] crbug.com/1191124 external/wpt/css/css-multicol/spanner-fragmentation-012.html [ Failure ] +crbug.com/1224888 external/wpt/css/css-multicol/spanner-in-opacity.html [ Failure ] crbug.com/1031667 external/wpt/css/css-pseudo/marker-content-007.tentative.html [ Failure ] crbug.com/1031667 external/wpt/css/css-pseudo/marker-content-008.tentative.html [ Failure ]
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/abspos-in-opacity-000-ref.html b/third_party/blink/web_tests/external/wpt/css/css-break/abspos-in-opacity-000-ref.html new file mode 100644 index 0000000..b7013a9 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-break/abspos-in-opacity-000-ref.html
@@ -0,0 +1,8 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<p>There should be a purple square below.</p> +<div style="width:100px; height:100px; background:blue;"> + <div style="opacity:0.5;"> + <div style="width:100px; height:100px; background:red;"></div> + </div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/abspos-in-opacity-000.html b/third_party/blink/web_tests/external/wpt/css/css-break/abspos-in-opacity-000.html new file mode 100644 index 0000000..f41c0353 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-break/abspos-in-opacity-000.html
@@ -0,0 +1,10 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="https://www.w3.org/TR/css-break-3/"> +<link rel="match" href="abspos-in-opacity-000-ref.html"> +<p>There should be a purple square below.</p> +<div style="columns:2; column-gap:0; column-fill:auto; width:100px; height:100px; background:blue;"> + <div style="opacity:0.5;"> + <div style="position:absolute; width:100px; height:100px; background:red;"></div> + </div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/abspos-in-opacity-001-ref.html b/third_party/blink/web_tests/external/wpt/css/css-break/abspos-in-opacity-001-ref.html new file mode 100644 index 0000000..b7013a9 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-break/abspos-in-opacity-001-ref.html
@@ -0,0 +1,8 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<p>There should be a purple square below.</p> +<div style="width:100px; height:100px; background:blue;"> + <div style="opacity:0.5;"> + <div style="width:100px; height:100px; background:red;"></div> + </div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/abspos-in-opacity-001.html b/third_party/blink/web_tests/external/wpt/css/css-break/abspos-in-opacity-001.html new file mode 100644 index 0000000..e81c558 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-break/abspos-in-opacity-001.html
@@ -0,0 +1,12 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="https://www.w3.org/TR/css-break-3/"> +<link rel="match" href="abspos-in-opacity-001-ref.html"> +<p>There should be a purple square below.</p> +<div style="columns:2; column-gap:0; column-fill:auto; width:100px; height:100px; background:blue;"> + <div style="position:relative;"> + <div style="opacity:0.5; height:200px;"> + <div style="position:absolute; width:50px; height:200px; background:red;"></div> + </div> + </div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/change-inline-color-ref.html b/third_party/blink/web_tests/external/wpt/css/css-break/change-inline-color-ref.html new file mode 100644 index 0000000..7f99f57 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-break/change-inline-color-ref.html
@@ -0,0 +1,16 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="https://www.w3.org/TR/css-break-3/"> +<style> + .fakecolumn { + width: 1em; + text-align: center; + } +</style> +<p>The word PASS should be seen below.</p> +<div style="display:flex; color:green;"> + <div class="fakecolumn">P</div> + <div class="fakecolumn">A</div> + <div class="fakecolumn">S</div> + <div class="fakecolumn">S</div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/change-inline-color.html b/third_party/blink/web_tests/external/wpt/css/css-break/change-inline-color.html new file mode 100644 index 0000000..c4334af --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-break/change-inline-color.html
@@ -0,0 +1,17 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="https://www.w3.org/TR/css-break-3/"> +<link rel="match" href="change-inline-color-ref.html"> +<p>The word PASS should be seen below.</p> +<div style="columns:4; width:4em; text-align:center; column-gap:0; orphans:1; widows:1; color:white;"> + <span id="span"> + P A S S + </span> +</div> +<script> + requestAnimationFrame(()=> { + requestAnimationFrame(()=> { + span.style.color = "green"; + }); + }); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/contain-strict-with-opacity-and-oof-ref.html b/third_party/blink/web_tests/external/wpt/css/css-break/contain-strict-with-opacity-and-oof-ref.html new file mode 100644 index 0000000..a9c82c4 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-break/contain-strict-with-opacity-and-oof-ref.html
@@ -0,0 +1,8 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<p>There should be a (pale) green square below, and no (pale) red.</p> +<div style="will-change:transform; contain:strict; width:100px; height:100px;"> + <div style="opacity:0.2; width:100px; height:100px;"> + <div style="width:100px; height:100px; background:green;"></div> + </div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/contain-strict-with-opacity-and-oof.html b/third_party/blink/web_tests/external/wpt/css/css-break/contain-strict-with-opacity-and-oof.html new file mode 100644 index 0000000..b3323a6 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-break/contain-strict-with-opacity-and-oof.html
@@ -0,0 +1,13 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="https://www.w3.org/TR/css-break-3/"> +<link rel="match" href="contain-strict-with-opacity-and-oof-ref.html"> +<p>There should be a (pale) green square below, and no (pale) red.</p> +<div style="columns:3; margin-top:-50px; column-fill:auto; height:200px;"> + <div style="height:50px;"></div> + <div style="will-change:transform; contain:strict; width:100px; height:100px;"> + <div style="opacity:0.2; width:100px; height:100px; background:red;"> + <div style="position:absolute; width:100px; height:100px; background:green;"></div> + </div> + </div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/out-of-flow-in-multicolumn-035.html b/third_party/blink/web_tests/external/wpt/css/css-break/out-of-flow-in-multicolumn-035.html index 6a2d527..f1fff40 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-break/out-of-flow-in-multicolumn-035.html +++ b/third_party/blink/web_tests/external/wpt/css/css-break/out-of-flow-in-multicolumn-035.html
@@ -11,7 +11,8 @@ column-gap: 0px; height: 100px; width: 100px; - margin-left: -200px; + margin-left: -250px; + margin-top: -50px; } .abs { position: absolute; @@ -31,7 +32,7 @@ <p>Test passes if there is a filled green square and <strong>no red</strong>.</p> <div class="multicol"> <div style="height: 400px;"></div> - <div style="transform: translateX(0);"> + <div style="transform: translate(50px,50px); "> <div style="height: 200px;"></div> <div class="abs"> <div class="fixed"></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/transform-008-ref.html b/third_party/blink/web_tests/external/wpt/css/css-break/transform-008-ref.html new file mode 100644 index 0000000..2a16079 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-break/transform-008-ref.html
@@ -0,0 +1,49 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<style> + .fakecolumn { + width: 100px; + height: 100px; + } + .relpos { + position: relative; + top: 50px; + left: 50px; + width: 50px; + } + .transform { + transform: rotate(45deg); + height: 100%; + } + .abspos { + position: absolute; + width: 100%; + height: 100%; + background: green; + } +</style> +<p>Below there should be two green squares, and one green rectangle between + them. They should all be rotated.</p> +<div style="display:flex;"> + <div class="fakecolumn"> + <div class="relpos" style="margin-top:50px; height:50px;"> + <div class="transform"> + <div class="abspos"></div> + </div> + </div> + </div> + <div class="fakecolumn"> + <div class="relpos" style="height:100px;"> + <div class="transform"> + <div class="abspos"></div> + </div> + </div> + </div> + <div class="fakecolumn"> + <div class="relpos" style="height:50px;"> + <div class="transform"> + <div class="abspos"></div> + </div> + </div> + </div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/transform-008.html b/third_party/blink/web_tests/external/wpt/css/css-break/transform-008.html new file mode 100644 index 0000000..b3b80d7 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-break/transform-008.html
@@ -0,0 +1,31 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="https://www.w3.org/TR/css-break-3/#transforms"> +<link rel="match" href="transform-008-ref.html"> +<style> + .relpos { + position: relative; + top: 50px; + left: 50px; + width: 50px; + } + .transform { + transform: rotate(45deg); + height: 200px; + } + .abspos { + position: absolute; + width: 100%; + height: 100%; + background: green; + } +</style> +<p>Below there should be two green squares, and one green rectangle between + them. They should all be rotated.</p> +<div style="columns:3; column-gap:0; column-fill:auto; width:300px; height:100px;"> + <div class="relpos" style="margin-top:50px;"> + <div class="transform"> + <div class="abspos"></div> + </div> + </div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/transform-009-ref.html b/third_party/blink/web_tests/external/wpt/css/css-break/transform-009-ref.html new file mode 100644 index 0000000..d7d3ebf --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-break/transform-009-ref.html
@@ -0,0 +1,71 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="https://www.w3.org/TR/css-break-3/#transforms"> +<style> + .fakecolumn { + width: 100px; + height: 100px; + } + .relpos { + position: relative; + width: 30px; + top: 50px; + left: 50px; + } + .transform { + transform: rotate(45deg); + height: 100%; + } + .abspos { + position: absolute; + width: 100%; + height: 100%; + background: green; + } +</style> +<p>Below there should be six rotated green rectangles (not all with the same + size).</p> +<div style="display:flex;"> + <div class="fakecolumn"> + <div class="relpos" style="margin-top:50px;"> + <div class="transform" style="height:0;"> + <div class="abspos" style="height:50px;"></div> + </div> + </div> + </div> + <div class="fakecolumn"> + <div class="relpos"> + <div class="transform" style="height:0;"> + <div class="abspos" style="height:100px;"></div> + </div> + </div> + </div> + <div class="fakecolumn"> + <div class="relpos" style="margin-top:50px;"> + <div class="transform" style="height:50px;"> + <div class="abspos" style="top:-50px; height:100px;"></div> + </div> + </div> + </div> + <div class="fakecolumn"> + <div class="relpos"> + <div class="transform" style="height:100px;"> + <div class="abspos"></div> + </div> + </div> + </div> + <div class="fakecolumn"> + <div class="relpos"> + <div class="transform" style="height:0;"> + <div class="abspos" style="height:100px;"></div> + </div> + </div> + </div> + <div class="fakecolumn"> + <div class="relpos"> + <div class="transform" style="height:0;"> + <div class="abspos" style="height:50px;"></div> + </div> + </div> + </div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/transform-009.html b/third_party/blink/web_tests/external/wpt/css/css-break/transform-009.html new file mode 100644 index 0000000..f0653f79 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-break/transform-009.html
@@ -0,0 +1,33 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="https://www.w3.org/TR/css-break-3/#transforms"> +<link rel="match" href="transform-009-ref.html"> +<style> + .relpos { + position: relative; + width: 30px; + top: 50px; + left: 50px; + } + .transform { + transform: rotate(45deg); + height: 150px; + } + .abspos { + position: absolute; + width: 100%; + height: 500px; + top: -200px; + background: green; + } +</style> +<p>Below there should be six rotated green rectangles (not all with the same + size).</p> +<div style="columns:5; column-gap:0; column-fill:auto; width:500px; height:100px;"> + <div style="height:250px;"></div> + <div class="relpos"> + <div class="transform"> + <div class="abspos"></div> + </div> + </div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-multicol/spanner-in-opacity-ref.html b/third_party/blink/web_tests/external/wpt/css/css-multicol/spanner-in-opacity-ref.html new file mode 100644 index 0000000..e981eac --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-multicol/spanner-in-opacity-ref.html
@@ -0,0 +1,8 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<p>Test passes if there is a purple square below.</p> +<div style="width:100px; background:blue;"> + <div style="opacity:0.5;"> + <div style="height:100px; background:red;"></div> + </div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-multicol/spanner-in-opacity.html b/third_party/blink/web_tests/external/wpt/css/css-multicol/spanner-in-opacity.html new file mode 100644 index 0000000..78b1ac8 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-multicol/spanner-in-opacity.html
@@ -0,0 +1,10 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="https://www.w3.org/TR/css-break-3/"> +<link rel="match" href="spanner-in-opacity-ref.html"> +<p>Test passes if there is a purple square below.</p> +<div style="columns:2; column-fill:auto; column-gap:0; width:100px; background:blue;"> + <div style="opacity:0.5;"> + <div style="column-span:all; height:100px; background:red;"></div> + </div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/webaudio/OWNERS b/third_party/blink/web_tests/external/wpt/webaudio/OWNERS index a837fc9b..5248064 100644 --- a/third_party/blink/web_tests/external/wpt/webaudio/OWNERS +++ b/third_party/blink/web_tests/external/wpt/webaudio/OWNERS
@@ -1,2 +1 @@ hongchan@chromium.org -rtoy@chromium.org
diff --git a/third_party/blink/web_tests/webaudio/OWNERS b/third_party/blink/web_tests/webaudio/OWNERS index a837fc9b..5248064 100644 --- a/third_party/blink/web_tests/webaudio/OWNERS +++ b/third_party/blink/web_tests/webaudio/OWNERS
@@ -1,2 +1 @@ hongchan@chromium.org -rtoy@chromium.org
diff --git a/third_party/blink/web_tests/wpt_internal/webid/get-argument-validation.https.html b/third_party/blink/web_tests/wpt_internal/webid/get-argument-validation.https.html index dc71265..a9f70d6f 100644 --- a/third_party/blink/web_tests/wpt_internal/webid/get-argument-validation.https.html +++ b/third_party/blink/web_tests/wpt_internal/webid/get-argument-validation.https.html
@@ -7,20 +7,12 @@ <script src="/resources/testharnessreport.js"></script> <script> - // request - promise_test(async t => { - assert_implements(navigator.id, 'missing navigator.id.'); - const result = navigator.id.get({ - provider: 'https://idp.test', - }); - return promise_rejects_js(t, TypeError, result); - }, "Reject when request is missing"); - // provider promise_test(async t => { assert_implements(navigator.id, 'missing navigator.id.'); const result = navigator.id.get({ - request: '' + client_id: '1', + nonce: '2', }); return promise_rejects_js(t, TypeError, result); }, "Reject when provider is missing" ); @@ -29,7 +21,8 @@ assert_implements(navigator.id, 'missing navigator.id.'); const result = navigator.id.get({ provider: 'not_a_url', - request: '', + client_id: '1', + nonce: '2', }); return promise_rejects_dom(t, 'SyntaxError', result); }, `Reject when provider is an invalid URL`); @@ -39,7 +32,8 @@ assert_implements(navigator.id, 'missing navigator.id.'); const result = navigator.id.get({ provider: 'https://idp.test', - request: '', + client_id: '1', + nonce: '2', mode: 'invalid_mode' }); return promise_rejects_js(t, TypeError, result);
diff --git a/third_party/blink/web_tests/wpt_internal/webid/get-permission-basic.https.html b/third_party/blink/web_tests/wpt_internal/webid/get-permission-basic.https.html index 2de3386..38b450b 100644 --- a/third_party/blink/web_tests/wpt_internal/webid/get-permission-basic.https.html +++ b/third_party/blink/web_tests/wpt_internal/webid/get-permission-basic.https.html
@@ -10,7 +10,8 @@ import {webid_test} from './resources/webid-helper.js'; const test_options = { provider: 'https://idp.test', - request: '' + client_id: '1', + nonce: '2', }; webid_test(async (t, mock) => {
diff --git a/tools/clang/rewrite_raw_ptr_fields/RewriteRawPtrFields.cpp b/tools/clang/rewrite_raw_ptr_fields/RewriteRawPtrFields.cpp index 9107c20..e331dd6 100644 --- a/tools/clang/rewrite_raw_ptr_fields/RewriteRawPtrFields.cpp +++ b/tools/clang/rewrite_raw_ptr_fields/RewriteRawPtrFields.cpp
@@ -241,6 +241,7 @@ return true; case clang::Language::CXX: + case clang::Language::OpenCLCXX: case clang::Language::ObjCXX: return false; } @@ -436,6 +437,12 @@ return !Node.isExplicitSpecialization(); } +// Matches CXXRecordDecls that are classified as trivial: +// https://en.cppreference.com/w/cpp/named_req/TrivialType +AST_MATCHER(clang::CXXRecordDecl, isTrivial) { + return Node.isTrivial(); +} + // Given: // template <typename T, typename T2> void foo(T t, T2 t2) {}; // N1 and N4 // template <typename T2> void foo<int, T2>(int t, T2 t) {}; // N2 @@ -1290,13 +1297,15 @@ match_finder.addMatcher(union_field_decl_matcher, &union_field_decl_writer); // Matches rewritable fields of struct `SomeStruct` if that struct happens to - // be a destination type of a `reinterpret_cast<SomeStruct*>` cast. + // be a destination type of a `reinterpret_cast<SomeStruct*>` cast and is a + // trivial type (otherwise `reinterpret_cast<SomeStruct*>` wouldn't be valid + // before the rewrite if it skipped non-trivial constructors). auto reinterpret_cast_struct_matcher = - cxxReinterpretCastExpr(hasDestinationType( - pointerType(pointee(hasUnqualifiedDesugaredType(recordType( - hasDeclaration(recordDecl(forEach(field_decl_matcher))))))))); - FilteredExprWriter reinterpret_cast_struct_writer(&output_helper, - "reinterpret-cast-struct"); + cxxReinterpretCastExpr(hasDestinationType(pointerType(pointee( + hasUnqualifiedDesugaredType(recordType(hasDeclaration(cxxRecordDecl( + allOf(forEach(field_decl_matcher), isTrivial()))))))))); + FilteredExprWriter reinterpret_cast_struct_writer( + &output_helper, "reinterpret-cast-trivial-type"); match_finder.addMatcher(reinterpret_cast_struct_matcher, &reinterpret_cast_struct_writer);
diff --git a/tools/clang/rewrite_raw_ptr_fields/tests/gen-in-out-arg-expected.txt b/tools/clang/rewrite_raw_ptr_fields/tests/gen-in-out-arg-expected.txt index c174fb7..36a442b 100644 --- a/tools/clang/rewrite_raw_ptr_fields/tests/gen-in-out-arg-expected.txt +++ b/tools/clang/rewrite_raw_ptr_fields/tests/gen-in-out-arg-expected.txt
@@ -1,7 +1,7 @@ ==== BEGIN EDITS ==== include-user-header:::gen-in-out-arg-actual.cc:::-1:::-1:::base/memory/checked_ptr.h r:::gen-in-out-arg-actual.cc:::1090:::3:::CheckedPtr<T> -r:::gen-in-out-arg-actual.cc:::2875:::3:::CheckedPtr<T> +r:::gen-in-out-arg-actual.cc:::2873:::3:::CheckedPtr<T> r:::gen-in-out-arg-actual.cc:::789:::11:::CheckedPtr<SomeClass> r:::gen-in-out-arg-actual.cc:::813:::11:::CheckedPtr<SomeClass> r:::gen-in-out-arg-actual.cc:::842:::11:::CheckedPtr<SomeClass>
diff --git a/tools/clang/rewrite_raw_ptr_fields/tests/gen-reinterpret-cast-expected.txt b/tools/clang/rewrite_raw_ptr_fields/tests/gen-reinterpret-cast-expected.txt index a9a48ba36..1894e20 100644 --- a/tools/clang/rewrite_raw_ptr_fields/tests/gen-reinterpret-cast-expected.txt +++ b/tools/clang/rewrite_raw_ptr_fields/tests/gen-reinterpret-cast-expected.txt
@@ -1,12 +1,13 @@ ==== BEGIN EDITS ==== include-user-header:::gen-reinterpret-cast-actual.cc:::-1:::-1:::base/memory/checked_ptr.h -r:::gen-reinterpret-cast-actual.cc:::1048:::5:::CheckedPtr<int> -r:::gen-reinterpret-cast-actual.cc:::1327:::5:::CheckedPtr<int> -r:::gen-reinterpret-cast-actual.cc:::1445:::5:::CheckedPtr<int> -r:::gen-reinterpret-cast-actual.cc:::976:::5:::CheckedPtr<int> +r:::gen-reinterpret-cast-actual.cc:::1000:::5:::CheckedPtr<int> +r:::gen-reinterpret-cast-actual.cc:::1072:::5:::CheckedPtr<int> +r:::gen-reinterpret-cast-actual.cc:::1459:::5:::CheckedPtr<int> +r:::gen-reinterpret-cast-actual.cc:::2317:::5:::CheckedPtr<int> +r:::gen-reinterpret-cast-actual.cc:::2570:::5:::CheckedPtr<int> ==== END EDITS ==== ==== BEGIN FIELD FILTERS ==== -ReinterpretedClass1::ptr2_ # reinterpret-cast-struct -ReinterpretedClass1::ptr_ # reinterpret-cast-struct -ReinterpretedClass2::ptr_ # reinterpret-cast-struct +ReinterpretedClass1::ptr2_ # reinterpret-cast-trivial-type +ReinterpretedClass1::ptr_ # reinterpret-cast-trivial-type +ReinterpretedClass2::ptr_ # reinterpret-cast-trivial-type ==== END FIELD FILTERS ====
diff --git a/tools/clang/rewrite_raw_ptr_fields/tests/gen-reinterpret-cast-test.cc b/tools/clang/rewrite_raw_ptr_fields/tests/gen-reinterpret-cast-test.cc index 2f9d92b..0e3c16a 100644 --- a/tools/clang/rewrite_raw_ptr_fields/tests/gen-reinterpret-cast-test.cc +++ b/tools/clang/rewrite_raw_ptr_fields/tests/gen-reinterpret-cast-test.cc
@@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <type_traits> + // This file (and other gen-*-test.cc files) tests generation of output for // --field-filter-file and therefore the expectations file // (gen-char-expected.txt) needs to be compared against the raw output of the @@ -22,6 +24,8 @@ // All fields in ReinterpretedClass1 should be emitted. int* ptr2_; }; +static_assert(std::is_trivial<ReinterpretedClass1>::value, + "ReinterpretedClass1 is trivial"); class ReinterpretedClass2 { // The field below should be emitted as candidates for the @@ -30,14 +34,36 @@ // https://crbug.com/1165613. int* ptr_; }; +static_assert(std::is_trivial<ReinterpretedClass2>::value, + "ReinterpretedClass2 is trivial"); + +class ReinterpretedNonTrivialClass3 { + // User-defined constructor means that ReinterpretedNonTrivialClass3 is + // non-trivial. + ReinterpretedNonTrivialClass3() : ptr_(nullptr) {} + + // This field should not be emitted as a candidate for --field-filter-file, + // because we only want to exclude cases where a `reinterpret_cast` is 1) + // valid before the rewrite and 2) invalid after the rewrite (e.g. because it + // skips CheckedPtr's constructors). A reinterpret_cast of a pointer to + // non-trivial type would have been invalid before the rewrite if it skipped + // the (non-trivial) constructors. See also the discussion in + // https://groups.google.com/a/google.com/g/chrome-memory-safety/c/MwnBj_EuILg/m/1cVmcBOMBAAJ + int* ptr_; +}; +static_assert(!std::is_trivial<ReinterpretedNonTrivialClass3>::value, + "ReinterpretedNonTrivialClass3 is *not* trivial"); class SomeOtherClass { // This field should not be emitted as a candidate for --field-filter-file. int* ptr_; }; +static_assert(std::is_trivial<SomeOtherClass>::value, + "SomeOtherClass is trivial"); void foo() { void* void_ptr = nullptr; auto* p1 = reinterpret_cast<ReinterpretedClass1*>(void_ptr); auto* p2 = reinterpret_cast<const ReinterpretedClass2*>(void_ptr); + auto* p3 = reinterpret_cast<const ReinterpretedNonTrivialClass3*>(void_ptr); }
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index 53b6205b..5ff46d9 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -341,6 +341,7 @@ 'linux-chromeos-js-code-coverage': 'chromeos_with_codecs_release_bot_javascript_coverage', 'linux-chromium-tests-staging-builder': 'release_bot', 'linux-code-coverage': 'clang_code_coverage', + 'linux-exp-code-coverage': 'clang_code_coverage', 'linux-example-builder': 'release_bot', 'linux-fieldtrial-rel': 'release_bot_minimal_symbols', 'linux-backuprefptr-x64-fyi-rel': 'release_trybot_backuprefptr_x64',
diff --git a/tools/mb/mb_config_expectations/chromium.fyi.json b/tools/mb/mb_config_expectations/chromium.fyi.json index 887d811..b7d21d8 100644 --- a/tools/mb/mb_config_expectations/chromium.fyi.json +++ b/tools/mb/mb_config_expectations/chromium.fyi.json
@@ -900,6 +900,16 @@ "use_goma": true } }, + "linux-exp-code-coverage": { + "gn_args": { + "is_clang": true, + "is_component_build": false, + "is_debug": false, + "symbol_level": 0, + "use_clang_coverage": true, + "use_goma": true + } + }, "linux-fieldtrial-rel": { "gn_args": { "is_component_build": false,
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index c79ad39..4649c32 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -25868,7 +25868,7 @@ <int value="862" label="DeviceScheduledReboot"/> <int value="863" label="ReportDeviceLoginLogout"/> <int value="864" label="RemoteDebuggingAllowed"/> - <int value="865" label="ManagedWebAppsAccessToDeviceAttributesAllowed"/> + <int value="865" label="DeviceAttributesAllowedForOrigins"/> <int value="866" label="BrowserSwitcherParsingMode"/> <int value="867" label="DefaultJavaScriptJitSetting"/> <int value="868" label="JavaScriptJitAllowedForSites"/> @@ -46671,6 +46671,7 @@ <int value="-1720653947" label="WebRtcHybridAgc:disabled"/> <int value="-1719833926" label="disable-answers-in-suggest"/> <int value="-1719699712" label="AudioPlayerJsModules:enabled"/> + <int value="-1718644168" label="SharingHubLinkToggle:disabled"/> <int value="-1718074215" label="HomepageSettingsUIConversion:enabled"/> <int value="-1716654100" label="tab-capture-downscale-quality"/> <int value="-1716140224" label="EnableEmbeddedAssistantUI:disabled"/> @@ -50837,6 +50838,7 @@ <int value="1717788959" label="SlowDCTimerInterruptsWin:disabled"/> <int value="1717987538" label="NTPTilesLowerResolutionFavicons:enabled"/> <int value="1718341860" label="NTPButton:enabled"/> + <int value="1718421370" label="SharingHubLinkToggle:enabled"/> <int value="1719189460" label="EnablePasswordSelection:disabled"/> <int value="1719958026" label="QueryTiles:enabled"/> <int value="1722748383" label="EnableAppReinstallZeroState:disabled"/>
diff --git a/tools/metrics/histograms/histograms_xml/memory/histograms.xml b/tools/metrics/histograms/histograms_xml/memory/histograms.xml index 097f1c5c..aa9fdda 100644 --- a/tools/metrics/histograms/histograms_xml/memory/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/memory/histograms.xml
@@ -1921,7 +1921,7 @@ </histogram> <histogram name="Memory.PaintPreviewCompositor.ResidentSet" units="MiB" - expires_after="2021-08-15"> + expires_after="2021-10-17"> <owner>ckitagawa@chromium.org</owner> <owner>fredmello@chromium.org</owner> <owner>mahmoudi@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/service/histograms.xml b/tools/metrics/histograms/histograms_xml/service/histograms.xml index b7b7258..a3adf1e 100644 --- a/tools/metrics/histograms/histograms_xml/service/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/service/histograms.xml
@@ -1185,7 +1185,7 @@ </histogram> <histogram name="ServiceWorkerCache.Cache.Browser.Match.RelatedFetchEvent" - units="ms" expires_after="2021-08-01"> + units="ms" expires_after="2022-08-01"> <owner>wanderview@chromium.org</owner> <owner>chrome-owp-storage@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/histograms_xml/web_audio/histograms.xml b/tools/metrics/histograms/histograms_xml/web_audio/histograms.xml index ca13433..8aaed2c 100644 --- a/tools/metrics/histograms/histograms_xml/web_audio/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/web_audio/histograms.xml
@@ -23,7 +23,6 @@ <histogram name="WebAudio.AudioBuffer.Length" units="frames" expires_after="2021-08-22"> - <owner>rtoy@chromium.org</owner> <owner>hongchan@chromium.org</owner> <summary> The length (in frames) requested by createBuffer(). Recorded for every call @@ -33,7 +32,6 @@ <histogram name="WebAudio.AudioBuffer.NumberOfChannels" units="units" expires_after="2021-11-14"> - <owner>rtoy@chromium.org</owner> <owner>hongchan@chromium.org</owner> <summary> The number of channels requested by createBuffer(). Recorded for every call @@ -43,7 +41,6 @@ <histogram name="WebAudio.AudioBuffer.SampleRate384kHz" units="Hz" expires_after="2021-12-26"> - <owner>rtoy@chromium.org</owner> <owner>hongchan@chromium.org</owner> <summary> The sample rate (in Hz) requested by createBuffer(). Recorded for every call @@ -53,7 +50,6 @@ <histogram name="WebAudio.AudioBuffer.SampleRateRatio384kHz" units="units" expires_after="2021-10-25"> - <owner>rtoy@chromium.org</owner> <owner>hongchan@chromium.org</owner> <summary> The ratio of the buffer sample rate from createBuffer() to the context @@ -64,7 +60,6 @@ <histogram name="WebAudio.AudioContext.HardwareSampleRate" units="Hz" expires_after="2021-09-05"> - <owner>rtoy@chromium.org</owner> <owner>hongchan@chromium.org</owner> <summary> The hardware sample rate (in Hz) used by an AudioContext. Recorded for every @@ -74,7 +69,6 @@ <histogram name="WebAudio.AudioContext.latencyHintCategory" units="units" expires_after="2022-01-02"> - <owner>rtoy@chromium.org</owner> <owner>hongchan@chromium.org</owner> <summary> If provided, the latencyHint option category of "interactive", @@ -87,7 +81,6 @@ <histogram name="WebAudio.AudioContext.latencyHintMilliSeconds" units="ms" expires_after="2022-01-02"> - <owner>rtoy@chromium.org</owner> <owner>hongchan@chromium.org</owner> <summary> If the latencyHint is provided and is a floating-point number, the value in @@ -98,7 +91,6 @@ <histogram name="WebAudio.AudioContext.MaxChannelsAvailable" units="units" expires_after="2022-01-06"> - <owner>rtoy@chromium.org</owner> <owner>hongchan@chromium.org</owner> <summary> The maximum number of (hardware) channels available in an AudioContext. @@ -109,7 +101,6 @@ <histogram name="WebAudio.AudioContextOptions.sampleRate" units="Hz" expires_after="2021-08-09"> - <owner>rtoy@chromium.org</owner> <owner>hongchan@chromium.org</owner> <summary> The sample rate requested by developer to be used as the sample rate when @@ -120,7 +111,6 @@ <histogram name="WebAudio.AudioContextOptions.sampleRateRatio" units="units" expires_after="2021-08-09"> - <owner>rtoy@chromium.org</owner> <owner>hongchan@chromium.org</owner> <summary> The ratio of the user-selected sample rate to the hardware sample rate of an @@ -131,7 +121,6 @@ <histogram name="WebAudio.AudioDestination.CallbackBufferSize" units="units" expires_after="2021-09-05"> - <owner>rtoy@chromium.org</owner> <owner>hongchan@chromium.org</owner> <summary> The callback buffer size (in audio frames) for WebAudio rendering between @@ -143,7 +132,6 @@ <histogram name="WebAudio.AudioDestination.HardwareBufferSize" units="units" expires_after="2021-12-12"> - <owner>rtoy@chromium.org</owner> <owner>hongchan@chromium.org</owner> <summary> The buffer size (in audio frames) for WebAudio rendering recommended by the @@ -155,7 +143,6 @@ expires_after="2021-08-09"> <owner>hongchan@chromium.org</owner> <owner>media-dev@chromium.org</owner> - <owner>rtoy@chromium.org</owner> <summary> The autoplay status of an AudioContext when destroyed. This include all types of frames. In order to know the value only for main frames, the @@ -167,7 +154,6 @@ expires_after="2021-10-04"> <owner>hongchan@chromium.org</owner> <owner>media-dev@chromium.org</owner> - <owner>rtoy@chromium.org</owner> <summary> The autoplay status of an AudioContext when destroyed in a cross-origin frame. @@ -178,7 +164,6 @@ enum="WebAudioAutoplayUnlockType" expires_after="2021-06-01"> <owner>hongchan@chromium.org</owner> <owner>media-dev@chromium.org</owner> - <owner>rtoy@chromium.org</owner> <summary> Records how an AudioContext was unlocked (if it was). This is recorded when the AudioContext is destroyed. @@ -187,7 +172,6 @@ <histogram name="WebAudio.BiquadFilter.Type" enum="BiquadFilterType" expires_after="2022-01-06"> - <owner>rtoy@chromium.org</owner> <owner>hongchan@chromium.org</owner> <summary> The type of the BiquadFilterNode. Recorded each time the type is set. This @@ -199,7 +183,6 @@ <histogram name="WebAudio.ConvolverNode.ImpulseResponseLength" units="ms" expires_after="2021-12-19"> - <owner>rtoy@chromium.org</owner> <owner>hongchan@chromium.org</owner> <summary> The duration in millisec of impulse responses for a ConvolverNode. Recorded @@ -209,7 +192,6 @@ <histogram name="WebAudio.IIRFilterNode.Order" units="units" expires_after="2022-01-06"> - <owner>rtoy@chromium.org</owner> <owner>hongchan@chromium.org</owner> <summary> The order of the WebAudio IIRFilterNode. The order is one less than the @@ -223,7 +205,6 @@ <obsolete> Removed 2021-01-12. See crbug.com/1165240. </obsolete> - <owner>rtoy@chromium.org</owner> <owner>hongchan@chromium.org</owner> <summary> The number of channels specified for the offline audio context. Recorded for @@ -237,7 +218,6 @@ <obsolete> Removed 2021-01-12. See crbug.com/1165240. </obsolete> - <owner>rtoy@chromium.org</owner> <owner>hongchan@chromium.org</owner> <summary> The length (in frames) specified for the offline audio context. Recorded for @@ -251,7 +231,6 @@ <obsolete> Removed 2021-01-12. See crbug.com/1165240. </obsolete> - <owner>rtoy@chromium.org</owner> <owner>hongchan@chromium.org</owner> <summary> The sample rate (in Hz) specified for the offline audio context. Recorded @@ -262,7 +241,6 @@ <histogram name="WebAudio.PannerNode.PanningModel" enum="PanningModelType" expires_after="2022-01-06"> - <owner>rtoy@chromium.org</owner> <owner>hongchan@chromium.org</owner> <summary> The panning model for the PannerNode. Recorded once with the default value @@ -275,7 +253,6 @@ <histogram name="WebAudio.PushPullFIFO.UnderflowGlitches" enum="Boolean" expires_after="2022-01-06"> - <owner>rtoy@chromium.org</owner> <owner>hongchan@chromium.org</owner> <summary> Captures if WebAudio caused glitches or not due to the FIFO underflow. It is @@ -286,7 +263,6 @@ <histogram name="WebAudio.PushPullFIFO.UnderflowPercentage" units="%" expires_after="2022-01-06"> - <owner>rtoy@chromium.org</owner> <owner>hongchan@chromium.org</owner> <summary> Percentage of FIFO underflow happened due to the the missed deadline of
diff --git a/tools/perf/OWNERS b/tools/perf/OWNERS index 6fe36de..05eacd34 100644 --- a/tools/perf/OWNERS +++ b/tools/perf/OWNERS
@@ -18,6 +18,9 @@ eyaich@chromium.org sullivan@chromium.org +# For V8 and system_health stories. +cbruni@chromium.org + # For page_cycler and loading benchmarks related changes. kouhei@chromium.org
diff --git a/tools/perf/benchmark.csv b/tools/perf/benchmark.csv index 74b3a56..592d70c 100644 --- a/tools/perf/benchmark.csv +++ b/tools/perf/benchmark.csv
@@ -22,7 +22,7 @@ blink_perf.sanitizer-api,lyf@chromium.org,Blink>Security>SanitizerAPI,https://bit.ly/blink-perf-benchmarks,all blink_perf.shadow_dom,masonf@chromium.org,Blink>DOM>ShadowDOM,https://bit.ly/blink-perf-benchmarks,all blink_perf.svg,"fs@opera.com, pdr@chromium.org",Blink>SVG,https://bit.ly/blink-perf-benchmarks,all -blink_perf.webaudio,"hongchan@chromium.org, rtoy@chromium.org",Blink>WebAudio,https://bit.ly/blink-perf-benchmarks,all +blink_perf.webaudio,hongchan@chromium.org,Blink>WebAudio,https://bit.ly/blink-perf-benchmarks,all blink_perf.webgl,"kbr@chromium.org, enga@chromium.org, webgl-team@google.com",Blink>WebGL,https://bit.ly/blink-perf-benchmarks, blink_perf.webgl_fast_call,"kbr@chromium.org, enga@chromium.org, mslekova@chromium.org, junov@chromium.org, webgl-team@google.com",Blink>WebGL,https://bit.ly/blink-perf-benchmarks, blink_perf.webgpu,"enga@chromium.org, cwallez@chromium.org, webgpu-developers@google.com",Blink>WebGPU,https://bit.ly/blink-perf-benchmarks,
diff --git a/tools/perf/benchmarks/blink_perf.py b/tools/perf/benchmarks/blink_perf.py index 466ef6f..d50c14b 100644 --- a/tools/perf/benchmarks/blink_perf.py +++ b/tools/perf/benchmarks/blink_perf.py
@@ -701,7 +701,8 @@ options.AppendExtraBrowserArgs( ['--enable-blink-features=DisplayLocking,CSSContentSize']) -@benchmark.Info(emails=['hongchan@chromium.org', 'rtoy@chromium.org'], + +@benchmark.Info(emails=['hongchan@chromium.org'], component='Blink>WebAudio', documentation_url='https://bit.ly/blink-perf-benchmarks') class BlinkPerfWebAudio(_BlinkPerfBenchmark):
diff --git a/ui/accessibility/accessibility_features.cc b/ui/accessibility/accessibility_features.cc index b9049968..574f23f9c 100644 --- a/ui/accessibility/accessibility_features.cc +++ b/ui/accessibility/accessibility_features.cc
@@ -91,6 +91,16 @@ bool IsIChromeAccessibleEnabled() { return base::FeatureList::IsEnabled(::features::kIChromeAccessible); } + +const base::Feature kSelectiveUIAEnablement{"SelectiveUIAEnablement", + base::FEATURE_DISABLED_BY_DEFAULT}; + +// Returns true if accessibility will be selectively enabled depending on the +// UIA APIs that are called, allowing non-screenreader usage to enable less of +// the accessibility system. +bool IsSelectiveUIAEnablementEnabled() { + return base::FeatureList::IsEnabled(::features::kSelectiveUIAEnablement); +} #endif // defined(OS_WIN) #if BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/ui/accessibility/accessibility_features.h b/ui/accessibility/accessibility_features.h index e2e6f697..28174e76 100644 --- a/ui/accessibility/accessibility_features.h +++ b/ui/accessibility/accessibility_features.h
@@ -75,6 +75,13 @@ // Returns true if the IChromeAccessible COM API is enabled. AX_BASE_EXPORT bool IsIChromeAccessibleEnabled(); +AX_BASE_EXPORT extern const base::Feature kSelectiveUIAEnablement; + +// Returns true if accessibility will be selectively enabled depending on the +// UIA APIs that are called, allowing non-screenreader usage to enable less of +// the accessibility system. +AX_BASE_EXPORT bool IsSelectiveUIAEnablementEnabled(); + #endif // defined(OS_WIN) #if BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/ui/accessibility/ax_mode.h b/ui/accessibility/ax_mode.h index 6bac8eb8..0bb0d50 100644 --- a/ui/accessibility/ax_mode.h +++ b/ui/accessibility/ax_mode.h
@@ -121,6 +121,13 @@ AXMode::kInlineTextBoxes | AXMode::kScreenReader | AXMode::kHTML); +// Similar to kAXModeComplete, used when an AT that requires full accessibility +// access, but does not need all HTML properties or attributes. +static constexpr AXMode kAXModeCompleteNoHTML(AXMode::kNativeAPIs | + AXMode::kWebContents | + AXMode::kInlineTextBoxes | + AXMode::kScreenReader); + // For debugging, test assertions, etc. AX_BASE_EXPORT std::ostream& operator<<(std::ostream& stream, const AXMode& mode);
diff --git a/ui/accessibility/platform/ax_fragment_root_win.cc b/ui/accessibility/platform/ax_fragment_root_win.cc index 7a180e4..fa7624a 100644 --- a/ui/accessibility/platform/ax_fragment_root_win.cc +++ b/ui/accessibility/platform/ax_fragment_root_win.cc
@@ -326,7 +326,7 @@ // Automation. Signal observers when we're asked for a platform object on it. for (WinAccessibilityAPIUsageObserver& observer : GetWinAccessibilityAPIUsageObserverList()) { - observer.OnUIAutomationUsed(); + observer.OnBasicUIAutomationUsed(); } return platform_node_.Get(); }
diff --git a/ui/accessibility/platform/ax_platform_node_win.cc b/ui/accessibility/platform/ax_platform_node_win.cc index 6fb0a48..c727ff3 100644 --- a/ui/accessibility/platform/ax_platform_node_win.cc +++ b/ui/accessibility/platform/ax_platform_node_win.cc
@@ -4185,6 +4185,7 @@ IUnknown** result) { WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_PATTERN_PROVIDER); WIN_ACCESSIBILITY_API_PERF_HISTOGRAM(UMA_API_GET_PATTERN_PROVIDER); + NotifyAPIObserverForPatternRequest(pattern_id); return GetPatternProviderImpl(pattern_id, result); } @@ -4217,6 +4218,9 @@ // Collapse all unknown property IDs into a single bucket. base::UmaHistogramSparse("Accessibility.WinAPIs.GetPropertyValue", 0); } + + NotifyAPIObserverForPropertyRequest(property_id); + return GetPropertyValueImpl(property_id, result); } @@ -8230,6 +8234,92 @@ SanitizeStringAttributeForIA2(input, output); } +void AXPlatformNodeWin::NotifyAPIObserverForPatternRequest( + PATTERNID pattern_id) const { + bool probable_advanced_client_detected = false; + bool text_pattern_support_needed = false; + switch (pattern_id) { + case UIA_TextPatternId: + case UIA_TextChildPatternId: + // These properties require information gated behind the kInlineTextBoxes + // AXMode. See kInlineTextBoxes for details. + text_pattern_support_needed = true; + break; + // These properties require more advanced accessibility features to be + // enabled See kScreenReader for details. + case UIA_RangeValuePatternId: + case UIA_TableItemPatternId: + probable_advanced_client_detected = true; + break; + } + + for (WinAccessibilityAPIUsageObserver& observer : + GetWinAccessibilityAPIUsageObserverList()) { + if (probable_advanced_client_detected) + observer.OnAdvancedUIAutomationUsed(); + if (text_pattern_support_needed) + observer.OnTextPatternRequested(); + } +} +void AXPlatformNodeWin::NotifyAPIObserverForPropertyRequest( + PROPERTYID property_id) const { + bool probable_advanced_client_detected = false; + bool probable_screen_reader_detected = false; + switch (property_id) { + // These properties are used by non-screenreader UIA clients. They should + // not cause additional enablement. + case UIA_ControlTypePropertyId: + case UIA_HasKeyboardFocusPropertyId: + case UIA_IsControlElementPropertyId: + case UIA_FrameworkIdPropertyId: + case UIA_IsEnabledPropertyId: + break; + // These properties are not currently implemented and should not cause + // enablement. + case UIA_AnnotationTypesPropertyId: + case UIA_CenterPointPropertyId: + case UIA_FillColorPropertyId: + case UIA_FillTypePropertyId: + case UIA_HeadingLevelPropertyId: + case UIA_ItemTypePropertyId: + case UIA_OutlineColorPropertyId: + case UIA_OutlineThicknessPropertyId: + case UIA_RotationPropertyId: + case UIA_SizePropertyId: + case UIA_VisualEffectsPropertyId: + break; + // These properties are provided by UIA Core; we should not implement, and + // they should not cause enablement. + case UIA_BoundingRectanglePropertyId: + case UIA_NativeWindowHandlePropertyId: + case UIA_ProcessIdPropertyId: + case UIA_ProviderDescriptionPropertyId: + case UIA_RuntimeIdPropertyId: + break; + // These properties are indicative of a screenreader, we should enable full + // accessibility support. + case UIA_AriaRolePropertyId: + case UIA_LabeledByPropertyId: + case UIA_LiveSettingPropertyId: + case UIA_LevelPropertyId: + case UIA_DescribedByPropertyId: + probable_screen_reader_detected = true; + probable_advanced_client_detected = true; + break; + default: + // All other properties should cause us to enable. + probable_advanced_client_detected = true; + } + + for (WinAccessibilityAPIUsageObserver& observer : + GetWinAccessibilityAPIUsageObserverList()) { + if (probable_advanced_client_detected) + observer.OnAdvancedUIAutomationUsed(); + if (probable_screen_reader_detected) + observer.OnProbableUIAutomationScreenReaderDetected(); + } +} + // static void AXPlatformNodeWin::SanitizeStringAttributeForIA2(const std::string& input, std::string* output) {
diff --git a/ui/accessibility/platform/ax_platform_node_win.h b/ui/accessibility/platform/ax_platform_node_win.h index 84a21ed..91f114d 100644 --- a/ui/accessibility/platform/ax_platform_node_win.h +++ b/ui/accessibility/platform/ax_platform_node_win.h
@@ -341,7 +341,10 @@ virtual void OnIAccessible2Used() = 0; virtual void OnScreenReaderHoneyPotQueried() = 0; virtual void OnAccNameCalled() = 0; - virtual void OnUIAutomationUsed() = 0; + virtual void OnBasicUIAutomationUsed() = 0; + virtual void OnAdvancedUIAutomationUsed() = 0; + virtual void OnProbableUIAutomationScreenReaderDetected() = 0; + virtual void OnTextPatternRequested() = 0; virtual void StartFiringUIAEvents() = 0; virtual void EndFiringUIAEvents() = 0; }; @@ -1470,6 +1473,9 @@ const std::wstring& active_composition_text, bool is_composition_committed); + void NotifyAPIObserverForPatternRequest(PATTERNID pattern_id) const; + void NotifyAPIObserverForPropertyRequest(PROPERTYID property_id) const; + // Return true if the given element is valid enough to be returned as a value // for a UIA relation property (e.g. ControllerFor). static bool IsValidUiaRelationTarget(AXPlatformNode* ax_platform_node);
diff --git a/ui/accessibility/platform/inspect/ax_tree_formatter_base.cc b/ui/accessibility/platform/inspect/ax_tree_formatter_base.cc index 33fb9f61..5209fcfd 100644 --- a/ui/accessibility/platform/inspect/ax_tree_formatter_base.cc +++ b/ui/accessibility/platform/inspect/ax_tree_formatter_base.cc
@@ -76,8 +76,9 @@ return contents; for (const base::Value& script : scripts->GetList()) { - WriteAttribute(true, script.GetString(), &contents); - contents += "\n"; + std::string line; + WriteAttribute(true, script.GetString(), &line); + contents += line + "\n"; } return contents;
diff --git a/ui/android/java/res/values/color_palette.xml b/ui/android/java/res/values/color_palette.xml index 54a25a3..801e5e3 100644 --- a/ui/android/java/res/values/color_palette.xml +++ b/ui/android/java/res/values/color_palette.xml
@@ -6,19 +6,30 @@ --> <resources xmlns:tools="http://schemas.android.com/tools"> <!-- 2021 color palette --> + <color name="baseline_error_200">#F2B8B5</color> + <color name="baseline_error_600">#B3261E</color> + <color name="baseline_primary_0">@android:color/white</color> <color name="baseline_primary_100">#D3E3FD</color> <color name="baseline_primary_200">#A8C7FA</color> <color name="baseline_primary_600">#0B57D0</color> <color name="baseline_primary_800">#062E6F</color> <color name="baseline_primary_900">#041E49</color> + <color name="baseline_neutral_0">@android:color/white</color> + <color name="baseline_neutral_50">#F2F2F2</color> <color name="baseline_neutral_100">#E3E3E3</color> <color name="baseline_neutral_100_alpha_12">#1EE3E3E3</color> + <color name="baseline_neutral_200">#C7C7C7</color> + <color name="baseline_neutral_600">#5E5E5E</color> + <color name="baseline_neutral_800">#303030</color> + <color name="baseline_neutral_900">#1F1F1F</color> <color name="baseline_neutral_900_alpha_12">#1E1F1F1F</color> <color name="baseline_neutral_900_with_neutral_100_alpha_38">#696969</color> <color name="baseline_neutral_variant_100">#E1E3E1</color> <color name="baseline_neutral_variant_200">#C4C7C5</color> <color name="baseline_neutral_variant_200_alpha_15">#26C4C7C5</color> <color name="baseline_neutral_variant_400">#8E918F</color> + <color name="baseline_neutral_variant_500">#747775</color> + <color name="baseline_neutral_variant_700">#444746</color> <color name="baseline_neutral_900_with_neutral_200_alpha_12_with_primary_200_alpha_2">#353637</color>
diff --git a/ui/base/x/x11_gl_egl_utility.cc b/ui/base/x/x11_gl_egl_utility.cc index 8464e44..624c6f9 100644 --- a/ui/base/x/x11_gl_egl_utility.cc +++ b/ui/base/x/x11_gl_egl_utility.cc
@@ -39,20 +39,8 @@ void GetPlatformExtraDisplayAttribs(EGLenum platform_type, std::vector<EGLAttrib>* attributes) { - // ANGLE_NULL and SwiftShader backends don't use the visual, - // and may run without X11 where we can't get it anyway. - if ((platform_type != EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE) && - (std::find(attributes->begin(), attributes->end(), - EGL_PLATFORM_ANGLE_DEVICE_TYPE_SWIFTSHADER_ANGLE) == - attributes->end())) { - x11::VisualId visual_id; - XVisualManager::GetInstance()->ChooseVisualForWindow( - true, &visual_id, nullptr, nullptr, nullptr); - attributes->push_back(EGL_X11_VISUAL_ID_ANGLE); - attributes->push_back(static_cast<EGLAttrib>(visual_id)); - attributes->push_back(EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE); - attributes->push_back(EGL_PLATFORM_X11_EXT); - } + attributes->push_back(EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE); + attributes->push_back(EGL_PLATFORM_X11_EXT); } void ChoosePlatformCustomAlphaAndBufferSize(EGLint* alpha_size,
diff --git a/ui/ozone/platform/wayland/host/wayland_data_drag_controller_unittest.cc b/ui/ozone/platform/wayland/host/wayland_data_drag_controller_unittest.cc index 541702c..eaed1f56 100644 --- a/ui/ozone/platform/wayland/host/wayland_data_drag_controller_unittest.cc +++ b/ui/ozone/platform/wayland/host/wayland_data_drag_controller_unittest.cc
@@ -811,12 +811,12 @@ // Override test server's data device drag delegate such that // wl_data_device.start_drag no-ops. - struct NoopDragDeviceDelegate : public wl::TestDataDevice::Delegate { + struct NoopDragDeviceDelegate : public wl::TestDataDevice::DragDelegate { void StartDrag(wl::TestDataSource* source, wl::MockSurface* origin, uint32_t serial) override {} } noop_drag_delegate; - data_device_manager_->data_device()->set_delegate(&noop_drag_delegate); + data_device_manager_->data_device()->set_drag_delegate(&noop_drag_delegate); FocusAndPressLeftPointerButton(window_.get(), &delegate_);
diff --git a/ui/ozone/platform/wayland/test/test_data_device.cc b/ui/ozone/platform/wayland/test/test_data_device.cc index 6fc8a3e..dface6c7 100644 --- a/ui/ozone/platform/wayland/test/test_data_device.cc +++ b/ui/ozone/platform/wayland/test/test_data_device.cc
@@ -64,8 +64,8 @@ uint32_t serial) { DCHECK(source); DCHECK(origin); - if (delegate_) - delegate_->StartDrag(source, origin, serial); + if (drag_delegate_) + drag_delegate_->StartDrag(source, origin, serial); wl_client_flush(client_); }
diff --git a/ui/ozone/platform/wayland/test/test_data_device.h b/ui/ozone/platform/wayland/test/test_data_device.h index 85ad4af..1b8805c 100644 --- a/ui/ozone/platform/wayland/test/test_data_device.h +++ b/ui/ozone/platform/wayland/test/test_data_device.h
@@ -25,7 +25,7 @@ class TestDataDevice : public ServerObject { public: - struct Delegate { + struct DragDelegate { virtual void StartDrag(TestDataSource* source, MockSurface* origin, uint32_t serial) = 0; @@ -34,7 +34,7 @@ TestDataDevice(wl_resource* resource, wl_client* client); ~TestDataDevice() override; - void set_delegate(Delegate* delegate) { delegate_ = delegate; } + void set_drag_delegate(DragDelegate* delegate) { drag_delegate_ = delegate; } void SetSelection(TestDataSource* data_source, uint32_t serial); void StartDrag(TestDataSource* data_source, @@ -55,7 +55,7 @@ private: TestDataOffer* data_offer_; wl_client* client_ = nullptr; - Delegate* delegate_ = nullptr; + DragDelegate* drag_delegate_ = nullptr; DISALLOW_COPY_AND_ASSIGN(TestDataDevice); };
diff --git a/ui/ozone/platform/wayland/test/wayland_drag_drop_test.cc b/ui/ozone/platform/wayland/test/wayland_drag_drop_test.cc index cf0b379f..739e424 100644 --- a/ui/ozone/platform/wayland/test/wayland_drag_drop_test.cc +++ b/ui/ozone/platform/wayland/test/wayland_drag_drop_test.cc
@@ -98,15 +98,15 @@ ASSERT_TRUE(data_device_manager_); data_source_ = nullptr; - data_device_manager_->data_device()->set_delegate(this); + data_device_manager_->data_device()->set_drag_delegate(this); } void WaylandDragDropTest::TearDown() { - data_device_manager_->data_device()->set_delegate(nullptr); + data_device_manager_->data_device()->set_drag_delegate(nullptr); data_device_manager_ = nullptr; } -// wl::TestDataDevice::Delegate: +// wl::TestDataDevice::DragDelegate: void WaylandDragDropTest::StartDrag(wl::TestDataSource* source, wl::MockSurface* origin, uint32_t serial) {
diff --git a/ui/ozone/platform/wayland/test/wayland_drag_drop_test.h b/ui/ozone/platform/wayland/test/wayland_drag_drop_test.h index 0bf5e67..cd7a238 100644 --- a/ui/ozone/platform/wayland/test/wayland_drag_drop_test.h +++ b/ui/ozone/platform/wayland/test/wayland_drag_drop_test.h
@@ -27,7 +27,7 @@ // emulate dnd-related events from the test compositor and can be used in both // data and window dragging test cases. class WaylandDragDropTest : public WaylandTest, - public wl::TestDataDevice::Delegate { + public wl::TestDataDevice::DragDelegate { public: WaylandDragDropTest(); WaylandDragDropTest(const WaylandDragDropTest&) = delete; @@ -56,7 +56,7 @@ void SetUp() override; void TearDown() override; - // wl::TestDataDevice::Delegate: + // wl::TestDataDevice::DragDelegate: void StartDrag(wl::TestDataSource* source, wl::MockSurface* origin, uint32_t serial) override;
diff --git a/ui/views/controls/webview/web_dialog_view.cc b/ui/views/controls/webview/web_dialog_view.cc index 606f82c..aba1ecf 100644 --- a/ui/views/controls/webview/web_dialog_view.cc +++ b/ui/views/controls/webview/web_dialog_view.cc
@@ -54,18 +54,6 @@ delegate_->OnWebContentsFinishedLoad(); } -void ObservableWebView::ResourceLoadComplete( - content::RenderFrameHost* render_frame_host, - const content::GlobalRequestID& request_id, - const blink::mojom::ResourceLoadInfo& resource_load_info) { - // Only listen to the main frame. - if (render_frame_host->GetParent()) - return; - - if (delegate_) - delegate_->OnMainFrameResourceLoadComplete(resource_load_info); -} - void ObservableWebView::ResetDelegate() { delegate_ = nullptr; }
diff --git a/ui/views/controls/webview/web_dialog_view.h b/ui/views/controls/webview/web_dialog_view.h index 978155ad..d4d63380 100644 --- a/ui/views/controls/webview/web_dialog_view.h +++ b/ui/views/controls/webview/web_dialog_view.h
@@ -26,7 +26,6 @@ namespace content { class BrowserContext; class RenderFrameHost; -struct GlobalRequestID; } // namespace content namespace views { @@ -45,10 +44,6 @@ // content::WebContentsObserver void DidFinishLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url) override; - void ResourceLoadComplete( - content::RenderFrameHost* render_frame_host, - const content::GlobalRequestID& request_id, - const blink::mojom::ResourceLoadInfo& resource_load_info) override; // Resets the delegate. The delegate will no longer receive calls after this // point.
diff --git a/ui/views/controls/webview/web_dialog_view_unittest.cc b/ui/views/controls/webview/web_dialog_view_unittest.cc index 352ffe7..18a6a3d 100644 --- a/ui/views/controls/webview/web_dialog_view_unittest.cc +++ b/ui/views/controls/webview/web_dialog_view_unittest.cc
@@ -177,12 +177,6 @@ EXPECT_FALSE(web_view_delegate()); ResetWebDialogDelegate(); - // Calling back to web view's ResourceLoadComplete() should not cause crash. - content::RenderFrameHost* rfh = web_view()->web_contents()->GetMainFrame(); - ASSERT_TRUE(rfh); - content::GlobalRequestID request_id; - blink::mojom::ResourceLoadInfo resource_load_info; - web_view()->ResourceLoadComplete(rfh, request_id, resource_load_info); } TEST_F(WebDialogViewUnitTest, MetadataTest) {
diff --git a/ui/web_dialogs/web_dialog_delegate.h b/ui/web_dialogs/web_dialog_delegate.h index dc7fe5f..417db49 100644 --- a/ui/web_dialogs/web_dialog_delegate.h +++ b/ui/web_dialogs/web_dialog_delegate.h
@@ -9,7 +9,6 @@ #include <vector> #include "content/public/browser/web_contents_delegate.h" -#include "third_party/blink/public/mojom/loader/resource_load_info.mojom.h" #include "ui/base/ui_base_types.h" #include "ui/base/window_open_disposition.h" #include "ui/web_dialogs/web_dialogs_export.h" @@ -176,8 +175,6 @@ virtual bool AcceleratorPressed(const Accelerator& accelerator); virtual void OnWebContentsFinishedLoad() {} - virtual void OnMainFrameResourceLoadComplete( - const blink::mojom::ResourceLoadInfo& resource_load_info) {} virtual void RequestMediaAccessPermission( content::WebContents* web_contents,
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/BrowserViewController.java b/weblayer/browser/java/org/chromium/weblayer_private/BrowserViewController.java index ba98983..d0e86a3 100644 --- a/weblayer/browser/java/org/chromium/weblayer_private/BrowserViewController.java +++ b/weblayer/browser/java/org/chromium/weblayer_private/BrowserViewController.java
@@ -210,6 +210,8 @@ mModalDialogManager.resumeType( ModalDialogManager.ModalDialogType.TAB, mTabModalToken); } + mAppModalToken = TokenHolder.INVALID_TOKEN; + mTabModalToken = TokenHolder.INVALID_TOKEN; } }; mBottomSheetController.addObserver(mBottomSheetObserver);