diff --git a/DEPS b/DEPS index 5d8236a..c00c128 100644 --- a/DEPS +++ b/DEPS
@@ -235,15 +235,15 @@ # 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': 'b23372df9ce751f1c2a30c3c0f24099aa21d3c2c', + 'skia_revision': 'e5a06afeaedd8a6d15c73747f9a9f9d799c9763c', # 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': 'b7ea16e261758f75cdcd09a7cfa76235dd5c7337', + 'v8_revision': '3910e888902506c07ac4f131cb12307723d5fbe3', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': '9ba5dcf604e7552be79a74a5e36cd73da7f70e4d', + 'angle_revision': '4349703b4c90633d70655850a0b86dd9eabeebf8', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -302,7 +302,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': '89d8a1b2c541992b209d84381bdf9eeb6694c372', + 'catapult_revision': '876bab7910dc34d647002e2c2d649ca04b82d037', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -350,7 +350,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': '34206ec07bfcc6a5942402caea0385ddffb25d9b', + 'dawn_revision': '6fd28ba4cb990953dc97ff22d3fbbd9b19a5f504', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -378,7 +378,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling nearby # and whatever else without interference from each other. - 'nearby_revision': 'dceb1e216bdd22daf37f71026db3d93124841cd4', + 'nearby_revision': '51a19d24c1644cccdf33d56a48db4dad3e418447', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling securemessage # and whatever else without interference from each other. @@ -1030,7 +1030,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'a0c67a3eab72e9524ef8b90bf2bf838597a4d1bc', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '4a06fb543238f49f674a44be355dde429286fa86', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), @@ -1695,7 +1695,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@f6a31866f14e8d38a9ecd72cac92f12c1ca20e6f', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@c1e1b2b1e121156dd48689ba26656f61e1335bba', 'condition': 'checkout_src_internal', },
diff --git a/ash/app_list/app_list_controller_impl.cc b/ash/app_list/app_list_controller_impl.cc index 4c17dae1..a89a451 100644 --- a/ash/app_list/app_list_controller_impl.cc +++ b/ash/app_list/app_list_controller_impl.cc
@@ -393,14 +393,15 @@ } void AppListControllerImpl::PublishSearchResults( - std::vector<std::unique_ptr<SearchResultMetadata>> results) { + std::vector<std::unique_ptr<SearchResultMetadata>> results, + const std::vector<ash::AppListSearchResultCategory>& categories) { std::vector<std::unique_ptr<SearchResult>> new_results; for (auto& result_metadata : results) { std::unique_ptr<SearchResult> result = std::make_unique<SearchResult>(); result->SetMetadata(std::move(result_metadata)); new_results.push_back(std::move(result)); } - search_model_.PublishResults(std::move(new_results)); + search_model_.PublishResults(std::move(new_results), categories); } void AppListControllerImpl::SetItemMetadata(
diff --git a/ash/app_list/app_list_controller_impl.h b/ash/app_list/app_list_controller_impl.h index b58f59c2..b1ce50a 100644 --- a/ash/app_list/app_list_controller_impl.h +++ b/ash/app_list/app_list_controller_impl.h
@@ -112,7 +112,8 @@ void UpdateSearchBox(const std::u16string& text, bool initiated_by_user) override; void PublishSearchResults( - std::vector<std::unique_ptr<SearchResultMetadata>> results) override; + std::vector<std::unique_ptr<SearchResultMetadata>> results, + const std::vector<ash::AppListSearchResultCategory>& categories) override; void SetItemMetadata(const std::string& id, std::unique_ptr<AppListItemMetadata> data) override; void SetItemIconVersion(const std::string& id, int icon_version) override;
diff --git a/ash/app_list/model/search/search_model.cc b/ash/app_list/model/search/search_model.cc index ee74a5c..cd970744 100644 --- a/ash/app_list/model/search/search_model.cc +++ b/ash/app_list/model/search/search_model.cc
@@ -60,7 +60,8 @@ } void SearchModel::PublishResults( - std::vector<std::unique_ptr<SearchResult>> new_results) { + std::vector<std::unique_ptr<SearchResult>> new_results, + const std::vector<ash::AppListSearchResultCategory>& categories) { // The following algorithm is used: // 1. Transform the |results_| list into an unordered map from result ID // to item. @@ -115,7 +116,8 @@ } void SearchModel::DeleteAllResults() { - PublishResults(std::vector<std::unique_ptr<SearchResult>>()); + PublishResults(std::vector<std::unique_ptr<SearchResult>>(), + std::vector<ash::AppListSearchResultCategory>()); } void SearchModel::DeleteResultById(const std::string& id) {
diff --git a/ash/app_list/model/search/search_model.h b/ash/app_list/model/search/search_model.h index 133bddc..ebc1bf5f 100644 --- a/ash/app_list/model/search/search_model.h +++ b/ash/app_list/model/search/search_model.h
@@ -62,7 +62,9 @@ SearchBoxModel* search_box() { return search_box_.get(); } SearchResults* results() { return results_.get(); } - void PublishResults(std::vector<std::unique_ptr<SearchResult>> new_results); + void PublishResults( + std::vector<std::unique_ptr<SearchResult>> new_results, + const std::vector<ash::AppListSearchResultCategory>& categories); SearchResult* FindSearchResult(const std::string& id);
diff --git a/ash/frame/header_view.cc b/ash/frame/header_view.cc index 57adb329..e1a68fd 100644 --- a/ash/frame/header_view.cc +++ b/ash/frame/header_view.cc
@@ -343,10 +343,12 @@ auto* center_button = frame_header_->GetCenterButton(); if (!center_button) return; - if (is_center_button_visible && !center_button->parent()) { - AddChildView(center_button); - } else if (!is_center_button_visible && center_button->parent()) { - RemoveChildView(center_button); + if (is_center_button_visible) { + if (!center_button->parent()) + AddChildView(center_button); + center_button->SetVisible(true); + } else { + center_button->SetVisible(false); } }
diff --git a/ash/public/cpp/app_list/app_list_config.cc b/ash/public/cpp/app_list/app_list_config.cc index 8a3baa5..99c1fd4 100644 --- a/ash/public/cpp/app_list/app_list_config.cc +++ b/ash/public/cpp/app_list/app_list_config.cc
@@ -203,15 +203,16 @@ int SharedAppListConfig::GetPreferredIconDimension( SearchResultDisplayType display_type) const { switch (display_type) { + case SearchResultDisplayType::kList: + return search_list_icon_dimension_; case SearchResultDisplayType::kTile: return search_tile_icon_dimension_; case SearchResultDisplayType::kChip: return suggestion_chip_icon_dimension_; - case SearchResultDisplayType::kList: - return search_list_icon_dimension_; + case SearchResultDisplayType::kContinue: + return suggestion_chip_icon_dimension_; case SearchResultDisplayType::kNone: // Falls through. - case SearchResultDisplayType::kCard: - return 0; + case SearchResultDisplayType::kCard: // Falls through. case SearchResultDisplayType::kLast: return 0; }
diff --git a/ash/public/cpp/app_list/app_list_controller.h b/ash/public/cpp/app_list/app_list_controller.h index 351a8cb..f8f6122a 100644 --- a/ash/public/cpp/app_list/app_list_controller.h +++ b/ash/public/cpp/app_list/app_list_controller.h
@@ -67,9 +67,14 @@ virtual void UpdateSearchBox(const std::u16string& text, bool initiated_by_user) = 0; - // Publishes search results to Ash to render them. + // Publishes search results to Ash to render them. The order of the + // |categories| vector is the order cateogories should be displayed in. Each + // result in |results| contains a category as a member, which is guaranteed + // to exist in |categories|. However, some values in |categories| may have + // no results associated with them. virtual void PublishSearchResults( - std::vector<std::unique_ptr<SearchResultMetadata>> results) = 0; + std::vector<std::unique_ptr<SearchResultMetadata>> results, + const std::vector<ash::AppListSearchResultCategory>& categories) = 0; // Updates an item's metadata (e.g. name, position, etc). virtual void SetItemMetadata(const std::string& id,
diff --git a/ash/public/cpp/app_list/app_list_types.h b/ash/public/cpp/app_list/app_list_types.h index d935820..8c9afd5 100644 --- a/ash/public/cpp/app_list/app_list_types.h +++ b/ash/public/cpp/app_list/app_list_types.h
@@ -155,6 +155,9 @@ // Type of the search result, which is set in Chrome. These values are persisted // to logs. Entries should not be renumbered and numeric values should never be // reused. +// +// TODO(crbug.com/1258415): kFileChip and kDriveChip can be deprecated once the +// new launcher is launched. enum class AppListSearchResultType { kUnknown, // Unknown type. Don't use over IPC kInstalledApp, // Installed apps. @@ -202,13 +205,16 @@ // Which UI container(s) the result should be displayed in. // Do not change the order of these as they are used for metrics. +// +// TODO(1258415): kChip can be deprecated once the new launcher is launched. enum SearchResultDisplayType { kNone = 0, kList = 1, // Displays in search list kTile = 2, // Displays in search tiles // kRecommendation = 3 // No longer used, split between kTile and kChip - kCard = 4, // Displays in answer cards - kChip = 5, // Displays in suggestion chips + kCard = 4, // Displays in answer cards + kChip = 5, // Displays in suggestion chips + kContinue = 6, // Displays in the Continue section // Add new values here kLast, // Don't use over IPC };
diff --git a/ash/public/cpp/arc_resize_lock_type.h b/ash/public/cpp/arc_resize_lock_type.h index d983a454..d539ce9 100644 --- a/ash/public/cpp/arc_resize_lock_type.h +++ b/ash/public/cpp/arc_resize_lock_type.h
@@ -8,17 +8,20 @@ namespace ash { // Represents how strictly resize operations are limited for a window. +// This class must strictly corresponds to the resize_lock_type enum in the +// wayland remote surface protocol. enum class ArcResizeLockType { - // The resizability is not restricted by the resize lock feature. - RESIZABLE = 0, + // ResizeLock is disabled and the window follows normal resizability. + NONE = 0, - // The app is only allowed to be resized via limited operations such as via - // the compatibility mode dialog. - RESIZE_LIMITED = 1, + // Resizing is enabled and resize lock type is togglable. + RESIZE_ENABLED_TOGGLABLE = 1, - // No explicit resize operation is allowed. (The window can still be resized, - // e.g. when the display scale factor changes.) - FULLY_LOCKED = 2, + // Resizing is disabled and resize lock type is togglable. + RESIZE_DISABLED_TOGGLABLE = 2, + + // Resizing is disabled and resize lock type is not togglable. + RESIZE_DISABLED_NONTOGGLABLE = 3, }; } // namespace ash
diff --git a/ash/public/cpp/window_properties.cc b/ash/public/cpp/window_properties.cc index 04b2341..4cd341bf 100644 --- a/ash/public/cpp/window_properties.cc +++ b/ash/public/cpp/window_properties.cc
@@ -28,7 +28,7 @@ DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(std::string, kArcPackageNameKey, nullptr) DEFINE_UI_CLASS_PROPERTY_KEY(ArcResizeLockType, kArcResizeLockTypeKey, - ArcResizeLockType::RESIZABLE) + ArcResizeLockType::NONE) DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(WindowBackdrop, kWindowBackdropKey, nullptr) DEFINE_UI_CLASS_PROPERTY_KEY(bool, kCanAttachToAnotherWindowKey, true) DEFINE_UI_CLASS_PROPERTY_KEY(bool, kCanConsumeSystemKeysKey, false)
diff --git a/ash/system/holding_space/holding_space_item_view.cc b/ash/system/holding_space/holding_space_item_view.cc index d1a97a6..ed98965 100644 --- a/ash/system/holding_space/holding_space_item_view.cc +++ b/ash/system/holding_space/holding_space_item_view.cc
@@ -133,6 +133,7 @@ // Accessibility. GetViewAccessibility().OverrideName(item->GetAccessibleName()); + GetViewAccessibility().OverrideDescription(base::EmptyString16()); GetViewAccessibility().OverrideRole(ax::mojom::Role::kListItem); // Layer.
diff --git a/ash/webui/telemetry_extension_ui/mojom/probe_service.mojom b/ash/webui/telemetry_extension_ui/mojom/probe_service.mojom index 0b712ea..d87c4b2 100644 --- a/ash/webui/telemetry_extension_ui/mojom/probe_service.mojom +++ b/ash/webui/telemetry_extension_ui/mojom/probe_service.mojom
@@ -88,6 +88,8 @@ // probing telemetry information. [Extensible] enum ErrorType { + // Default value. + kUnknown, // An error reading a system file. kFileReadError, // An error parsing data into a consumable form.
diff --git a/ash/webui/telemetry_extension_ui/resources/trusted.js b/ash/webui/telemetry_extension_ui/resources/trusted.js index fe8d580..4054b64 100644 --- a/ash/webui/telemetry_extension_ui/resources/trusted.js +++ b/ash/webui/telemetry_extension_ui/resources/trusted.js
@@ -618,6 +618,7 @@ * @const */ this.errorTypeToString_ = new Map([ + [errorEnum.kUnknown, 'unknown-error'], [errorEnum.kFileReadError, 'file-read-error'], [errorEnum.kParseError, 'parse-error'], [errorEnum.kSystemUtilityError, 'system-utility-error'],
diff --git a/ash/webui/telemetry_extension_ui/services/probe_service_converters.cc b/ash/webui/telemetry_extension_ui/services/probe_service_converters.cc index 93d2fe7d..99ea99e 100644 --- a/ash/webui/telemetry_extension_ui/services/probe_service_converters.cc +++ b/ash/webui/telemetry_extension_ui/services/probe_service_converters.cc
@@ -333,6 +333,8 @@ health::mojom::ErrorType Convert(cros_healthd::mojom::ErrorType input) { switch (input) { + case cros_healthd::mojom::ErrorType::kUnknown: + return health::mojom::ErrorType::kUnknown; case cros_healthd::mojom::ErrorType::kFileReadError: return health::mojom::ErrorType::kFileReadError; case cros_healthd::mojom::ErrorType::kParseError:
diff --git a/base/BUILD.gn b/base/BUILD.gn index 6c66c072..34a637f 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -3546,7 +3546,6 @@ "allocator/partition_allocator/hardening_unittest.cc", "allocator/partition_allocator/memory_reclaimer_unittest.cc", "allocator/partition_allocator/page_allocator_unittest.cc", - "allocator/partition_allocator/partition_address_space_unittest.cc", "allocator/partition_allocator/partition_alloc_unittest.cc", "allocator/partition_allocator/partition_lock_unittest.cc", "allocator/partition_allocator/starscan/pcscan_scheduling_unittest.cc",
diff --git a/base/allocator/partition_allocator/partition_address_space.cc b/base/allocator/partition_allocator/partition_address_space.cc index 7146152..3c01dbd 100644 --- a/base/allocator/partition_allocator/partition_address_space.cc +++ b/base/allocator/partition_allocator/partition_address_space.cc
@@ -21,59 +21,65 @@ #if defined(PA_HAS_64_BITS_POINTERS) -constexpr std::array<size_t, 2> PartitionAddressSpace::kGigaCagePoolSizes; - alignas(64) PartitionAddressSpace::GigaCageSetup PartitionAddressSpace::setup_; void PartitionAddressSpace::Init() { if (IsInitialized()) return; - GigaCageProperties properties = - CalculateGigaCageProperties(kGigaCagePoolSizes); + setup_.non_brp_pool_base_address_ = reinterpret_cast<uintptr_t>( + AllocPages(nullptr, kNonBRPPoolSize, kNonBRPPoolSize, + base::PageInaccessible, PageTag::kPartitionAlloc)); + PA_CHECK(setup_.non_brp_pool_base_address_); - setup_.reserved_base_address_ = - reinterpret_cast<uintptr_t>(AllocPagesWithAlignOffset( - nullptr, properties.size, properties.alignment, - properties.alignment_offset, base::PageInaccessible, - PageTag::kPartitionAlloc)); - PA_CHECK(setup_.reserved_base_address_); - - uintptr_t current = setup_.reserved_base_address_; - - setup_.non_brp_pool_base_address_ = current; PA_DCHECK(!(setup_.non_brp_pool_base_address_ & (kNonBRPPoolSize - 1))); setup_.non_brp_pool_ = internal::AddressPoolManager::GetInstance()->Add( - current, kNonBRPPoolSize); + setup_.non_brp_pool_base_address_, kNonBRPPoolSize); PA_CHECK(setup_.non_brp_pool_ == kNonBRPPoolHandle); - PA_DCHECK(!IsInNonBRPPool(reinterpret_cast<void*>(current - 1))); - PA_DCHECK(IsInNonBRPPool(reinterpret_cast<void*>(current))); - current += kNonBRPPoolSize; - PA_DCHECK(IsInNonBRPPool(reinterpret_cast<void*>(current - 1))); - PA_DCHECK(!IsInNonBRPPool(reinterpret_cast<void*>(current))); + PA_DCHECK(!IsInNonBRPPool( + reinterpret_cast<void*>(setup_.non_brp_pool_base_address_ - 1))); + PA_DCHECK(IsInNonBRPPool( + reinterpret_cast<void*>(setup_.non_brp_pool_base_address_))); + PA_DCHECK(IsInNonBRPPool(reinterpret_cast<void*>( + setup_.non_brp_pool_base_address_ + kNonBRPPoolSize - 1))); + PA_DCHECK(!IsInNonBRPPool(reinterpret_cast<void*>( + setup_.non_brp_pool_base_address_ + kNonBRPPoolSize))); - setup_.brp_pool_base_address_ = current; + // Reserve an extra allocation granularity unit before the BRP pool, but keep + // the pool aligned at kBRPPoolSize. A pointer immediately past an allocation + // is a valid pointer, and having a "forbidden zone" before the BRP pool + // prevents such a pointer from "sneaking into" the pool. + const size_t kForbiddenZoneSize = PageAllocationGranularity(); + setup_.brp_pool_base_address_ = + reinterpret_cast<uintptr_t>(AllocPagesWithAlignOffset( + nullptr, kBRPPoolSize + kForbiddenZoneSize, kBRPPoolSize, + kBRPPoolSize - kForbiddenZoneSize, base::PageInaccessible, + PageTag::kPartitionAlloc)) + + kForbiddenZoneSize; + PA_CHECK(setup_.brp_pool_base_address_); PA_DCHECK(!(setup_.brp_pool_base_address_ & (kBRPPoolSize - 1))); - setup_.brp_pool_ = - internal::AddressPoolManager::GetInstance()->Add(current, kBRPPoolSize); + setup_.brp_pool_ = internal::AddressPoolManager::GetInstance()->Add( + setup_.brp_pool_base_address_, kBRPPoolSize); PA_CHECK(setup_.brp_pool_ == kBRPPoolHandle); - PA_DCHECK(!IsInBRPPool(reinterpret_cast<void*>(current - 1))); - PA_DCHECK(IsInBRPPool(reinterpret_cast<void*>(current))); - current += kBRPPoolSize; - PA_DCHECK(IsInBRPPool(reinterpret_cast<void*>(current - 1))); - PA_DCHECK(!IsInBRPPool(reinterpret_cast<void*>(current))); + PA_DCHECK( + !IsInBRPPool(reinterpret_cast<void*>(setup_.brp_pool_base_address_ - 1))); + PA_DCHECK( + IsInBRPPool(reinterpret_cast<void*>(setup_.brp_pool_base_address_))); + PA_DCHECK(IsInBRPPool(reinterpret_cast<void*>(setup_.brp_pool_base_address_ + + kBRPPoolSize - 1))); + PA_DCHECK(!IsInBRPPool( + reinterpret_cast<void*>(setup_.brp_pool_base_address_ + kBRPPoolSize))); #if PA_STARSCAN_USE_CARD_TABLE // Reserve memory for PCScan quarantine card table. - void* requested_address = reinterpret_cast<void*>(non_brp_pool_base_address_); + void* requested_address = + reinterpret_cast<void*>(setup_.non_brp_pool_base_address_); char* actual_address = internal::AddressPoolManager::GetInstance()->Reserve( non_brp_pool_, requested_address, kSuperPageSize); PA_CHECK(requested_address == actual_address) << "QuarantineCardTable is required to be allocated in the beginning of " "the non-BRP pool"; #endif // PA_STARSCAN_USE_CARD_TABLE - - PA_DCHECK(setup_.reserved_base_address_ + properties.size == current); } void PartitionAddressSpace::InitConfigurablePool(void* address, size_t size) { @@ -96,12 +102,16 @@ } void PartitionAddressSpace::UninitForTesting() { - GigaCageProperties properties = - CalculateGigaCageProperties(kGigaCagePoolSizes); - - FreePages(reinterpret_cast<void*>(setup_.reserved_base_address_), - properties.size); - setup_.reserved_base_address_ = 0; + FreePages(reinterpret_cast<void*>(setup_.non_brp_pool_base_address_), + kNonBRPPoolSize); + // For BRP pool, the allocation region includes a "forbidden zone" before the + // pool. + const size_t kForbiddenZoneSize = PageAllocationGranularity(); + FreePages(reinterpret_cast<void*>(setup_.brp_pool_base_address_ - + kForbiddenZoneSize), + kBRPPoolSize + kForbiddenZoneSize); + // Do not free pages for the configurable pool, because its memory is owned + // by someone else, but deinitialize it nonetheless. setup_.non_brp_pool_base_address_ = kNonBRPPoolOffsetMask; setup_.brp_pool_base_address_ = kBRPPoolOffsetMask; setup_.configurable_pool_base_address_ = kConfigurablePoolOffsetMask;
diff --git a/base/allocator/partition_allocator/partition_address_space.h b/base/allocator/partition_allocator/partition_address_space.h index a756b322..6cc8429 100644 --- a/base/allocator/partition_allocator/partition_address_space.h +++ b/base/allocator/partition_allocator/partition_address_space.h
@@ -11,6 +11,7 @@ #include "base/allocator/buildflags.h" #include "base/allocator/partition_allocator/address_pool_manager_types.h" +#include "base/allocator/partition_allocator/page_allocator_constants.h" #include "base/allocator/partition_allocator/partition_alloc_check.h" #include "base/allocator/partition_allocator/partition_alloc_config.h" #include "base/allocator/partition_allocator/partition_alloc_constants.h" @@ -29,47 +30,6 @@ // The feature is not applicable to 32-bit address space. #if defined(PA_HAS_64_BITS_POINTERS) -struct GigaCageProperties { - size_t size; - size_t alignment; - size_t alignment_offset; -}; - -template <size_t N> -GigaCageProperties CalculateGigaCageProperties( - const std::array<size_t, N>& pool_sizes) { - size_t size_sum = 0; - size_t alignment = 0; - size_t alignment_offset; - // The goal is to find properties such that each pool's start address is - // aligned to its own size. To achieve that, the largest pool will serve - // as an anchor (the first one, if there are more) and it'll be used to - // determine the core alignment. The sizes of pools before the anchor will - // determine the offset within the core alignment at which the GigaCage will - // start. - // If this algorithm doesn't find the proper alignment, it means such an - // alignment doesn't exist. - for (size_t pool_size : pool_sizes) { - PA_CHECK(bits::IsPowerOfTwo(pool_size)); - if (pool_size > alignment) { - alignment = pool_size; - // This may underflow, leading to a very high value, so use modulo - // |alignment| to bring it down. - alignment_offset = (alignment - size_sum) & (alignment - 1); - } - size_sum += pool_size; - } - // Use PA_CHECK because we can't correctly proceed if any pool's start address - // isn't aligned to its own size. Exact initial value of |sample_address| - // doesn't matter as long as |address % alignment == alignment_offset|. - uintptr_t sample_address = alignment_offset + 7 * alignment; - for (size_t pool_size : pool_sizes) { - PA_CHECK(!(sample_address & (pool_size - 1))); - sample_address += pool_size; - } - return GigaCageProperties{size_sum, alignment, alignment_offset}; -} - // Reserves address space for PartitionAllocator. class BASE_EXPORT PartitionAddressSpace { public: @@ -107,7 +67,7 @@ #if BUILDFLAG(USE_BACKUP_REF_PTR) } else if (IsInBRPPool(address)) { pool = GetBRPPool(); - base = brp_pool_base_address_; + base = setup_.brp_pool_base_address_; #endif // BUILDFLAG(USE_BACKUP_REF_PTR) } else if (IsInConfigurablePool(address)) { pool = GetConfigurablePool(); @@ -134,13 +94,13 @@ static void UninitForTesting(); static ALWAYS_INLINE bool IsInitialized() { - if (setup_.reserved_base_address_) { - PA_DCHECK(setup_.non_brp_pool_ != 0); + // Either neither or both non-BRP and BRP pool are initialized. The + // configurable pool is initialized separately. + if (setup_.non_brp_pool_) { PA_DCHECK(setup_.brp_pool_ != 0); return true; } - PA_DCHECK(setup_.non_brp_pool_ == 0); PA_DCHECK(setup_.brp_pool_ == 0); return false; } @@ -187,15 +147,10 @@ void* operator new(size_t, void*) = delete; private: - // On 64-bit systems, GigaCage is split into two pools, one with allocations - // that have a BRP ref-count, and one with allocations that don't. - // +----------------+ reserved_base_address_ (8GiB aligned) - // | non-BRP | == non_brp_pool_base_address_ - // | pool | - // +----------------+ reserved_base_address_ + 8GiB - // | BRP | == brp_pool_base_address_ - // | pool | - // +----------------+ reserved_base_address_ + 16GiB + // On 64-bit systems, GigaCage is split into disjoint pools. The BRP pool, is + // where all allocations have a BRP ref-count, thus pointers pointing there + // can use a BRP protection against UaF. Allocations in the non-BRP pool don't + // have that. // // Pool sizes have to be the power of two. Each pool will be aligned at its // own size boundary. @@ -203,17 +158,8 @@ // NOTE! The BRP pool must be preceded by a reserved region, where allocations // are forbidden. This is to prevent a pointer immediately past a non-GigaCage // allocation from falling into the BRP pool, thus triggering BRP mechanism - // and likely crashing. One way to implement this is to place another - // PartitionAlloc pool right before, because trailing guard pages there will - // fulfill this guarantee. Alternatively, it could be any region that - // guarantess to not have allocations extending to its very end. But it's just - // easier to have non-BRP pool there. - // - // If more than 2 consecutive pools are ever needed, care will have to be - // taken when choosing sizes. For example, for sizes [8GiB,4GiB,8GiB], it'd be - // impossible to align each pool at its own size boundary while keeping them - // next to each other. CalculateGigaCageProperties() has non-debug, run-time - // checks to assert that. + // and likely crashing. This "forbidden zone" can be as small as 1B, but it's + // simpler to just reserve an allocation granularity unit. // // The ConfigurablePool is an optional Pool that can be created inside an // existing mapping by the embedder, and so will be outside of the GigaCage. @@ -222,8 +168,6 @@ // memory cage, which requires that ArrayBuffers be located inside of it. static constexpr size_t kNonBRPPoolSize = kPoolMaxSize; static constexpr size_t kBRPPoolSize = kPoolMaxSize; - static constexpr std::array<size_t, 2> kGigaCagePoolSizes = {kNonBRPPoolSize, - kBRPPoolSize}; static constexpr size_t kConfigurablePoolSize = 4 * kGiB; static_assert( kConfigurablePoolSize <= kPoolMaxSize, @@ -246,8 +190,6 @@ ~kConfigurablePoolOffsetMask; struct GigaCageSetup { - uintptr_t reserved_base_address_ = 0; - // Before PartitionAddressSpace::Init(), no allocation are allocated from a // reserved address space. Therefore, set *_pool_base_address_ initially to // k*PoolOffsetMask, so that PartitionAddressSpace::IsIn*Pool() always @@ -260,7 +202,7 @@ pool_handle brp_pool_ = 0; pool_handle configurable_pool_ = 0; - char padding_[20] = {}; + char padding_[28] = {}; }; static_assert(sizeof(GigaCageSetup) % 64 == 0, "GigaCageSetup has to fill a cacheline(s)");
diff --git a/base/allocator/partition_allocator/partition_address_space_unittest.cc b/base/allocator/partition_allocator/partition_address_space_unittest.cc deleted file mode 100644 index 44c509a..0000000 --- a/base/allocator/partition_allocator/partition_address_space_unittest.cc +++ /dev/null
@@ -1,89 +0,0 @@ -// Copyright 2021 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/allocator/partition_allocator/partition_address_space.h" - -#include <array> - -#include "base/allocator/partition_allocator/partition_alloc_config.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace base { -namespace internal { - -#if defined(PA_HAS_64_BITS_POINTERS) - -TEST(PartitionAllocAddressSpaceTest, CalculateGigaCageProperties) { - GigaCageProperties props; - - props = CalculateGigaCageProperties(std::array<size_t, 1>{1}); - EXPECT_EQ(1u, props.size); - EXPECT_EQ(1u, props.alignment); - EXPECT_EQ(0u, props.alignment_offset); - - props = CalculateGigaCageProperties(std::array<size_t, 2>{2, 1}); - EXPECT_EQ(3u, props.size); - EXPECT_EQ(2u, props.alignment); - EXPECT_EQ(0u, props.alignment_offset); - - props = CalculateGigaCageProperties(std::array<size_t, 2>{1, 2}); - EXPECT_EQ(3u, props.size); - EXPECT_EQ(2u, props.alignment); - EXPECT_EQ(1u, props.alignment_offset); - - props = CalculateGigaCageProperties(std::array<size_t, 4>{8, 4, 2, 1}); - EXPECT_EQ(15u, props.size); - EXPECT_EQ(8u, props.alignment); - EXPECT_EQ(0u, props.alignment_offset); - - props = CalculateGigaCageProperties(std::array<size_t, 4>{1, 2, 4, 8}); - EXPECT_EQ(15u, props.size); - EXPECT_EQ(8u, props.alignment); - EXPECT_EQ(1u, props.alignment_offset); - - props = - CalculateGigaCageProperties(std::array<size_t, 7>{1, 2, 4, 2, 2, 4, 8}); - EXPECT_EQ(23u, props.size); - EXPECT_EQ(8u, props.alignment); - EXPECT_EQ(1u, props.alignment_offset); - - props = CalculateGigaCageProperties(std::array<size_t, 3>{8, 4, 4}); - EXPECT_EQ(16u, props.size); - EXPECT_EQ(8u, props.alignment); - EXPECT_EQ(0u, props.alignment_offset); - - props = CalculateGigaCageProperties(std::array<size_t, 3>{4, 4, 8}); - EXPECT_EQ(16u, props.size); - EXPECT_EQ(8u, props.alignment); - EXPECT_EQ(0u, props.alignment_offset); - - props = CalculateGigaCageProperties(std::array<size_t, 4>{8, 4, 4, 8}); - EXPECT_EQ(24u, props.size); - EXPECT_EQ(8u, props.alignment); - EXPECT_EQ(0u, props.alignment_offset); - - size_t GiB = 1024ull * 1024 * 1024; - props = CalculateGigaCageProperties( - std::array<size_t, 6>{GiB, GiB, GiB, GiB, GiB, GiB}); - EXPECT_EQ(6 * GiB, props.size); - EXPECT_EQ(GiB, props.alignment); - EXPECT_EQ(0u, props.alignment_offset); -} - -TEST(PartitionAllocAddressSpaceTest, CalculateGigaCagePropertiesImpossible) { - EXPECT_DEATH_IF_SUPPORTED( - CalculateGigaCageProperties(std::array<size_t, 1>{0}), ""); - EXPECT_DEATH_IF_SUPPORTED( - CalculateGigaCageProperties(std::array<size_t, 1>{3}), ""); - EXPECT_DEATH_IF_SUPPORTED( - CalculateGigaCageProperties(std::array<size_t, 3>{8, 4, 8}), ""); - EXPECT_DEATH_IF_SUPPORTED( - CalculateGigaCageProperties(std::array<size_t, 7>{1, 2, 4, 1, 2, 4, 8}), - ""); -} - -#endif // defined(PA_HAS_64_BITS_POINTERS) - -} // namespace internal -} // namespace base
diff --git a/chrome/VERSION b/chrome/VERSION index d291e495..249d4f7 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=97 MINOR=0 -BUILD=4667 +BUILD=4668 PATCH=0
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 5c51e82..c096695 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -339,7 +339,6 @@ "//chrome/browser/banners/android:java", "//chrome/browser/browser_controls/android:java", "//chrome/browser/commerce/merchant_viewer/android:java", - "//chrome/browser/commerce/price_tracking/proto:proto_java", "//chrome/browser/commerce/shopping_list/android:java", "//chrome/browser/consent_auditor/android:java", "//chrome/browser/contextmenu:java", @@ -779,7 +778,6 @@ "//chrome/browser/android/browserservices/metrics:jni_headers", "//chrome/browser/android/browserservices/verification:jni_headers", "//chrome/browser/commerce/merchant_viewer/android:jni_headers", - "//chrome/browser/commerce/price_tracking/android:jni_headers", "//chrome/browser/commerce/subscriptions/android:jni_headers", "//chrome/browser/contextmenu:jni_headers", "//chrome/browser/download/android:jni_headers", @@ -936,7 +934,6 @@ "//chrome/browser/browser_controls/android:java", "//chrome/browser/browser_controls/android:junit", "//chrome/browser/commerce/merchant_viewer/android:junit", - "//chrome/browser/commerce/price_tracking/proto:proto_java", "//chrome/browser/contextmenu:java", "//chrome/browser/continuous_search:junit", "//chrome/browser/continuous_search/internal:junit",
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 4a6200d..24cca08 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -11971,6 +11971,13 @@ <message name="IDS_LENS_REGION_SEARCH_BUBBLE_TEXT" desc="Text that is shown in the Lens Region Search education bubble when starting the feature. Informs the user to drag over the screen to select a region to search with Google Lens."> Drag over any image to search </message> + <!-- ChromeLabs Thumbnail Tab Strip --> + <message name="IDS_THUMBNAIL_TAB_STRIP_EXPERIMENT_NAME" desc="Name for Thumbnail Tab Strip experiment"> + Thumbnail tab strip for tablet mode + </message> + <message name="IDS_THUMBNAIL_TAB_STRIP_EXPERIMENT_DESCRIPTION" desc="Description for Thumbnail Tab Strip experiment"> + In tablet mode, tap on the tab counter toolbar button to open the new tab strip that shows thumbnails of each tab. + </message> <if expr="is_cfm"> <message name="IDS_CFM_NETWORK_SETTINGS_TITLE" desc="Title for CFM Network Settings dialog">
diff --git a/chrome/app/generated_resources_grd/IDS_THUMBNAIL_TAB_STRIP_EXPERIMENT_DESCRIPTION.png.sha1 b/chrome/app/generated_resources_grd/IDS_THUMBNAIL_TAB_STRIP_EXPERIMENT_DESCRIPTION.png.sha1 new file mode 100644 index 0000000..f7f8057 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_THUMBNAIL_TAB_STRIP_EXPERIMENT_DESCRIPTION.png.sha1
@@ -0,0 +1 @@ +e456532664b2976795b83b70b5334b55af9073f6 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_THUMBNAIL_TAB_STRIP_EXPERIMENT_NAME.png.sha1 b/chrome/app/generated_resources_grd/IDS_THUMBNAIL_TAB_STRIP_EXPERIMENT_NAME.png.sha1 new file mode 100644 index 0000000..f7f8057 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_THUMBNAIL_TAB_STRIP_EXPERIMENT_NAME.png.sha1
@@ -0,0 +1 @@ +e456532664b2976795b83b70b5334b55af9073f6 \ No newline at end of file
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index c42f5d10..2c7581e 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -3002,8 +3002,6 @@ "chrome_browser_main_android.cc", "chrome_browser_main_android.h", "commerce/merchant_viewer/web_contents_helper.cc", - "commerce/price_tracking/android/price_tracking_notification_bridge.cc", - "commerce/price_tracking/android/price_tracking_notification_bridge.h", "component_updater/desktop_sharing_hub_component_remover.cc", "component_updater/desktop_sharing_hub_component_remover.h", "content_creation/notes/internal/android/note_service_bridge_factory.cc", @@ -3337,7 +3335,7 @@ "//chrome/browser/commerce/merchant_viewer:merchant_signal_db_content_proto", "//chrome/browser/commerce/merchant_viewer:merchant_viewer_data_manager", "//chrome/browser/commerce/merchant_viewer/android:jni_headers", - "//chrome/browser/commerce/price_tracking/proto:proto_java", + "//chrome/browser/commerce/price_tracking/proto:notifications_proto", "//chrome/browser/commerce/subscriptions:commerce_subscription_db", "//chrome/browser/commerce/subscriptions:commerce_subscription_db_content_proto", "//chrome/browser/commerce/subscriptions/android:jni_headers", @@ -4771,12 +4769,12 @@ "shell_integration_chromeos.cc", "signin/signin_status_metrics_provider_chromeos.cc", "signin/signin_status_metrics_provider_chromeos.h", - "speech/crosapi_tts_engine_delegate_ash.cc", - "speech/crosapi_tts_engine_delegate_ash.h", "speech/cros_speech_recognition_service.cc", "speech/cros_speech_recognition_service.h", "speech/cros_speech_recognition_service_factory.cc", "speech/cros_speech_recognition_service_factory.h", + "speech/crosapi_tts_engine_delegate_ash.cc", + "speech/crosapi_tts_engine_delegate_ash.h", "speech/network_speech_recognizer.cc", "speech/network_speech_recognizer.h", "speech/on_device_speech_recognizer.cc", @@ -4897,6 +4895,7 @@ "//components/metrics/structured:neutrino_logging", "//components/metrics/structured:neutrino_logging_util", "//components/services/app_service/public/cpp:instance_update", + "//components/services/app_service/public/cpp:permission_utils", "//components/services/font:lib", "//components/services/font/public/mojom", "//components/user_manager",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 5e7c79449..84b04cba 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -3004,7 +3004,8 @@ flag_descriptions::kTopChromeTouchUiDescription, kOsDesktop, MULTI_VALUE_TYPE(kTopChromeTouchUiChoices)}, #if BUILDFLAG(ENABLE_WEBUI_TAB_STRIP) - {"webui-tab-strip", flag_descriptions::kWebUITabStripName, + {flag_descriptions::kWebUITabStripFlagId, + flag_descriptions::kWebUITabStripName, flag_descriptions::kWebUITabStripDescription, kOsDesktop, FEATURE_VALUE_TYPE(features::kWebUITabStrip)},
diff --git a/chrome/browser/apps/app_service/publishers/arc_apps.cc b/chrome/browser/apps/app_service/publishers/arc_apps.cc index 6cdda259..0777de7 100644 --- a/chrome/browser/apps/app_service/publishers/arc_apps.cc +++ b/chrome/browser/apps/app_service/publishers/arc_apps.cc
@@ -51,6 +51,7 @@ #include "components/arc/mojom/file_system.mojom.h" #include "components/arc/session/arc_bridge_service.h" #include "components/services/app_service/public/cpp/intent_util.h" +#include "components/services/app_service/public/cpp/permission_utils.h" #include "components/services/app_service/public/cpp/types_util.h" #include "extensions/grit/extensions_browser_resources.h" #include "mojo/public/cpp/bindings/remote.h" @@ -191,8 +192,8 @@ auto permission = apps::mojom::Permission::New(); permission->permission_type = GetAppServicePermissionType(new_permission.first); - permission->value_type = apps::mojom::PermissionValueType::kBool; - permission->value = static_cast<uint32_t>(new_permission.second->granted); + permission->value = apps::mojom::PermissionValue::New(); + permission->value->set_bool_value(new_permission.second->granted); permission->is_managed = new_permission.second->managed; permissions->push_back(std::move(permission)); @@ -893,7 +894,7 @@ return; } - if (permission->value) { + if (apps_util::IsPermissionEnabled(permission->value)) { auto* permissions_instance = ARC_GET_INSTANCE_FOR_METHOD( arc_service_manager->arc_bridge_service()->app_permissions(), GrantPermission);
diff --git a/chrome/browser/apps/app_service/publishers/borealis_apps.cc b/chrome/browser/apps/app_service/publishers/borealis_apps.cc index c0f437d8..2561e7f 100644 --- a/chrome/browser/apps/app_service/publishers/borealis_apps.cc +++ b/chrome/browser/apps/app_service/publishers/borealis_apps.cc
@@ -22,6 +22,7 @@ #include "chrome/grit/chrome_unscaled_resources.h" #include "chrome/grit/generated_resources.h" #include "components/prefs/pref_service.h" +#include "components/services/app_service/public/cpp/permission_utils.h" #include "components/services/app_service/public/cpp/publisher_base.h" #include "ui/base/l10n/l10n_util.h" @@ -82,9 +83,9 @@ for (const PermissionInfo& info : permission_infos) { auto permission = apps::mojom::Permission::New(); permission->permission_type = info.permission; - permission->value_type = apps::mojom::PermissionValueType::kBool; - permission->value = - static_cast<uint32_t>(profile->GetPrefs()->GetBoolean(info.pref_name)); + permission->value = apps::mojom::PermissionValue::New(); + permission->value->set_bool_value( + profile->GetPrefs()->GetBoolean(info.pref_name)); permission->is_managed = false; app->permissions.push_back(std::move(permission)); } @@ -215,7 +216,8 @@ if (!pref_name) { return; } - profile_->GetPrefs()->SetBoolean(pref_name, permission_ptr->value); + profile_->GetPrefs()->SetBoolean( + pref_name, apps_util::IsPermissionEnabled(permission_ptr->value)); } void BorealisApps::Uninstall(const std::string& app_id,
diff --git a/chrome/browser/apps/app_service/publishers/plugin_vm_apps.cc b/chrome/browser/apps/app_service/publishers/plugin_vm_apps.cc index 36bdf74..9d390d6 100644 --- a/chrome/browser/apps/app_service/publishers/plugin_vm_apps.cc +++ b/chrome/browser/apps/app_service/publishers/plugin_vm_apps.cc
@@ -24,6 +24,7 @@ #include "chrome/grit/chrome_unscaled_resources.h" #include "chrome/grit/generated_resources.h" #include "components/prefs/pref_service.h" +#include "components/services/app_service/public/cpp/permission_utils.h" #include "components/services/app_service/public/mojom/types.mojom.h" #include "ui/base/l10n/l10n_util.h" @@ -79,9 +80,9 @@ for (const PermissionInfo& info : permission_infos) { auto permission = apps::mojom::Permission::New(); permission->permission_type = info.permission; - permission->value_type = apps::mojom::PermissionValueType::kBool; - permission->value = - static_cast<uint32_t>(profile->GetPrefs()->GetBoolean(info.pref_name)); + permission->value = apps::mojom::PermissionValue::New(); + permission->value->set_bool_value( + profile->GetPrefs()->GetBoolean(info.pref_name)); permission->is_managed = false; app->permissions.push_back(std::move(permission)); } @@ -212,7 +213,8 @@ return; } - profile_->GetPrefs()->SetBoolean(pref_name, permission_ptr->value); + profile_->GetPrefs()->SetBoolean( + pref_name, apps_util::IsPermissionEnabled(permission_ptr->value)); } void PluginVmApps::Uninstall(const std::string& app_id,
diff --git a/chrome/browser/ash/app_restore/full_restore_app_launch_handler_browsertest.cc b/chrome/browser/ash/app_restore/full_restore_app_launch_handler_browsertest.cc index 79ab9341..19b494b 100644 --- a/chrome/browser/ash/app_restore/full_restore_app_launch_handler_browsertest.cc +++ b/chrome/browser/ash/app_restore/full_restore_app_launch_handler_browsertest.cc
@@ -1109,7 +1109,7 @@ auto window_info = ::full_restore::GetWindowInfo(window1); ASSERT_TRUE(window_info); EXPECT_TRUE(window_info->activation_index.has_value()); - EXPECT_EQ(INT32_MIN, window_info->activation_index.value()); + EXPECT_EQ(INT32_MAX, window_info->activation_index.value()); app_window2 = CreateAppWindow(browser()->profile(), extension); ASSERT_TRUE(app_window2); @@ -1120,7 +1120,7 @@ window_info = ::full_restore::GetWindowInfo(window2); ASSERT_TRUE(window_info); EXPECT_TRUE(window_info->activation_index.has_value()); - EXPECT_EQ(INT32_MIN, window_info->activation_index.value()); + EXPECT_EQ(INT32_MAX, window_info->activation_index.value()); // Create a new window, verity the restore window id is 0. auto* app_window = CreateAppWindow(browser()->profile(), extension);
diff --git a/chrome/browser/ash/crosapi/browser_util_unittest.cc b/chrome/browser/ash/crosapi/browser_util_unittest.cc index 9e5e6e6ea..81c6aa0 100644 --- a/chrome/browser/ash/crosapi/browser_util_unittest.cc +++ b/chrome/browser/ash/crosapi/browser_util_unittest.cc
@@ -107,10 +107,22 @@ ScopedTestingLocalState local_state_; }; -TEST_F(BrowserUtilTest, LacrosEnabledByFlag) { +class LacrosSupportBrowserUtilTest : public BrowserUtilTest { + public: + LacrosSupportBrowserUtilTest() { + scoped_feature_list_.InitAndDisableFeature( + chromeos::features::kLacrosSupport); + } + ~LacrosSupportBrowserUtilTest() override = default; + + private: + base::test::ScopedFeatureList scoped_feature_list_; +}; + +TEST_F(LacrosSupportBrowserUtilTest, LacrosEnabledByFlag) { AddRegularUser("user@test.com"); - // Lacros is disabled because the feature isn't enabled by default. + // Lacros is initially disabled. EXPECT_FALSE(browser_util::IsLacrosEnabled()); // Enabling the flag enables Lacros. @@ -202,7 +214,7 @@ EXPECT_FALSE(browser_util::IsLacrosEnabled(Channel::UNKNOWN)); } -TEST_F(BrowserUtilTest, AshWebBrowserEnabled) { +TEST_F(LacrosSupportBrowserUtilTest, AshWebBrowserEnabled) { base::test::ScopedFeatureList feature_list; AddRegularUser("user@managedchrome.com"); testing_profile_.GetProfilePolicyConnector()->OverrideIsManagedForTesting( @@ -278,7 +290,7 @@ EXPECT_FALSE(browser_util::IsAshWebBrowserEnabled(Channel::STABLE)); } -TEST_F(BrowserUtilTest, LacrosPrimaryBrowserByFlags) { +TEST_F(LacrosSupportBrowserUtilTest, LacrosPrimaryBrowserByFlags) { AddRegularUser("user@test.com"); { EXPECT_FALSE(browser_util::IsLacrosPrimaryBrowser()); }
diff --git a/chrome/browser/ash/crostini/crostini_terminal.cc b/chrome/browser/ash/crostini/crostini_terminal.cc index fd542c7c..12e8bd3 100644 --- a/chrome/browser/ash/crostini/crostini_terminal.cc +++ b/chrome/browser/ash/crostini/crostini_terminal.cc
@@ -85,10 +85,21 @@ const ContainerId& container_id, const std::string& cwd, const std::vector<std::string>& terminal_args) { - crostini::RecordAppLaunchHistogram( - crostini::CrostiniAppLaunchAppType::kTerminal); GURL vsh_in_crosh_url = GenerateVshInCroshUrl(profile, container_id, cwd, terminal_args); + LaunchTerminalWithUrl(profile, display_id, vsh_in_crosh_url); +} + +void LaunchTerminalWithUrl(Profile* profile, + int64_t display_id, + const GURL& url) { + if (url.GetOrigin() != chrome::kChromeUIUntrustedTerminalURL) { + LOG(ERROR) << "Trying to launch terminal with an invalid url: " << url; + return; + } + + crostini::RecordAppLaunchHistogram( + crostini::CrostiniAppLaunchAppType::kTerminal); auto params = web_app::CreateSystemWebAppLaunchParams( profile, web_app::SystemAppType::TERMINAL, display_id); if (!params.has_value()) { @@ -109,7 +120,7 @@ // System Web Apps managed by Web App publisher should call // LaunchSystemWebAppAsync. web_app::LaunchSystemWebAppImpl(profile, web_app::SystemAppType::TERMINAL, - vsh_in_crosh_url, *params); + url, *params); } void LaunchTerminalSettings(Profile* profile, int64_t display_id) {
diff --git a/chrome/browser/ash/crostini/crostini_terminal.h b/chrome/browser/ash/crostini/crostini_terminal.h index e7e1781a..4da286ed 100644 --- a/chrome/browser/ash/crostini/crostini_terminal.h +++ b/chrome/browser/ash/crostini/crostini_terminal.h
@@ -103,6 +103,10 @@ const std::string& cwd = "", const std::vector<std::string>& terminal_args = {}); +void LaunchTerminalWithUrl(Profile* profile, + int64_t display_id, + const GURL& url); + // Launches the terminal settings popup window. void LaunchTerminalSettings(Profile* profile, int64_t display_id = display::kInvalidDisplayId);
diff --git a/chrome/browser/banners/app_banner_manager_browsertest_base.cc b/chrome/browser/banners/app_banner_manager_browsertest_base.cc index f8afcc5..a9f96c1 100644 --- a/chrome/browser/banners/app_banner_manager_browsertest_base.cc +++ b/chrome/browser/banners/app_banner_manager_browsertest_base.cc
@@ -5,6 +5,8 @@ #include "chrome/browser/banners/app_banner_manager_browsertest_base.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/browser/web_applications/test/web_app_install_test_utils.h" +#include "chrome/browser/web_applications/web_app_provider.h" #include "content/public/browser/web_contents.h" #include "content/public/test/browser_test_utils.h" #include "net/base/url_util.h" @@ -21,6 +23,8 @@ os_hooks_suppress_ = web_app::OsIntegrationManager::ScopedSuppressOsHooksForTesting(); + web_app::test::WaitUntilReady( + web_app::WebAppProvider::GetForTest(browser()->profile())); } GURL AppBannerManagerBrowserTestBase::GetBannerURL() {
diff --git a/chrome/browser/cart/cart_service.h b/chrome/browser/cart/cart_service.h index 8b4e2d9..60902b4a 100644 --- a/chrome/browser/cart/cart_service.h +++ b/chrome/browser/cart/cart_service.h
@@ -130,6 +130,7 @@ friend class CartServiceBrowserDiscountTest; friend class CartServiceDiscountFetchTest; friend class CartServiceCouponTest; + friend class FetchDiscountWorkerBrowserTest; FRIEND_TEST_ALL_PREFIXES(CartHandlerNtpModuleFakeDataTest, TestEnableFakeData);
diff --git a/chrome/browser/cart/fetch_discount_worker.cc b/chrome/browser/cart/fetch_discount_worker.cc index b62d526b..559d6f3e 100644 --- a/chrome/browser/cart/fetch_discount_worker.cc +++ b/chrome/browser/cart/fetch_discount_worker.cc
@@ -250,6 +250,7 @@ if (!discounts.count(cart_url)) { cart_discount_proto->clear_discount_text(); cart_discount_proto->clear_rule_discount_info(); + cart_discount_proto->clear_has_coupons(); cart_service_delegate_->UpdateCart(cart_url, std::move(cart_proto), is_tester); continue;
diff --git a/chrome/browser/cart/fetch_discount_worker_browsertest.cc b/chrome/browser/cart/fetch_discount_worker_browsertest.cc new file mode 100644 index 0000000..818d98c --- /dev/null +++ b/chrome/browser/cart/fetch_discount_worker_browsertest.cc
@@ -0,0 +1,345 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/test/base/in_process_browser_test.h" + +#include "base/callback_list.h" +#include "base/test/scoped_feature_list.h" +#include "base/test/test_timeouts.h" +#include "chrome/browser/cart/cart_db_content.pb.h" +#include "chrome/browser/cart/cart_service.h" +#include "chrome/browser/commerce/commerce_feature_list.h" +#include "chrome/browser/persisted_state_db/profile_proto_db.h" +#include "chrome/browser/signin/identity_test_environment_profile_adaptor.h" +#include "chrome/common/pref_names.h" +#include "components/keyed_service/content/browser_context_dependency_manager.h" +#include "components/optimization_guide/core/optimization_guide_features.h" +#include "components/prefs/pref_service.h" +#include "components/search/ntp_features.h" +#include "components/signin/public/identity_manager/identity_test_environment.h" +#include "content/public/test/browser_test.h" +#include "net/dns/mock_host_resolver.h" +#include "net/test/embedded_test_server/embedded_test_server.h" +#include "net/test/embedded_test_server/http_request.h" +#include "net/test/embedded_test_server/http_response.h" + +namespace { +std::string BuildPartnerMerchantPattern( + std::vector<std::string>& parter_merchant_list) { + std::string pattern = "("; + pattern += base::JoinString(parter_merchant_list, "|"); + pattern += ")"; + return pattern; +} + +std::unique_ptr<net::test_server::HttpResponse> BasicResponse( + bool return_empty_response, + const net::test_server::HttpRequest& request) { + if (request.relative_url == "/coupons/fl_codeless_discounts.json" && + !return_empty_response) { + return nullptr; + } + auto response = std::make_unique<net::test_server::BasicHttpResponse>(); + response->set_content("{}"); + response->set_content_type("application/json; charset=UTF-8"); + return response; +} + +cart_db::ChromeCartContentProto BuildCartProto(const char* domain, + const char* merchant_url) { + cart_db::ChromeCartContentProto proto; + proto.set_key(domain); + proto.set_merchant_cart_url(merchant_url); + proto.set_timestamp(base::Time::Now().ToDoubleT()); + return proto; +} + +cart_db::ChromeCartContentProto BuildCartProtoWithCoupon( + const char* domain, + const char* merchant_url) { + cart_db::ChromeCartContentProto proto = BuildCartProto(domain, merchant_url); + proto.mutable_discount_info()->set_has_coupons(true); + return proto; +} + +using ShoppingCarts = + std::vector<ProfileProtoDB<cart_db::ChromeCartContentProto>::KeyAndValue>; +} // namespace + +class FetchDiscountWorkerBrowserTest : public InProcessBrowserTest { + public: + void SetUpInProcessBrowserTestFixture() override { + create_services_subscription_ = + BrowserContextDependencyManager::GetInstance() + ->RegisterCreateServicesCallbackForTesting( + base::BindRepeating(&FetchDiscountWorkerBrowserTest:: + OnWillCreateBrowserContextServices, + base::Unretained(this))); + } + + void SetUpOnMainThread() override { + Profile* profile = browser()->profile(); + identity_test_environment_adaptor_ = + std::make_unique<IdentityTestEnvironmentProfileAdaptor>(profile); + service_ = CartServiceFactory::GetForProfile(profile); + + host_resolver()->AddRule("*", "127.0.0.1"); + embedded_test_server()->ServeFilesFromSourceDirectory( + "chrome/test/data/cart"); + embedded_test_server()->RegisterDefaultHandler( + base::BindRepeating(&BasicResponse, false /*return_empty_response*/)); + + // Simulate discount consent is accepted. + profile->GetPrefs()->SetBoolean(prefs::kCartDiscountEnabled, true); + + SignIn(); + } + + void TearDownOnMainThread() override { + identity_test_environment_adaptor_.reset(); + } + + void CheckFLCodelessDiscounts(base::OnceClosure closure, + bool contained_coupon, + std::string expected_discount_text, + bool success, + ShoppingCarts found) { + EXPECT_TRUE(success); + EXPECT_EQ(1U, found.size()); + + EXPECT_TRUE(found[0].second.has_discount_info()); + EXPECT_EQ(contained_coupon, found[0].second.discount_info().has_coupons()); + EXPECT_EQ(expected_discount_text, + found[0].second.discount_info().discount_text()); + + std::move(closure).Run(); + } + + protected: + void OnWillCreateBrowserContextServices(content::BrowserContext* context) { + IdentityTestEnvironmentProfileAdaptor:: + SetIdentityTestEnvironmentFactoriesOnBrowserContext(context); + } + + void SignIn() { + identity_test_environment_adaptor_->identity_test_env() + ->MakePrimaryAccountAvailable("user@gmail.com", + signin::ConsentLevel::kSync); + identity_test_environment_adaptor_->identity_test_env() + ->SetAutomaticIssueOfAccessTokens(true); + } + + void CreateCart(const std::string& domain, + cart_db::ChromeCartContentProto cart_proto) { + CartDB* cart_db = service_->GetDB(); + base::RunLoop run_loop; + + cart_db->AddCart( + domain, cart_proto, + base::BindOnce(&FetchDiscountWorkerBrowserTest::OnCartAdded, + base::Unretained(this), run_loop.QuitClosure())); + run_loop.Run(); + } + + void OnCartAdded(base::OnceClosure closure, bool success) { + EXPECT_TRUE(success); + std::move(closure).Run(); + } + + void StartGettingDiscount() { service_->StartGettingDiscount(); } + + void waitForDiscounts(const std::string& cart_domain) { + satisfied_ = false; + while (true) { + base::RunLoop().RunUntilIdle(); + base::RunLoop run_loop; + service_->LoadCart( + cart_domain, + base::BindOnce(&FetchDiscountWorkerBrowserTest::CheckLastFetchTime, + base::Unretained(this), run_loop.QuitClosure())); + run_loop.Run(); + if (satisfied_) + break; + base::PlatformThread::Sleep(TestTimeouts::tiny_timeout()); + } + } + + void CheckLastFetchTime(base::OnceClosure closure, + bool success, + ShoppingCarts found) { + EXPECT_TRUE(success); + EXPECT_EQ(1U, found.size()); + + if (found[0].second.has_discount_info()) { + if (found[0].second.discount_info().last_fetched_timestamp() != 0) { + satisfied_ = true; + } else { + VLOG(2) << "last_fetched_timestamp not set"; + } + + } else { + VLOG(2) << "Not contain discount_info"; + } + + std::move(closure).Run(); + } + + base::test::ScopedFeatureList scoped_feature_list_; + std::unique_ptr<IdentityTestEnvironmentProfileAdaptor> + identity_test_environment_adaptor_; + base::CallbackListSubscription create_services_subscription_; + CartService* service_; + bool satisfied_; +}; + +class FetchFLCodelessDiscountWorkerBrowserTest + : public FetchDiscountWorkerBrowserTest { + public: + FetchFLCodelessDiscountWorkerBrowserTest() { + parter_merchant_list_.push_back("merchant0.com"); + parter_merchant_list_.push_back("merchant1.com"); + parter_merchant_list_.push_back("merchant2.com"); + } + + void SetUpCommandLine(base::CommandLine* command_line) override { + ASSERT_TRUE(embedded_test_server()->InitializeAndListen()); + + std::vector<base::test::ScopedFeatureList::FeatureAndParams> + enabled_features; + base::FieldTrialParams cart_params, coupon_params; + cart_params[ntp_features::kNtpChromeCartModuleAbandonedCartDiscountParam] = + "true"; + cart_params["CartDiscountFetcherEndpointParam"] = + embedded_test_server() + ->GetURL("/coupons/fl_codeless_discounts.json") + .spec(); + enabled_features.emplace_back(ntp_features::kNtpChromeCartModule, + cart_params); + coupon_params["coupon-partner-merchant-pattern"] = + BuildPartnerMerchantPattern(parter_merchant_list_); + enabled_features.emplace_back(commerce::kRetailCoupons, coupon_params); + scoped_feature_list_.InitWithFeaturesAndParameters( + enabled_features, + /*disabled_features*/ { + optimization_guide::features::kOptimizationHints}); + } + + protected: + std::vector<std::string> parter_merchant_list_; +}; + +IN_PROC_BROWSER_TEST_F(FetchFLCodelessDiscountWorkerBrowserTest, + SimplePercentOffTest) { + embedded_test_server()->StartAcceptingConnections(); + + CreateCart("merchant1.com", + BuildCartProto("merchant1.com", "https://www.merchant1.com/cart")); + + StartGettingDiscount(); + waitForDiscounts("merchant1.com"); + + // Verify discounts. + base::RunLoop run_loop; + std::string expected_discount_text = "10% off"; + service_->LoadCart( + "merchant1.com", + base::BindOnce(&FetchDiscountWorkerBrowserTest::CheckFLCodelessDiscounts, + base::Unretained(this), run_loop.QuitClosure(), true, + expected_discount_text)); + run_loop.Run(); +} + +IN_PROC_BROWSER_TEST_F(FetchFLCodelessDiscountWorkerBrowserTest, + SimpleDollarOffTest) { + embedded_test_server()->StartAcceptingConnections(); + + CreateCart("merchant2.com", + BuildCartProto("merchant2.com", "https://www.merchant2.com/cart")); + + StartGettingDiscount(); + waitForDiscounts("merchant2.com"); + + // Verify discounts. + base::RunLoop run_loop; + std::string expected_discount_text = "$2 off"; + service_->LoadCart( + "merchant2.com", + base::BindOnce(&FetchDiscountWorkerBrowserTest::CheckFLCodelessDiscounts, + base::Unretained(this), run_loop.QuitClosure(), true, + expected_discount_text)); + run_loop.Run(); +} + +IN_PROC_BROWSER_TEST_F(FetchFLCodelessDiscountWorkerBrowserTest, + NoDiscountForThisMerchantTest) { + embedded_test_server()->StartAcceptingConnections(); + + CreateCart("merchant0.com", + BuildCartProto("merchant0.com", "https://www.merchant0.com/cart")); + + StartGettingDiscount(); + waitForDiscounts("merchant0.com"); + + // Verify discounts. + base::RunLoop run_loop; + service_->LoadCart( + "merchant0.com", + base::BindOnce(&FetchDiscountWorkerBrowserTest::CheckFLCodelessDiscounts, + base::Unretained(this), run_loop.QuitClosure(), false, + "")); + run_loop.Run(); +} + +IN_PROC_BROWSER_TEST_F(FetchFLCodelessDiscountWorkerBrowserTest, + TwoCartsOneWithDiscountOneWithoutDiscount) { + embedded_test_server()->StartAcceptingConnections(); + + CreateCart("merchant0.com", + BuildCartProto("merchant0.com", "https://www.merchant0.com/cart")); + CreateCart("merchant1.com", + BuildCartProto("merchant1.com", "https://www.merchant1.com/cart")); + + StartGettingDiscount(); + waitForDiscounts("merchant0.com"); + waitForDiscounts("merchant1.com"); + + // Verify discounts. + base::RunLoop run_loop[2]; + service_->LoadCart( + "merchant0.com", + base::BindOnce(&FetchDiscountWorkerBrowserTest::CheckFLCodelessDiscounts, + base::Unretained(this), run_loop[0].QuitClosure(), false, + "")); + run_loop[0].Run(); + service_->LoadCart( + "merchant1.com", + base::BindOnce(&FetchDiscountWorkerBrowserTest::CheckFLCodelessDiscounts, + base::Unretained(this), run_loop[1].QuitClosure(), true, + "10% off" /*expected_discount_text*/)); + run_loop[1].Run(); +} + +IN_PROC_BROWSER_TEST_F(FetchFLCodelessDiscountWorkerBrowserTest, + CartDiscountBecomeUnavailable) { + CreateCart("merchant1.com", + BuildCartProtoWithCoupon("merchant1.com", + "https://www.merchant1.com/cart")); + + // Config server to return empty response. + embedded_test_server()->RegisterRequestHandler( + base::BindRepeating(&BasicResponse, true /*return_empty_response*/)); + embedded_test_server()->StartAcceptingConnections(); + + StartGettingDiscount(); + waitForDiscounts("merchant1.com"); + + // Verify cart has no coupon discount. + base::RunLoop run_loop; + service_->LoadCart( + "merchant1.com", + base::BindOnce(&FetchDiscountWorkerBrowserTest::CheckFLCodelessDiscounts, + base::Unretained(this), run_loop.QuitClosure(), false, + "")); + run_loop.Run(); +}
diff --git a/chrome/browser/chromeos/extensions/file_manager/file_stream_md5_digester.cc b/chrome/browser/chromeos/extensions/file_manager/file_stream_md5_digester.cc index 4c6eb40..3397c42 100644 --- a/chrome/browser/chromeos/extensions/file_manager/file_stream_md5_digester.cc +++ b/chrome/browser/chromeos/extensions/file_manager/file_stream_md5_digester.cc
@@ -42,8 +42,7 @@ void FileStreamMd5Digester::ReadNextChunk() { const int result = reader_->Read(buffer_.get(), kMd5DigestBufferSize, - base::BindOnce(&FileStreamMd5Digester::OnChunkRead, - base::Unretained(this))); + base::BindOnce(&FileStreamMd5Digester::OnChunkRead, this)); if (result != net::ERR_IO_PENDING) OnChunkRead(result); }
diff --git a/chrome/browser/chromeos/extensions/file_manager/file_stream_md5_digester.h b/chrome/browser/chromeos/extensions/file_manager/file_stream_md5_digester.h index dd0dd43..9516182 100644 --- a/chrome/browser/chromeos/extensions/file_manager/file_stream_md5_digester.h +++ b/chrome/browser/chromeos/extensions/file_manager/file_stream_md5_digester.h
@@ -22,7 +22,8 @@ // Computes the (base-16 encoded) MD5 digest of data extracted from a file // stream. -class FileStreamMd5Digester { +class FileStreamMd5Digester + : public base::RefCountedThreadSafe<FileStreamMd5Digester> { public: using ResultCallback = base::OnceCallback<void(std::string)>; @@ -31,8 +32,6 @@ FileStreamMd5Digester(const FileStreamMd5Digester&) = delete; FileStreamMd5Digester& operator=(const FileStreamMd5Digester&) = delete; - ~FileStreamMd5Digester(); - // Computes an MD5 digest of data read from the given |streamReader|. The // work occurs asynchronously, and the resulting hash is returned via the // |callback|. If an error occurs, |callback| is called with an empty string. @@ -42,6 +41,9 @@ ResultCallback callback); private: + friend class base::RefCountedThreadSafe<FileStreamMd5Digester>; + ~FileStreamMd5Digester(); + // Kicks off a read of the next chunk from the stream. void ReadNextChunk(); // Handles the incoming chunk of data from a stream read.
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc index 6c0c823..92f9255 100644 --- a/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc +++ b/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc
@@ -1093,7 +1093,7 @@ FileManagerPrivateInternalComputeChecksumFunction:: FileManagerPrivateInternalComputeChecksumFunction() - : digester_(new drive::util::FileStreamMd5Digester()) {} + : digester_(base::MakeRefCounted<drive::util::FileStreamMd5Digester>()) {} FileManagerPrivateInternalComputeChecksumFunction:: ~FileManagerPrivateInternalComputeChecksumFunction() = default; @@ -1129,8 +1129,7 @@ &FileManagerPrivateInternalComputeChecksumFunction::RespondWith, this)); content::GetIOThreadTaskRunner({})->PostTask( - FROM_HERE, base::BindOnce(&FileStreamMd5Digester::GetMd5Digest, - base::Unretained(digester_.get()), + FROM_HERE, base::BindOnce(&FileStreamMd5Digester::GetMd5Digest, digester_, std::move(reader), std::move(result_callback))); return RespondLater();
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.h b/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.h index 2ca6bc5..ad9e7c9 100644 --- a/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.h +++ b/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.h
@@ -348,7 +348,7 @@ ResponseAction Run() override; private: - std::unique_ptr<drive::util::FileStreamMd5Digester> digester_; + scoped_refptr<drive::util::FileStreamMd5Digester> digester_; void RespondWith(std::string hash); };
diff --git a/chrome/browser/chromeos/extensions/file_manager/system_notification_manager.cc b/chrome/browser/chromeos/extensions/file_manager/system_notification_manager.cc index 4d7881a..3e64abe 100644 --- a/chrome/browser/chromeos/extensions/file_manager/system_notification_manager.cc +++ b/chrome/browser/chromeos/extensions/file_manager/system_notification_manager.cc
@@ -593,6 +593,8 @@ IDS_DEVICE_UNSUPPORTED_MESSAGE, base::UTF8ToUTF16(volume.drive_label())); } + RecordDeviceNotificationMetric( + DeviceNotificationUmaType::DEVICE_FAIL); } else { if (volume.drive_label().empty()) { message = @@ -606,6 +608,11 @@ // Give a format device button on the notification. notification_buttons.push_back(message_center::ButtonInfo( l10n_util::GetStringUTF16(IDS_DEVICE_UNKNOWN_BUTTON_LABEL))); + RecordDeviceNotificationMetric( + DeviceNotificationUmaType::DEVICE_FAIL_UNKNOWN); + } else { + RecordDeviceNotificationMetric( + DeviceNotificationUmaType::DEVICE_FAIL_UNKNOWN_READONLY); } } break; @@ -620,6 +627,7 @@ IDS_MULTIPART_DEVICE_UNSUPPORTED_MESSAGE, base::UTF8ToUTF16(volume.drive_label())); } + RecordDeviceNotificationMetric(DeviceNotificationUmaType::DEVICE_FAIL); break; default: DLOG(WARNING) << "Unhandled mount status for "
diff --git a/chrome/browser/chromeos/extensions/file_manager/system_notification_manager_unittest.cc b/chrome/browser/chromeos/extensions/file_manager/system_notification_manager_unittest.cc index cc7a03b..6cb07f9 100644 --- a/chrome/browser/chromeos/extensions/file_manager/system_notification_manager_unittest.cc +++ b/chrome/browser/chromeos/extensions/file_manager/system_notification_manager_unittest.cc
@@ -551,6 +551,7 @@ // method. Both parent and child unknown volume filesystems generate // the same nofication. TEST_F(SystemNotificationManagerTest, DeviceUnsupportedDefault) { + base::HistogramTester histogram_tester; std::unique_ptr<Volume> volume(Volume::CreateForTesting( base::FilePath(FILE_PATH_LITERAL("/mount/path1")), VolumeType::VOLUME_TYPE_TESTING, chromeos::DeviceType::DEVICE_TYPE_USB, @@ -580,11 +581,16 @@ EXPECT_EQ( notification_strings.message, u"Sorry, your external storage device is not supported at this time."); + // Check that the correct UMA was emitted. + histogram_tester.ExpectUniqueSample(kNotificationShowHistogramName, + DeviceNotificationUmaType::DEVICE_FAIL, + 1); } // The named version of the device unsupported notification is // generated when the device includes a device label. TEST_F(SystemNotificationManagerTest, DeviceUnsupportedNamed) { + base::HistogramTester histogram_tester; std::unique_ptr<Volume> volume(Volume::CreateForTesting( base::FilePath(FILE_PATH_LITERAL("/mount/path1")), VolumeType::VOLUME_TYPE_TESTING, chromeos::DeviceType::DEVICE_TYPE_USB, @@ -613,6 +619,10 @@ EXPECT_EQ(notification_strings.title, kRemovableDeviceTitle); EXPECT_EQ(notification_strings.message, u"Sorry, the device MyUSB is not supported at this time."); + // Check that the correct UMA was emitted. + histogram_tester.ExpectUniqueSample(kNotificationShowHistogramName, + DeviceNotificationUmaType::DEVICE_FAIL, + 1); } // Multipart device unsupported notifications are generated when there is @@ -622,6 +632,7 @@ // 1) A device navigation notification for the supported file system // 2) The multipart device unsupported notification. TEST_F(SystemNotificationManagerTest, MultipartDeviceUnsupportedDefault) { + base::HistogramTester histogram_tester; // Build a supported file system volume and mount it. std::unique_ptr<Volume> volume1(Volume::CreateForTesting( base::FilePath(FILE_PATH_LITERAL("/mount/path1")), @@ -675,12 +686,17 @@ EXPECT_EQ(notification_strings.message, u"Sorry, at least one partition on your external storage device " u"could not be mounted."); + // A DEVICE_NAVIGATION UMA is emitted during the setup so just check for the + // occurrence of the DEVICE_FAIL sample instead. + histogram_tester.ExpectBucketCount(kNotificationShowHistogramName, + DeviceNotificationUmaType::DEVICE_FAIL, 1); } // The named version of the multipart device unsupported notification is // generated when the device label exists and at least one partition can be // mounted on a device with an unsupported file system on another partition. TEST_F(SystemNotificationManagerTest, MultipartDeviceUnsupportedNamed) { + base::HistogramTester histogram_tester; // Build a supported file system volume and mount it. std::unique_ptr<Volume> volume1(Volume::CreateForTesting( base::FilePath(FILE_PATH_LITERAL("/mount/path1")), @@ -720,6 +736,10 @@ EXPECT_EQ(notification_strings.message, u"Sorry, at least one partition on the device MyUSB could not be " u"mounted."); + // A DEVICE_NAVIGATION UMA is emitted during the setup so just check for the + // occurrence of the DEVICE_FAIL sample instead. + histogram_tester.ExpectBucketCount(kNotificationShowHistogramName, + DeviceNotificationUmaType::DEVICE_FAIL, 1); } // Device fail unknown notifications are generated when the type of filesystem @@ -729,6 +749,7 @@ // These notifications are similar to the device unsupported notifications, // the difference being an unknown vs. unsupported file system. TEST_F(SystemNotificationManagerTest, DeviceFailUnknownDefault) { + base::HistogramTester histogram_tester; std::unique_ptr<Volume> volume(Volume::CreateForTesting( base::FilePath(FILE_PATH_LITERAL("/mount/path1")), VolumeType::VOLUME_TYPE_TESTING, chromeos::DeviceType::DEVICE_TYPE_USB, @@ -759,11 +780,15 @@ u"Sorry, your external storage device could not be recognized."); EXPECT_EQ(notification_strings.buttons.size(), 1); EXPECT_EQ(notification_strings.buttons[0], u"Format this device"); + histogram_tester.ExpectUniqueSample( + kNotificationShowHistogramName, + DeviceNotificationUmaType::DEVICE_FAIL_UNKNOWN, 1); } // The named version of the device fail unknown notification is // generated when the device includes a device label. TEST_F(SystemNotificationManagerTest, DeviceFailUnknownNamed) { + base::HistogramTester histogram_tester; std::unique_ptr<Volume> volume(Volume::CreateForTesting( base::FilePath(FILE_PATH_LITERAL("/mount/path1")), VolumeType::VOLUME_TYPE_TESTING, chromeos::DeviceType::DEVICE_TYPE_USB, @@ -794,6 +819,9 @@ u"Sorry, the device MyUSB could not be recognized."); EXPECT_EQ(notification_strings.buttons.size(), 1); EXPECT_EQ(notification_strings.buttons[0], u"Format this device"); + histogram_tester.ExpectUniqueSample( + kNotificationShowHistogramName, + DeviceNotificationUmaType::DEVICE_FAIL_UNKNOWN, 1); } // Device fail unknown read only notifications are generated when @@ -801,6 +829,7 @@ // The default notification message is generated when there is // no device label. TEST_F(SystemNotificationManagerTest, DeviceFailUnknownReadOnlyDefault) { + base::HistogramTester histogram_tester; std::unique_ptr<Volume> volume(Volume::CreateForTesting( base::FilePath(FILE_PATH_LITERAL("/mount/path1")), VolumeType::VOLUME_TYPE_TESTING, chromeos::DeviceType::DEVICE_TYPE_USB, @@ -831,11 +860,15 @@ u"Sorry, your external storage device could not be recognized."); // Device is read-only, expect no buttons present. EXPECT_EQ(notification_strings.buttons.size(), 0); + histogram_tester.ExpectUniqueSample( + kNotificationShowHistogramName, + DeviceNotificationUmaType::DEVICE_FAIL_UNKNOWN_READONLY, 1); } // The named version of the read only device fail unknown notification is // generated when the device includes a device label. TEST_F(SystemNotificationManagerTest, DeviceFailUnknownReadOnlyNamed) { + base::HistogramTester histogram_tester; std::unique_ptr<Volume> volume(Volume::CreateForTesting( base::FilePath(FILE_PATH_LITERAL("/mount/path1")), VolumeType::VOLUME_TYPE_TESTING, chromeos::DeviceType::DEVICE_TYPE_USB, @@ -864,6 +897,9 @@ EXPECT_EQ(notification_strings.title, kRemovableDeviceTitle); EXPECT_EQ(notification_strings.message, u"Sorry, the device MyUSB could not be recognized."); + histogram_tester.ExpectUniqueSample( + kNotificationShowHistogramName, + DeviceNotificationUmaType::DEVICE_FAIL_UNKNOWN_READONLY, 1); } TEST_F(SystemNotificationManagerTest, TestCopyEvents) {
diff --git a/chrome/browser/commerce/price_tracking/android/BUILD.gn b/chrome/browser/commerce/price_tracking/android/BUILD.gn deleted file mode 100644 index d9a37ffc..0000000 --- a/chrome/browser/commerce/price_tracking/android/BUILD.gn +++ /dev/null
@@ -1,9 +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. - -import("//build/config/android/rules.gni") - -generate_jni("jni_headers") { - sources = [ "java/src/org/chromium/chrome/browser/price_tracking/PriceTrackingNotificationBridge.java" ] -}
diff --git a/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceDropNotifier.java b/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceDropNotifier.java index 28e83d4a..fe9d3cb 100644 --- a/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceDropNotifier.java +++ b/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceDropNotifier.java
@@ -89,7 +89,7 @@ } private final Context mContext; - private ImageFetcher mImageFetcher; + private final ImageFetcher mImageFetcher; private final NotificationWrapperBuilder mNotificationBuilder; private final NotificationManagerProxy mNotificationManagerProxy; private final PriceDropNotificationManager mPriceDropNotificationManager; @@ -99,19 +99,24 @@ * @param context The Android context. */ public static PriceDropNotifier create(Context context) { + ImageFetcher imageFetcher = + ImageFetcherFactory.createImageFetcher(ImageFetcherConfig.NETWORK_ONLY, + Profile.getLastUsedRegularProfile().getProfileKey()); NotificationWrapperBuilder notificationBuilder = NotificationWrapperBuilderFactory.createNotificationWrapperBuilder( ChannelId.PRICE_DROP, new NotificationMetadata(SystemNotificationType.PRICE_DROP_ALERTS, NOTIFICATION_TAG, NOTIFICATION_ID)); - return new PriceDropNotifier( - context, notificationBuilder, new NotificationManagerProxyImpl(context)); + return new PriceDropNotifier(context, imageFetcher, notificationBuilder, + new NotificationManagerProxyImpl(context)); } @VisibleForTesting - PriceDropNotifier(Context context, NotificationWrapperBuilder notificationBuilder, + PriceDropNotifier(Context context, ImageFetcher imageFetcher, + NotificationWrapperBuilder notificationBuilder, NotificationManagerProxy notificationManager) { mContext = context; + mImageFetcher = imageFetcher; mNotificationBuilder = notificationBuilder; mNotificationManagerProxy = notificationManager; mPriceDropNotificationManager = @@ -126,15 +131,6 @@ maybeFetchIcon(notificationData, bitmap -> { showWithIcon(notificationData, bitmap); }); } - @VisibleForTesting - protected ImageFetcher getImageFetcher() { - if (mImageFetcher == null) { - mImageFetcher = ImageFetcherFactory.createImageFetcher(ImageFetcherConfig.NETWORK_ONLY, - Profile.getLastUsedRegularProfile().getProfileKey()); - } - return mImageFetcher; - } - private void maybeFetchIcon( final NotificationData notificationData, Callback<Bitmap> callback) { if (notificationData.iconUrl == null) { @@ -144,7 +140,7 @@ ImageFetcher.Params params = ImageFetcher.Params.create( notificationData.iconUrl, ImageFetcher.PRICE_DROP_NOTIFICATION); - getImageFetcher().fetchImage(params, bitmap -> { callback.onResult(bitmap); }); + mImageFetcher.fetchImage(params, bitmap -> { callback.onResult(bitmap); }); } private void showWithIcon(NotificationData notificationData, @Nullable Bitmap icon) {
diff --git a/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceTrackingNotificationBridge.java b/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceTrackingNotificationBridge.java deleted file mode 100644 index d2064df..0000000 --- a/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceTrackingNotificationBridge.java +++ /dev/null
@@ -1,119 +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. - -package org.chromium.chrome.browser.price_tracking; - -import androidx.annotation.VisibleForTesting; - -import com.google.protobuf.ByteString; -import com.google.protobuf.InvalidProtocolBufferException; - -import org.chromium.base.ContextUtils; -import org.chromium.base.Log; -import org.chromium.base.annotations.CalledByNative; -import org.chromium.chrome.browser.price_tracking.PriceDropNotifier.ActionData; -import org.chromium.chrome.browser.price_tracking.proto.Notifications; -import org.chromium.chrome.browser.price_tracking.proto.Notifications.ChromeMessage; -import org.chromium.chrome.browser.price_tracking.proto.Notifications.ChromeNotification; -import org.chromium.chrome.browser.price_tracking.proto.Notifications.ChromeNotification.NotificationDataType; -import org.chromium.chrome.browser.price_tracking.proto.Notifications.ExpandedView; -import org.chromium.chrome.browser.price_tracking.proto.Notifications.PriceDropNotificationPayload; - -import java.util.ArrayList; -import java.util.List; - -/** - * Class to show a price tracking notification. The Java object is owned by the native side - * PriceTrackingNotificationBridge object through JNI bridge. - */ -public class PriceTrackingNotificationBridge { - private static final String TAG = "PriceTrackNotif"; - private final long mNativePriceTrackingNotificationBridge; - private final PriceDropNotifier mNotifier; - - /** - * Construct a {@link PriceTrackingNotificationBridge} object from native code. - * @param nativePriceTrackingNotificationBridge The native JNI object pointer. - */ - @VisibleForTesting - PriceTrackingNotificationBridge( - long nativePriceTrackingNotificationBridge, PriceDropNotifier notifier) { - mNativePriceTrackingNotificationBridge = nativePriceTrackingNotificationBridge; - mNotifier = notifier; - } - - @CalledByNative - private static PriceTrackingNotificationBridge create( - long nativePriceTrackingNotificationBridge) { - return new PriceTrackingNotificationBridge(nativePriceTrackingNotificationBridge, - PriceDropNotifier.create(ContextUtils.getApplicationContext())); - } - - @VisibleForTesting - @CalledByNative - void showNotification(byte[] payload) { - ChromeNotification chromeNotification; - try { - chromeNotification = ChromeNotification.parseFrom(payload); - } catch (InvalidProtocolBufferException e) { - Log.e(TAG, "Failed to parse ChromeNotification payload."); - return; - } - - if (!chromeNotification.hasChromeMessage()) return; - ChromeMessage chromeMessage = chromeNotification.getChromeMessage(); - if (!chromeMessage.hasDestinationUrl()) return; - - // TODO(xingliu): Use client strings for display text, title, and action text. - // Show the notification. - PriceDropNotifier.NotificationData notificationData = - new PriceDropNotifier.NotificationData(chromeMessage.getDisplayTitle(), - chromeMessage.getDisplayText(), - chromeMessage.hasIconImageUrl() ? chromeMessage.getIconImageUrl() : null, - chromeMessage.getDestinationUrl(), parseOfferId(chromeNotification), - parseActions(chromeNotification)); - mNotifier.showNotification(notificationData); - } - - private static String parseOfferId(ChromeNotification chromeNotification) { - PriceDropNotificationPayload priceDropPayload = null; - Long offerId = null; - if (chromeNotification.hasNotificationData() - && chromeNotification.hasNotificationDataType()) { - if (chromeNotification.getNotificationDataType() - == NotificationDataType.PRICE_DROP_NOTIFICATION) { - priceDropPayload = parsePriceDropPayload(chromeNotification.getNotificationData()); - } - } - if (priceDropPayload != null && priceDropPayload.hasOfferId()) { - offerId = priceDropPayload.getOfferId(); - } - // TODO(crbug.com/1257380): Figure out how to serialize offer id correctly. - return offerId != null ? String.valueOf(offerId) : null; - } - - private static PriceDropNotificationPayload parsePriceDropPayload(ByteString payload) { - PriceDropNotificationPayload priceDropPayload = null; - try { - priceDropPayload = PriceDropNotificationPayload.parseFrom(payload); - } catch (InvalidProtocolBufferException e) { - Log.e(TAG, "Failed to parse PriceDropNotificationPayload."); - } - return priceDropPayload; - } - - private static List<PriceDropNotifier.ActionData> parseActions( - ChromeNotification chromeNotification) { - List<PriceDropNotifier.ActionData> actions = new ArrayList<>(); - if (!chromeNotification.hasChromeMessage()) return actions; - ChromeMessage chromeMessage = chromeNotification.getChromeMessage(); - if (!chromeMessage.hasExpandedView()) return actions; - ExpandedView expandedView = chromeMessage.getExpandedView(); - for (Notifications.Action action : expandedView.getActionList()) { - if (!action.hasActionId() || !action.hasText()) continue; - actions.add(new ActionData(action.getActionId(), action.getText())); - } - return actions; - } -}
diff --git a/chrome/browser/commerce/price_tracking/android/java_sources.gni b/chrome/browser/commerce/price_tracking/android/java_sources.gni index 5f3fb55..f9b2641 100644 --- a/chrome/browser/commerce/price_tracking/android/java_sources.gni +++ b/chrome/browser/commerce/price_tracking/android/java_sources.gni
@@ -5,5 +5,4 @@ price_tracking_java_sources = [ "//chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceDropNotificationManager.java", "//chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceDropNotifier.java", - "//chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceTrackingNotificationBridge.java", ]
diff --git a/chrome/browser/commerce/price_tracking/android/javatests/src/org/chromium/chrome/browser/price_tracking/PriceDropNotifierUnitTest.java b/chrome/browser/commerce/price_tracking/android/javatests/src/org/chromium/chrome/browser/price_tracking/PriceDropNotifierUnitTest.java index e7bbab2c..259d4966 100644 --- a/chrome/browser/commerce/price_tracking/android/javatests/src/org/chromium/chrome/browser/price_tracking/PriceDropNotifierUnitTest.java +++ b/chrome/browser/commerce/price_tracking/android/javatests/src/org/chromium/chrome/browser/price_tracking/PriceDropNotifierUnitTest.java
@@ -12,7 +12,6 @@ import static org.mockito.Mockito.when; import android.app.PendingIntent; -import android.content.Context; import android.graphics.Bitmap; import androidx.annotation.Nullable; @@ -96,22 +95,6 @@ } } - static class TestPriceDropNotifier extends PriceDropNotifier { - private final ImageFetcher mMockImageFetcher; - - TestPriceDropNotifier(Context context, ImageFetcher imageFetcher, - NotificationWrapperBuilder notificationBuilder, - NotificationManagerProxy notificationManager) { - super(context, notificationBuilder, notificationManager); - mMockImageFetcher = imageFetcher; - } - - @Override - protected ImageFetcher getImageFetcher() { - return mMockImageFetcher; - } - } - @Rule public MockitoRule mMockitoRule = MockitoJUnit.rule(); @@ -137,7 +120,7 @@ @Before public void setUp() { ShadowLog.stream = System.out; - mPriceDropNotifier = new TestPriceDropNotifier(ContextUtils.getApplicationContext(), + mPriceDropNotifier = new PriceDropNotifier(ContextUtils.getApplicationContext(), mImageFetcher, mNotificationBuilder, mNotificationManagerProxy); ChromeBrowserInitializer.setForTesting(mChromeInitializer); when(mNotificationBuilder.buildNotificationWrapper()).thenReturn(mNotificationWrapper);
diff --git a/chrome/browser/commerce/price_tracking/android/javatests/src/org/chromium/chrome/browser/price_tracking/PriceTrackingNotificationBridgeUnitTest.java b/chrome/browser/commerce/price_tracking/android/javatests/src/org/chromium/chrome/browser/price_tracking/PriceTrackingNotificationBridgeUnitTest.java deleted file mode 100644 index 0a148e30..0000000 --- a/chrome/browser/commerce/price_tracking/android/javatests/src/org/chromium/chrome/browser/price_tracking/PriceTrackingNotificationBridgeUnitTest.java +++ /dev/null
@@ -1,134 +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. - -package org.chromium.chrome.browser.price_tracking; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; -import org.robolectric.annotation.Config; -import org.robolectric.shadows.ShadowLog; - -import org.chromium.base.test.BaseRobolectricTestRunner; -import org.chromium.chrome.browser.price_tracking.PriceDropNotifier.NotificationData; -import org.chromium.chrome.browser.price_tracking.proto.Notifications.Action; -import org.chromium.chrome.browser.price_tracking.proto.Notifications.ChromeMessage; -import org.chromium.chrome.browser.price_tracking.proto.Notifications.ChromeNotification; -import org.chromium.chrome.browser.price_tracking.proto.Notifications.ChromeNotification.NotificationDataType; -import org.chromium.chrome.browser.price_tracking.proto.Notifications.ExpandedView; -import org.chromium.chrome.browser.price_tracking.proto.Notifications.PriceDropNotificationPayload; - -/** - * Unit test for {@link PriceDropNotifier}. - */ -@RunWith(BaseRobolectricTestRunner.class) -@Config(manifest = Config.NONE) -public class PriceTrackingNotificationBridgeUnitTest { - private static final String TITLE = "title"; - private static final String TEXT = "text"; - private static final String ICON_URL = "http://www.example.com/icon"; - private static final String DESTINATION_URL = "http://www.example.com/destination"; - private static final long OFFER_ID = 10L; - private static final String ACTION_ID_0 = "action_id_0"; - private static final String ACTION_ID_1 = "action_id_1"; - private static final String ACTION_TEXT_0 = "action_text_0"; - private static final String ACTION_TEXT_1 = "action_text_1"; - - private PriceTrackingNotificationBridge mPriceTrackingNotificationBridge; - - @Rule - public MockitoRule mMockitoRule = MockitoJUnit.rule(); - - @Mock - PriceDropNotifier mNotifier; - - @Captor - ArgumentCaptor<PriceDropNotifier.NotificationData> mNotificationDataCaptor; - - @Before - public void setUp() { - ShadowLog.stream = System.out; - mPriceTrackingNotificationBridge = new PriceTrackingNotificationBridge(0, mNotifier); - } - - // Creates a ChromeNotification.Builder that sets a valid ChromeNotification proto. - private ChromeNotification.Builder createValidPayload() { - return createPayloadWithChromeMessage(createValidChromeMessage()); - } - - // Create a ChromeNotification.Builder with specific ChromeMessage. - private ChromeNotification.Builder createPayloadWithChromeMessage( - ChromeMessage.Builder chromeMessage) { - ChromeNotification.Builder builder = ChromeNotification.newBuilder(); - builder.setNotificationDataType(NotificationDataType.PRICE_DROP_NOTIFICATION); - - // Only offer id is used in unido code path. - PriceDropNotificationPayload.Builder priceDropPayload = - PriceDropNotificationPayload.newBuilder(); - priceDropPayload.setOfferId(OFFER_ID); - builder.setNotificationData(priceDropPayload.build().toByteString()); - builder.setChromeMessage(chromeMessage.build()); - return builder; - } - - // Create a valid ChromeMessage proto builder. - private ChromeMessage.Builder createValidChromeMessage() { - // Create ChromeMessage, some fields are duplicated to PriceDropNotificationPayload, - ChromeMessage.Builder message = ChromeMessage.newBuilder(); - message.setDisplayTitle(TITLE); - message.setDisplayText(TEXT); - message.setIconImageUrl(ICON_URL); - message.setDestinationUrl(DESTINATION_URL); - ExpandedView.Builder expandedView = ExpandedView.newBuilder(); - expandedView.addAction(Action.newBuilder().setActionId(ACTION_ID_0).setText(ACTION_TEXT_0)); - expandedView.addAction(Action.newBuilder().setActionId(ACTION_ID_1).setText(ACTION_TEXT_1)); - message.setExpandedView(expandedView.build()); - return message; - } - - @Test - public void testShowNotification_ValidProto() { - mPriceTrackingNotificationBridge.showNotification( - createValidPayload().build().toByteArray()); - verify(mNotifier).showNotification(mNotificationDataCaptor.capture()); - NotificationData data = mNotificationDataCaptor.getValue(); - Assert.assertEquals(TITLE, data.title); - Assert.assertEquals(TEXT, data.text); - Assert.assertEquals(ICON_URL, data.iconUrl); - Assert.assertEquals(DESTINATION_URL, data.destinationUrl); - Assert.assertEquals(ACTION_ID_0, data.actions.get(0).actionId); - Assert.assertEquals(ACTION_TEXT_0, data.actions.get(0).text); - Assert.assertEquals(ACTION_ID_1, data.actions.get(1).actionId); - Assert.assertEquals(ACTION_TEXT_1, data.actions.get(1).text); - Assert.assertEquals(String.valueOf(OFFER_ID), data.offerId); - } - - @Test - public void testShowNotification_NoChromeMessage() { - ChromeNotification.Builder builder = createValidPayload(); - builder.clearChromeMessage(); - mPriceTrackingNotificationBridge.showNotification(builder.build().toByteArray()); - verify(mNotifier, times(0)).showNotification(any()); - } - - @Test - public void testShowNotification_NoDestinationURL() { - ChromeMessage.Builder chromeMessage = createValidChromeMessage(); - chromeMessage.clearDestinationUrl(); - ChromeNotification.Builder builder = createPayloadWithChromeMessage(chromeMessage); - mPriceTrackingNotificationBridge.showNotification(builder.build().toByteArray()); - verify(mNotifier, times(0)).showNotification(any()); - } -}
diff --git a/chrome/browser/commerce/price_tracking/android/price_tracking_notification_bridge.cc b/chrome/browser/commerce/price_tracking/android/price_tracking_notification_bridge.cc deleted file mode 100644 index 456c97b..0000000 --- a/chrome/browser/commerce/price_tracking/android/price_tracking_notification_bridge.cc +++ /dev/null
@@ -1,50 +0,0 @@ -// Copyright 2021 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/commerce/price_tracking/android/price_tracking_notification_bridge.h" - -#include "base/android/jni_array.h" -#include "base/memory/ptr_util.h" -#include "chrome/browser/commerce/price_tracking/android/jni_headers/PriceTrackingNotificationBridge_jni.h" -#include "content/public/browser/browser_context.h" - -using OptimizationType = optimization_guide::proto::OptimizationType; - -const char kUserDataKey[] = "commerce.price_tracking_notification_bridge"; - -// static -PriceTrackingNotificationBridge* -PriceTrackingNotificationBridge::GetForBrowserContext( - content::BrowserContext* context) { - if (!context->GetUserData(kUserDataKey)) { - context->SetUserData(kUserDataKey, - base::WrapUnique(new PriceTrackingNotificationBridge)); - } - return static_cast<PriceTrackingNotificationBridge*>( - context->GetUserData(kUserDataKey)); -} - -PriceTrackingNotificationBridge::PriceTrackingNotificationBridge() { - JNIEnv* env = base::android::AttachCurrentThread(); - java_obj_.Reset(env, Java_PriceTrackingNotificationBridge_create( - env, reinterpret_cast<intptr_t>(this)) - .obj()); -} - -PriceTrackingNotificationBridge::~PriceTrackingNotificationBridge() = default; - -void PriceTrackingNotificationBridge::OnNotificationPayload( - optimization_guide::proto::OptimizationType optimization_type, - const optimization_guide::proto::Any& payload) { - // Only parse PRICE_TRACKING payload. - if (optimization_type != OptimizationType::PRICE_TRACKING || - !payload.has_value()) { - return; - } - - // Pass the payload to Java. - JNIEnv* env = base::android::AttachCurrentThread(); - Java_PriceTrackingNotificationBridge_showNotification( - env, java_obj_, base::android::ToJavaByteArray(env, payload.value())); -}
diff --git a/chrome/browser/commerce/price_tracking/android/price_tracking_notification_bridge.h b/chrome/browser/commerce/price_tracking/android/price_tracking_notification_bridge.h deleted file mode 100644 index 4330bfe..0000000 --- a/chrome/browser/commerce/price_tracking/android/price_tracking_notification_bridge.h +++ /dev/null
@@ -1,42 +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. - -#ifndef CHROME_BROWSER_COMMERCE_PRICE_TRACKING_ANDROID_PRICE_TRACKING_NOTIFICATION_BRIDGE_H_ -#define CHROME_BROWSER_COMMERCE_PRICE_TRACKING_ANDROID_PRICE_TRACKING_NOTIFICATION_BRIDGE_H_ - -#include "base/android/scoped_java_ref.h" -#include "base/supports_user_data.h" -#include "components/optimization_guide/core/push_notification_manager.h" -#include "components/optimization_guide/proto/common_types.pb.h" -#include "components/optimization_guide/proto/push_notification.pb.h" - -namespace content { -class BrowserContext; -} // namespace content - -// JNI bridge that receives the price tracking notification payload from -// optimization_guide::PushNotificationManager. This class is owned by a browser -// context through SupportsUserData. -class PriceTrackingNotificationBridge - : public optimization_guide::PushNotificationManager::Observer, - public base::SupportsUserData::Data { - public: - // Get the bridge from a browser context. - static PriceTrackingNotificationBridge* GetForBrowserContext( - content::BrowserContext* context); - ~PriceTrackingNotificationBridge() override; - - // optimization_guide::PushNotificationManager::Observer implementation. - void OnNotificationPayload( - optimization_guide::proto::OptimizationType optimization_type, - const optimization_guide::proto::Any& payload) override; - - private: - PriceTrackingNotificationBridge(); - - // The Java object, owned by the native object. - base::android::ScopedJavaGlobalRef<jobject> java_obj_; -}; - -#endif // CHROME_BROWSER_COMMERCE_PRICE_TRACKING_ANDROID_PRICE_TRACKING_NOTIFICATION_BRIDGE_H_
diff --git a/chrome/browser/commerce/price_tracking/android/test_java_sources.gni b/chrome/browser/commerce/price_tracking/android/test_java_sources.gni index 0663454..7950aa7 100644 --- a/chrome/browser/commerce/price_tracking/android/test_java_sources.gni +++ b/chrome/browser/commerce/price_tracking/android/test_java_sources.gni
@@ -4,7 +4,4 @@ price_tracking_test_java_sources = [ "//chrome/browser/commerce/price_tracking/android/javatests/src/org/chromium/chrome/browser/price_tracking/PriceDropNotificationManagerTest.java" ] -price_tracking_junit_test_java_sources = [ - "//chrome/browser/commerce/price_tracking/android/javatests/src/org/chromium/chrome/browser/price_tracking/PriceDropNotifierUnitTest.java", - "//chrome/browser/commerce/price_tracking/android/javatests/src/org/chromium/chrome/browser/price_tracking/PriceTrackingNotificationBridgeUnitTest.java", -] +price_tracking_junit_test_java_sources = [ "//chrome/browser/commerce/price_tracking/android/javatests/src/org/chromium/chrome/browser/price_tracking/PriceDropNotifierUnitTest.java" ]
diff --git a/chrome/browser/commerce/price_tracking/proto/BUILD.gn b/chrome/browser/commerce/price_tracking/proto/BUILD.gn index b12177a..8d079a9 100644 --- a/chrome/browser/commerce/price_tracking/proto/BUILD.gn +++ b/chrome/browser/commerce/price_tracking/proto/BUILD.gn
@@ -5,8 +5,6 @@ import("//build/config/android/rules.gni") import("//third_party/protobuf/proto_library.gni") -proto_java_library("proto_java") { - proto_path = "//" +proto_library("notifications_proto") { sources = [ "notifications.proto" ] - deps = [ "//components/commerce/core:proto_java" ] }
diff --git a/chrome/browser/commerce/price_tracking/proto/notifications.proto b/chrome/browser/commerce/price_tracking/proto/notifications.proto index a8cf97d..8f07db73 100644 --- a/chrome/browser/commerce/price_tracking/proto/notifications.proto +++ b/chrome/browser/commerce/price_tracking/proto/notifications.proto
@@ -4,12 +4,10 @@ syntax = "proto2"; -package commerce.proto; +package org.chromium.chrome.browser.price_tracking.proto; option optimize_for = LITE_RUNTIME; option java_package = "org.chromium.chrome.browser.price_tracking.proto"; -import "components/commerce/core/proto/price_tracking.proto"; - // Copied from // google3/java/com/google/chrome/memex/service/proto/shopping/notifications.proto, // must synced with the google3 proto. Contains either a ChromeMessage to @@ -50,12 +48,3 @@ optional string action_id = 1; optional string text = 2; } - -// Contains notification metadata for Chrome Price Drop notifications. -message PriceDropNotificationPayload { - optional string product_name = 1; - optional uint64 offer_id = 2; - optional string destination_url = 3; - optional commerce.ProductPrice current_price = 4; - optional commerce.ProductPrice previous_price = 5; -}
diff --git a/chrome/browser/extensions/DEPS b/chrome/browser/extensions/DEPS index d3aad9a7..3406b3a 100644 --- a/chrome/browser/extensions/DEPS +++ b/chrome/browser/extensions/DEPS
@@ -22,7 +22,7 @@ ], "content_script_apitest.cc": [ - "+components/web_package/test_support", + "+components/web_package", ], "extension_protocols_unittest\.cc": [ "+services/network/test",
diff --git a/chrome/browser/extensions/api/DEPS b/chrome/browser/extensions/api/DEPS index 5a22ab5e..c2f7fbe1 100644 --- a/chrome/browser/extensions/api/DEPS +++ b/chrome/browser/extensions/api/DEPS
@@ -11,7 +11,7 @@ ".*test.*": [ "+chrome/browser/ui/views/frame", "+components/captive_portal", - "+components/web_package/test_support", + "+components/web_package", "+skia/public/mojom/bitmap.mojom.h", ], "tls_socket_unittest\.cc": [
diff --git a/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc b/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc index 271c7d5..e73d07a3 100644 --- a/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc +++ b/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc
@@ -60,7 +60,7 @@ #include "components/prefs/pref_service.h" #include "components/proxy_config/proxy_config_dictionary.h" #include "components/proxy_config/proxy_config_pref_names.h" -#include "components/web_package/test_support/web_bundle_builder.h" +#include "components/web_package/web_bundle_builder.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" @@ -5477,7 +5477,7 @@ // of a web bundle. So we use |pass_js_url_str| for the fallback URL. // TODO(crbug.com/966753): Stop using |pass_js_url_str| when // https://github.com/WICG/webpackage/issues/590 is resolved. - web_package::test::WebBundleBuilder builder(pass_js_url_str, ""); + web_package::WebBundleBuilder builder(pass_js_url_str, ""); auto pass_js_location = builder.AddResponse( {{":status", "200"}, {"content-type", "application/javascript"}}, "document.title = 'script loaded';"); @@ -5550,7 +5550,7 @@ // of a web bundle. So we use |pass_js_url_str| for the fallback URL. // TODO(crbug.com/966753): Stop using |pass_js_url_str| when // https://github.com/WICG/webpackage/issues/590 is resolved. - web_package::test::WebBundleBuilder builder(pass_js_url, ""); + web_package::WebBundleBuilder builder(pass_js_url, ""); auto pass_js_location = builder.AddResponse( {{":status", "200"}, {"content-type", "application/javascript"}}, "document.title = 'script loaded';"); @@ -5629,7 +5629,7 @@ // of a web bundle. So we use |redirect_js_url_str| for the fallback URL. // TODO(crbug.com/966753): Stop using |redirect_js_url_str| when // https://github.com/WICG/webpackage/issues/590 is resolved. - web_package::test::WebBundleBuilder builder(redirect_js_url_str, ""); + web_package::WebBundleBuilder builder(redirect_js_url_str, ""); auto redirect_js_location = builder.AddResponse( {{":status", "200"}, {"content-type", "application/javascript"}}, "document.title = 'redirect';"); @@ -5719,7 +5719,7 @@ // Create a web bundle. std::string js_url_str = embedded_test_server()->GetURL("/script.js").spec(); - web_package::test::WebBundleBuilder builder(js_url_str, ""); + web_package::WebBundleBuilder builder(js_url_str, ""); builder.AddExchange( js_url_str, {{":status", "200"}, {"content-type", "application/javascript"}},
diff --git a/chrome/browser/extensions/api/terminal/terminal_private_api.cc b/chrome/browser/extensions/api/terminal/terminal_private_api.cc index 71d18a1d..4e7f992 100644 --- a/chrome/browser/extensions/api/terminal/terminal_private_api.cc +++ b/chrome/browser/extensions/api/terminal/terminal_private_api.cc
@@ -45,6 +45,7 @@ #include "extensions/browser/app_window/app_window_registry.h" #include "extensions/browser/event_router.h" #include "extensions/browser/extensions_browser_client.h" +#include "ui/display/types/display_constants.h" namespace terminal_private = extensions::api::terminal_private; namespace OnTerminalResize = @@ -58,6 +59,7 @@ namespace SendInput = extensions::api::terminal_private::SendInput; namespace AckOutput = extensions::api::terminal_private::AckOutput; namespace SetSettings = extensions::api::terminal_private::SetSettings; +namespace OpenWindow = extensions::api::terminal_private::OpenWindow; using crostini::mojom::InstallerState; @@ -604,7 +606,17 @@ default; ExtensionFunction::ResponseAction TerminalPrivateOpenWindowFunction::Run() { - crostini::LaunchTerminal(Profile::FromBrowserContext(browser_context())); + std::unique_ptr<OpenWindow::Params> params( + OpenWindow::Params::Create(args())); + EXTENSION_FUNCTION_VALIDATE(params.get()); + + if (params->data && params->data->url) { + crostini::LaunchTerminalWithUrl( + Profile::FromBrowserContext(browser_context()), + display::kInvalidDisplayId, GURL(*params->data->url)); + } else { + crostini::LaunchTerminal(Profile::FromBrowserContext(browser_context())); + } return RespondNow(NoArguments()); }
diff --git a/chrome/browser/extensions/api/web_request/web_request_apitest.cc b/chrome/browser/extensions/api/web_request/web_request_apitest.cc index c752dfd..c77ebc4 100644 --- a/chrome/browser/extensions/api/web_request/web_request_apitest.cc +++ b/chrome/browser/extensions/api/web_request/web_request_apitest.cc
@@ -70,7 +70,7 @@ #include "components/prefs/pref_service.h" #include "components/proxy_config/proxy_config_dictionary.h" #include "components/proxy_config/proxy_config_pref_names.h" -#include "components/web_package/test_support/web_bundle_builder.h" +#include "components/web_package/web_bundle_builder.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/navigation_controller.h" @@ -3574,7 +3574,7 @@ // of a web bundle. So we use |script_url_str| for the fallback URL. // TODO(crbug.com/966753): Stop using |script_url_str| when // https://github.com/WICG/webpackage/issues/590 is resolved. - web_package::test::WebBundleBuilder builder(script_url_str, ""); + web_package::WebBundleBuilder builder(script_url_str, ""); auto script_location = builder.AddResponse( {{":status", "200"}, {"content-type", "application/javascript"}}, "document.title = 'ScriptDone';"); @@ -3697,7 +3697,7 @@ embedded_test_server()->GetURL("/pass.js").spec(); std::string cancel_js_url_str = embedded_test_server()->GetURL("/cancel.js").spec(); - web_package::test::WebBundleBuilder builder(pass_js_url_str, ""); + web_package::WebBundleBuilder builder(pass_js_url_str, ""); auto pass_js_location = builder.AddResponse( {{":status", "200"}, {"content-type", "application/javascript"}}, "document.title = 'script loaded';"); @@ -3821,7 +3821,7 @@ // Create a web bundle. std::string target_txt_url_str = embedded_test_server()->GetURL("/target.txt").spec(); - web_package::test::WebBundleBuilder builder(target_txt_url_str, ""); + web_package::WebBundleBuilder builder(target_txt_url_str, ""); auto target_txt_location = builder.AddResponse( {{":status", "200"}, {"content-type", "text/plain"}, {"foo", "bar"}}, "Hello world"); @@ -3924,7 +3924,7 @@ ASSERT_TRUE(StartEmbeddedTestServer()); // Create a web bundle. - web_package::test::WebBundleBuilder builder(uun_uuid_url, ""); + web_package::WebBundleBuilder builder(uun_uuid_url, ""); auto uun_uuid_script = builder.AddResponse( {{":status", "200"}, {"content-type", "application/javascript"}}, "document.title = 'loaded';"); @@ -4036,7 +4036,7 @@ embedded_test_server()->GetURL("/redirected_to_unlisted.js").spec(); std::string redirect_to_server_js_url_str = embedded_test_server()->GetURL("/redirect_to_server.js").spec(); - web_package::test::WebBundleBuilder builder(redirect_js_url_str, ""); + web_package::WebBundleBuilder builder(redirect_js_url_str, ""); auto redirect_js_location = builder.AddResponse( {{":status", "200"}, {"content-type", "application/javascript"}}, "document.title = 'redirect';"); @@ -4132,7 +4132,7 @@ // Create a web bundle. std::string js_url_str = embedded_test_server()->GetURL("/script.js").spec(); - web_package::test::WebBundleBuilder builder(js_url_str, ""); + web_package::WebBundleBuilder builder(js_url_str, ""); builder.AddExchange( js_url_str, {{":status", "200"}, {"content-type", "application/javascript"}},
diff --git a/chrome/browser/extensions/content_script_apitest.cc b/chrome/browser/extensions/content_script_apitest.cc index 199cdaa..8f5cf2e 100644 --- a/chrome/browser/extensions/content_script_apitest.cc +++ b/chrome/browser/extensions/content_script_apitest.cc
@@ -31,7 +31,7 @@ #include "chrome/test/base/ui_test_utils.h" #include "components/javascript_dialogs/tab_modal_dialog_manager.h" #include "components/policy/core/browser/browser_policy_connector.h" -#include "components/web_package/test_support/web_bundle_builder.h" +#include "components/web_package/web_bundle_builder.h" #include "content/public/browser/javascript_dialog_manager.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" @@ -1953,7 +1953,7 @@ // of a web bundle. So we use |urn_uuid_html_url| for the fallback URL. // TODO(crbug.com/966753): Stop using |urn_uuid_html_url| when // https://github.com/WICG/webpackage/issues/590 is resolved. - web_package::test::WebBundleBuilder builder(urn_uuid_html_url, ""); + web_package::WebBundleBuilder builder(urn_uuid_html_url, ""); auto html_location = builder.AddResponse({{":status", "200"}, {"content-type", "text/html"}}, "<script>console.error('hoge');</script>");
diff --git a/chrome/browser/extensions/extension_prefs_unittest.cc b/chrome/browser/extensions/extension_prefs_unittest.cc index 0f712d34..9874822a 100644 --- a/chrome/browser/extensions/extension_prefs_unittest.cc +++ b/chrome/browser/extensions/extension_prefs_unittest.cc
@@ -735,15 +735,6 @@ { base::DictionaryValue dictionary; - dictionary.SetString(manifest_keys::kName, "from_bookmark"); - dictionary.SetString(manifest_keys::kVersion, "0.1"); - dictionary.SetInteger(manifest_keys::kManifestVersion, 2); - bookmark_extension_ = prefs_.AddExtensionWithManifestAndFlags( - dictionary, ManifestLocation::kInternal, Extension::FROM_BOOKMARK); - } - - { - base::DictionaryValue dictionary; dictionary.SetString(manifest_keys::kName, "was_installed_by_default"); dictionary.SetString(manifest_keys::kVersion, "0.1"); dictionary.SetInteger(manifest_keys::kManifestVersion, 2); @@ -765,18 +756,12 @@ void Verify() override { EXPECT_TRUE(prefs()->IsFromWebStore(webstore_extension_->id())); - EXPECT_FALSE(prefs()->IsFromBookmark(webstore_extension_->id())); - - EXPECT_TRUE(prefs()->IsFromBookmark(bookmark_extension_->id())); - EXPECT_FALSE(prefs()->IsFromWebStore(bookmark_extension_->id())); - EXPECT_TRUE(prefs()->WasInstalledByDefault(default_extension_->id())); EXPECT_TRUE(prefs()->WasInstalledByOem(oem_extension_->id())); } private: scoped_refptr<Extension> webstore_extension_; - scoped_refptr<Extension> bookmark_extension_; scoped_refptr<Extension> default_extension_; scoped_refptr<Extension> oem_extension_; };
diff --git a/chrome/browser/extensions/extension_service_unittest.cc b/chrome/browser/extensions/extension_service_unittest.cc index e5e6afa..5cbc294b 100644 --- a/chrome/browser/extensions/extension_service_unittest.cc +++ b/chrome/browser/extensions/extension_service_unittest.cc
@@ -1261,8 +1261,6 @@ // Tests that flags passed to OnExternalExtensionFileFound() make it to the // extension object. TEST_F(ExtensionServiceTest, InstallingExternalExtensionWithFlags) { - const char kPrefFromBookmark[] = "from_bookmark"; - InitializeEmptyExtensionService(); base::FilePath path = data_dir().AppendASCII("good.crx"); @@ -1281,12 +1279,10 @@ registry()->enabled_extensions().GetByID(good_crx); ASSERT_TRUE(extension); ASSERT_TRUE(extension->from_bookmark()); - ASSERT_TRUE(ValidateBooleanPref(good_crx, kPrefFromBookmark, true)); // Upgrade to version 2.0, the flag should be preserved. path = data_dir().AppendASCII("good2.crx"); UpdateExtension(good_crx, path, ENABLED); - ASSERT_TRUE(ValidateBooleanPref(good_crx, kPrefFromBookmark, true)); extension = registry()->enabled_extensions().GetByID(good_crx); ASSERT_TRUE(extension); ASSERT_TRUE(extension->from_bookmark()); @@ -4680,8 +4676,6 @@ TEST_F(ExtensionServiceTest, MAYBE_UpdatingPendingExternalExtensionWithFlags) { // Regression test for crbug.com/627522 - const char kPrefFromBookmark[] = "from_bookmark"; - InitializeEmptyExtensionService(); base::FilePath path = data_dir().AppendASCII("good.crx"); @@ -4701,7 +4695,6 @@ // Upgrade to version 2.0, the flag should be preserved. path = data_dir().AppendASCII("good2.crx"); UpdateExtension(good_crx, path, ENABLED); - ASSERT_TRUE(ValidateBooleanPref(good_crx, kPrefFromBookmark, true)); const Extension* extension = registry()->enabled_extensions().GetByID(good_crx); ASSERT_TRUE(extension);
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index baad1e43..c3aea1d 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -5411,6 +5411,7 @@ #endif // BUILDFLAG(ENABLE_SIDE_SEARCH) #if BUILDFLAG(ENABLE_WEBUI_TAB_STRIP) +const char kWebUITabStripFlagId[] = "webui-tab-strip"; const char kWebUITabStripName[] = "WebUI tab strip"; const char kWebUITabStripDescription[] = "When enabled makes use of a WebUI-based tab strip.";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index c940335..d0af920 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -3142,6 +3142,7 @@ #endif // BUILDFLAG(ENABLE_SIDE_SEARCH) #if BUILDFLAG(ENABLE_WEBUI_TAB_STRIP) +extern const char kWebUITabStripFlagId[]; extern const char kWebUITabStripName[]; extern const char kWebUITabStripDescription[];
diff --git a/chrome/browser/lacros/browser_service_lacros.cc b/chrome/browser/lacros/browser_service_lacros.cc index 039911f..d4eff4e 100644 --- a/chrome/browser/lacros/browser_service_lacros.cc +++ b/chrome/browser/lacros/browser_service_lacros.cc
@@ -86,9 +86,15 @@ void BrowserServiceLacros::NewFullscreenWindow( const GURL& url, NewFullscreenWindowCallback callback) { - // TODO(anqing): refactor the following window control logic and make it - // shared by both lacros and ash chrome. + // Get the current user profile. Report an error to ash if it doesn't exist. Profile* profile = ProfileManager::GetLastUsedProfileAllowedByPolicy(); + if (!profile) { + std::move(callback).Run(crosapi::mojom::CreationResult::kProfileNotExist); + return; + } + + // Launch a fullscreen window with the user profile, and navigate to the + // target URL. Browser::CreateParams params = Browser::CreateParams::CreateForApp( "app_name", true, gfx::Rect(), profile, false); params.initial_show_state = ui::SHOW_STATE_FULLSCREEN; @@ -96,8 +102,14 @@ NavigateParams nav_params(browser, url, ui::PageTransition::PAGE_TRANSITION_AUTO_TOPLEVEL); Navigate(&nav_params); - CHECK(browser); - CHECK(browser->window()); + + // Verify the creation result of browser window. + if (!browser || !browser->window()) { + std::move(callback).Run( + crosapi::mojom::CreationResult::kBrowserWindowUnavailable); + return; + } + browser->window()->Show(); // TODO(crbug/1247638): we'd better figure out a better solution to move this @@ -107,8 +119,9 @@ KioskSessionServiceLacros::Get()->InitWebKioskSession(browser); } - // TODO(anqing): valicate current profile and window status, and return - // non-success result if anything is wrong. + // Report a success result to ash. Please note that showing Lacros window is + // asynchronous. Ash-chrome should use the `exo::WMHelper` class rather than + // this callback method call to track window creation status. std::move(callback).Run(crosapi::mojom::CreationResult::kSuccess); }
diff --git a/chrome/browser/lifetime/application_lifetime.cc b/chrome/browser/lifetime/application_lifetime.cc index 782604ed..894b9fa 100644 --- a/chrome/browser/lifetime/application_lifetime.cc +++ b/chrome/browser/lifetime/application_lifetime.cc
@@ -163,6 +163,7 @@ PrefService* pref_service = g_browser_process->local_state(); pref_service->SetBoolean(prefs::kWasRestarted, true); + KeepAliveRegistry::GetInstance()->SetRestarting(); #if BUILDFLAG(IS_CHROMEOS_ASH) chromeos::BootTimesRecorder::Get()->set_restart_requested();
diff --git a/chrome/browser/net/chrome_network_delegate.cc b/chrome/browser/net/chrome_network_delegate.cc index 74aeb2ab..d602d24 100644 --- a/chrome/browser/net/chrome_network_delegate.cc +++ b/chrome/browser/net/chrome_network_delegate.cc
@@ -12,10 +12,6 @@ #if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) #include "base/files/file_util.h" #include "base/system/sys_info.h" -#include "chrome/browser/download/download_prefs.h" -#endif - -#if BUILDFLAG(IS_CHROMEOS_LACROS) #include "chrome/common/chrome_paths.h" #endif @@ -83,10 +79,6 @@ if (base::PathService::Get(base::DIR_TEMP, &temp_dir)) allowlist.push_back(temp_dir); - // For developers on linux-chromeos, MyFiles dir is at $HOME/Downloads. - if (!base::SysInfo::IsRunningOnChromeOS()) - allowlist.push_back(base::GetHomeDir().Append("Downloads")); - #if BUILDFLAG(IS_CHROMEOS_ASH) // The actual location of "/home/chronos/user/Xyz" is the Xyz directory under // the profile path ("/home/chronos/user' is a hard link to current primary @@ -100,10 +92,19 @@ const base::FilePath webrtc_logs = profile_path.AppendASCII("WebRTC Logs"); allowlist.push_back(webrtc_logs); } + // For developers using the linux-chromeos emulator, the MyFiles dir is at + // $HOME/Downloads. Ensure developers can access it for manual testing. + if (!base::SysInfo::IsRunningOnChromeOS()) { + base::FilePath downloads_dir; + if (base::PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS, &downloads_dir)) + allowlist.push_back(downloads_dir); + } #else // Lacros uses the system-level documents directory and downloads directory // under /home/chronos/u-<hash>, which are provided via PathService. Since // they are system-level, they are not subdirectories of |profile_path|. + // PathService also provides valid paths for developers using the + // linux-chromeos emulator. base::FilePath documents_dir; if (base::PathService::Get(chrome::DIR_USER_DOCUMENTS, &documents_dir)) allowlist.push_back(documents_dir);
diff --git a/chrome/browser/net/chrome_network_delegate_unittest.cc b/chrome/browser/net/chrome_network_delegate_unittest.cc index e3074ee..76f489fb 100644 --- a/chrome/browser/net/chrome_network_delegate_unittest.cc +++ b/chrome/browser/net/chrome_network_delegate_unittest.cc
@@ -16,9 +16,6 @@ #include "base/system/sys_info.h" #include "base/test/scoped_running_on_chromeos.h" #include "base/time/time.h" -#endif - -#if BUILDFLAG(IS_CHROMEOS_LACROS) #include "chrome/common/chrome_paths.h" #endif @@ -86,6 +83,14 @@ EXPECT_TRUE(IsAccessAllowed("/profile/Downloads", "/profile")); EXPECT_TRUE(IsAccessAllowed("/profile/MyFiles", "/profile")); EXPECT_TRUE(IsAccessAllowed("/profile/MyFiles/file.pdf", "/profile")); + // $HOME/Downloads is allowed for linux-chromeos, but not on devices. + base::FilePath downloads_dir; + base::PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS, &downloads_dir); + EXPECT_TRUE(IsAccessAllowed(downloads_dir.AsUTF8Unsafe(), "")); + { + base::test::ScopedRunningOnChromeOS running_on_chromeos; + EXPECT_FALSE(IsAccessAllowed(downloads_dir.AsUTF8Unsafe(), "")); + } #endif #if BUILDFLAG(IS_CHROMEOS_LACROS) @@ -113,14 +118,6 @@ EXPECT_FALSE(IsAccessAllowed("/profile/GCache/v2", "/profile")); EXPECT_FALSE(IsAccessAllowed("/home/chronos/user/GCache/v2/id/Logs", "")); - // $HOME/Downloads is allowed for linux-chromeos, but not on devices. - std::string home_downloads = base::GetHomeDir().Append("Downloads").value(); - EXPECT_TRUE(IsAccessAllowed(home_downloads, "")); - { - base::test::ScopedRunningOnChromeOS running_on_chromeos; - EXPECT_FALSE(IsAccessAllowed(home_downloads, "")); - } - #elif defined(OS_ANDROID) // Android allows the following directories. EXPECT_TRUE(IsAccessAllowed("/sdcard", ""));
diff --git a/chrome/browser/notifications/arc_application_notifier_controller.cc b/chrome/browser/notifications/arc_application_notifier_controller.cc index e9dedf65..ec593e2 100644 --- a/chrome/browser/notifications/arc_application_notifier_controller.cc +++ b/chrome/browser/notifications/arc_application_notifier_controller.cc
@@ -13,6 +13,7 @@ #include "chrome/browser/notifications/notifier_dataset.h" #include "chrome/browser/profiles/profile.h" #include "components/services/app_service/public/cpp/app_update.h" +#include "components/services/app_service/public/cpp/permission_utils.h" #include "components/services/app_service/public/mojom/types.mojom.h" #include "ui/message_center/public/cpp/message_center_constants.h" #include "ui/message_center/public/cpp/notifier_id.h" @@ -52,7 +53,7 @@ apps::mojom::PermissionType::kNotifications) { continue; } - DCHECK(permission->value_type == apps::mojom::PermissionValueType::kBool); + DCHECK(permission->value->is_bool_value()); // Do not include notifier metadata for system apps. if (update.InstallReason() == apps::mojom::InstallReason::kSystem) { return; @@ -60,7 +61,7 @@ notifier_dataset.push_back(NotifierDataset{ update.AppId() /*app_id*/, update.ShortName() /*app_name*/, update.PublisherId() /*publisher_id*/, - !!permission->value /*enabled*/}); + permission->value->get_bool_value() /*enabled*/}); } }); @@ -92,8 +93,8 @@ last_used_profile_ = profile; auto permission = apps::mojom::Permission::New(); permission->permission_type = apps::mojom::PermissionType::kNotifications; - permission->value_type = apps::mojom::PermissionValueType::kBool; - permission->value = enabled; + permission->value = apps::mojom::PermissionValue::New(); + permission->value->set_bool_value(enabled); permission->is_managed = false; apps::AppServiceProxy* service = apps::AppServiceProxyFactory::GetForProfile(profile); @@ -147,7 +148,8 @@ apps::mojom::PermissionType::kNotifications) { message_center::NotifierId notifier_id( message_center::NotifierType::ARC_APPLICATION, update.AppId()); - observer_->OnNotifierEnabledChanged(notifier_id, permission->value); + observer_->OnNotifierEnabledChanged( + notifier_id, apps_util::IsPermissionEnabled(permission->value)); } } }
diff --git a/chrome/browser/notifications/pwa_notifier_controller.cc b/chrome/browser/notifications/pwa_notifier_controller.cc index 85b4b1b..f812b2c 100644 --- a/chrome/browser/notifications/pwa_notifier_controller.cc +++ b/chrome/browser/notifications/pwa_notifier_controller.cc
@@ -11,6 +11,7 @@ #include "chrome/browser/notifications/notifier_dataset.h" #include "chrome/browser/profiles/profile.h" #include "components/services/app_service/public/cpp/app_update.h" +#include "components/services/app_service/public/cpp/permission_utils.h" #include "components/services/app_service/public/mojom/types.mojom.h" #include "ui/message_center/public/cpp/message_center_constants.h" #include "ui/message_center/public/cpp/notifier_id.h" @@ -44,8 +45,7 @@ apps::mojom::PermissionType::kNotifications) { continue; } - DCHECK(permission->value_type == - apps::mojom::PermissionValueType::kTriState); + DCHECK(permission->value->is_tristate_value()); // Do not include notifier metadata for system apps. if (update.InstallReason() == apps::mojom::InstallReason::kSystem) { return; @@ -53,10 +53,7 @@ notifier_dataset.push_back(NotifierDataset{ update.AppId() /*app_id*/, update.ShortName() /*app_name*/, update.PublisherId() /*publisher_id*/, - static_cast<apps::mojom::TriState>(permission->value) == - apps::mojom::TriState::kAllow - ? true - : false /*enabled*/}); + apps_util::IsPermissionEnabled(permission->value)}); } }); std::vector<ash::NotifierMetadata> notifiers; @@ -89,8 +86,8 @@ DCHECK(observed_profile_->IsSameOrParent(profile)); auto permission = apps::mojom::Permission::New(); permission->permission_type = apps::mojom::PermissionType::kNotifications; - permission->value_type = apps::mojom::PermissionValueType::kTriState; - permission->value = static_cast<uint32_t>( + permission->value = apps::mojom::PermissionValue::New(); + permission->value->set_tristate_value( enabled ? apps::mojom::TriState::kAllow : apps::mojom::TriState::kBlock); permission->is_managed = false; apps::AppServiceProxy* service = @@ -142,7 +139,8 @@ apps::mojom::PermissionType::kNotifications) { message_center::NotifierId notifier_id( message_center::NotifierType::APPLICATION, update.AppId()); - observer_->OnNotifierEnabledChanged(notifier_id, permission->value); + observer_->OnNotifierEnabledChanged( + notifier_id, apps_util::IsPermissionEnabled(permission->value)); } } }
diff --git a/chrome/browser/optimization_guide/android/android_push_notification_manager_unittest.cc b/chrome/browser/optimization_guide/android/android_push_notification_manager_unittest.cc index 3ad4f5ca..162b1264 100644 --- a/chrome/browser/optimization_guide/android/android_push_notification_manager_unittest.cc +++ b/chrome/browser/optimization_guide/android/android_push_notification_manager_unittest.cc
@@ -112,8 +112,6 @@ ASSERT_TRUE(profile_manager_.SetUp(temp_dir_.GetPath())); profile_ = profile_manager_.CreateTestingProfile(chrome::kInitialProfile); - Java_OptimizationGuidePushNotificationTestHelper_setUpMocks(env_, j_test_); - service_ = static_cast<OptimizationGuideKeyedService*>( OptimizationGuideKeyedServiceFactory::GetInstance() ->SetTestingFactoryAndUse( @@ -124,6 +122,8 @@ service_->GetHintsManager()->push_notification_manager()->AddObserver( &observer_); + Java_OptimizationGuidePushNotificationTestHelper_setUpMocks(env_, j_test_); + // It takes two session starts for experimental params and feature flags to // be picked up by Java, so override them manually. Java_OptimizationGuidePushNotificationTestHelper_setOverflowSizeForTesting(
diff --git a/chrome/browser/optimization_guide/chrome_hints_manager.cc b/chrome/browser/optimization_guide/chrome_hints_manager.cc index bcd354e..63eec4e 100644 --- a/chrome/browser/optimization_guide/chrome_hints_manager.cc +++ b/chrome/browser/optimization_guide/chrome_hints_manager.cc
@@ -19,7 +19,6 @@ #include "services/network/public/cpp/shared_url_loader_factory.h" #if defined(OS_ANDROID) -#include "chrome/browser/commerce/price_tracking/android/price_tracking_notification_bridge.h" #include "chrome/browser/optimization_guide/android/android_push_notification_manager.h" #endif @@ -27,18 +26,12 @@ // Creates the platform specific push notification manager. std::unique_ptr<optimization_guide::PushNotificationManager> -MaybeCreatePushNotificationManager(Profile* profile, - PrefService* pref_service) { +MaybeCreatePushNotificationManager(PrefService* pref_service) { #if defined(OS_ANDROID) if (optimization_guide::features::IsPushNotificationsEnabled()) { - auto push_notification_manager = std::make_unique< + return std::make_unique< optimization_guide::android::AndroidPushNotificationManager>( pref_service); - // TODO(xingliu): Move this to OptimizationGuideKeyedServiceFactory. See - // crbug.com/1256908. - push_notification_manager->AddObserver( - PriceTrackingNotificationBridge::GetForBrowserContext(profile)); - return push_notification_manager; } #endif return nullptr; @@ -85,7 +78,7 @@ tab_url_provider, url_loader_factory, network_connection_tracker, - MaybeCreatePushNotificationManager(profile, pref_service)), + MaybeCreatePushNotificationManager(pref_service)), profile_(profile) { NavigationPredictorKeyedService* navigation_predictor_service = NavigationPredictorKeyedServiceFactory::GetForProfile(profile);
diff --git a/chrome/browser/resources/chromeos/accessibility/accessibility_common_manifest.json.jinja2 b/chrome/browser/resources/chromeos/accessibility/accessibility_common_manifest.json.jinja2 index d51026b..e69dbfa1 100644 --- a/chrome/browser/resources/chromeos/accessibility/accessibility_common_manifest.json.jinja2 +++ b/chrome/browser/resources/chromeos/accessibility/accessibility_common_manifest.json.jinja2
@@ -31,9 +31,7 @@ "input_components": [ { "name": "Dictation", - "type": "ime", "id": "dictation", - "description": "Dictation", "language": ["none"] } ]
diff --git a/chrome/browser/resources/settings/chromeos/BUILD.gn b/chrome/browser/resources/settings/chromeos/BUILD.gn index 1504ad85e4..03d7703 100644 --- a/chrome/browser/resources/settings/chromeos/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/BUILD.gn
@@ -258,6 +258,8 @@ "chromeos/os_apps_page/app_management_page/types.js", "chromeos/os_apps_page/app_management_page/util.js", "chromeos/os_apps_page/app_notifications_page/mojo_interface_provider.js", + "chromeos/os_apps_page/permission_constants.js", + "chromeos/os_apps_page/permission_util.js", "chromeos/os_languages_page/input_method_settings.js", "chromeos/os_languages_page/languages_browser_proxy.js", "chromeos/os_languages_page/languages.js",
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_apps_page/BUILD.gn index eda4686..aeb1ba9 100644 --- a/chrome/browser/resources/settings/chromeos/os_apps_page/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/BUILD.gn
@@ -13,6 +13,8 @@ ":android_apps_browser_proxy", ":android_apps_subpage", ":os_apps_page", + ":permission_constants", + ":permission_util", ] } @@ -58,6 +60,17 @@ ] } +js_library("permission_util") { + deps = [ + ":permission_constants", + "//ui/webui/resources/js:assert.m", + ] +} + +js_library("permission_constants") { + deps = [ "//chrome/browser/ui/webui/app_management:mojo_bindings_js_library_for_compile" ] +} + html_to_js("web_components") { js_files = [ "android_apps_subpage.js",
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/BUILD.gn index 63b0ffe..290a938 100644 --- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/BUILD.gn
@@ -308,6 +308,7 @@ js_library("util") { deps = [ + "../:permission_constants", "../..:os_route.m", "../../..:router", ]
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/browser_proxy.js b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/browser_proxy.js index 454b70f3..1f49d7e 100644 --- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/browser_proxy.js +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/browser_proxy.js
@@ -14,7 +14,9 @@ import {addSingletonGetter} from 'chrome://resources/js/cr.m.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; -import {AppType, InstallReason, PermissionType, TriState} from './constants.js'; +import {PermissionType, TriState} from '../permission_constants.js'; + +import {AppType, InstallReason} from './constants.js'; import {FakePageHandler} from './fake_page_handler.js'; export class BrowserProxy {
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/constants.js b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/constants.js index 0eea81c..c3e2189 100644 --- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/constants.js +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/constants.js
@@ -28,31 +28,14 @@ DETAIL: 1, }; -/** - * A number representation of a Bool. Permission values should be of this type - * for permissions with value type PermissionValueType.kBool. - * @enum {number} - * @const - */ -export const Bool = { - kFalse: 0, - kTrue: 1, -}; - export const AppType = apps.mojom.AppType; -export const PermissionValueType = apps.mojom.PermissionValueType; - -export const TriState = apps.mojom.TriState; - export const OptionalBool = apps.mojom.OptionalBool; export const InstallReason = apps.mojom.InstallReason; export const WindowMode = apps.mojom.WindowMode; -export const PermissionType = apps.mojom.PermissionType; - // This histogram is also declared and used at chrome/browser/ui/webui/settings/ // chromeos/app_management/app_management_uma.h. export const AppManagementEntryPointsHistogramName =
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/fake_page_handler.js b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/fake_page_handler.js index 92ab454..ae98192 100644 --- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/fake_page_handler.js +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/fake_page_handler.js
@@ -4,9 +4,12 @@ import {assert} from 'chrome://resources/js/assert.m.js'; import {PromiseResolver} from 'chrome://resources/js/promise_resolver.m.js'; -import {AppType, Bool, OptionalBool, PermissionType, PermissionValueType, TriState} from './constants.js'; + +import {PermissionType, PermissionValue, TriState} from '../permission_constants.js'; +import {createBoolPermission, createTriStatePermission, getTriStatePermissionValue} from '../permission_util.js'; + +import {AppType, OptionalBool} from './constants.js'; import {AppManagementStore} from './store.js'; -import {createPermission} from './util.js'; /** * @implements {appManagement.mojom.PageHandlerInterface} @@ -32,12 +35,12 @@ if (options && options[permissionType]) { const opts = options[permissionType]; - permissionValue = opts.permissionValue || permissionValue; + permissionValue = + getTriStatePermissionValue(opts.value) || permissionValue; isManaged = opts.isManaged || isManaged; } - permissions[permissionType] = createPermission( - permissionType, PermissionValueType.kTriState, permissionValue, - isManaged); + permissions[permissionType] = + createTriStatePermission(permissionType, permissionValue, isManaged); } return permissions; @@ -60,9 +63,8 @@ const permissions = {}; for (const permissionType of permissionTypes) { - permissions[permissionType] = createPermission( - permissionType, PermissionValueType.kBool, Bool.kTrue, - false /*is_managed*/); + permissions[permissionType] = + createBoolPermission(permissionType, true, false /*is_managed*/); } return permissions;
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/permission_item.js b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/permission_item.js index 7abaebe..ac3489d 100644 --- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/permission_item.js +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/permission_item.js
@@ -8,11 +8,13 @@ import {afterNextRender, flush, html, Polymer, TemplateInstanceBase, Templatizer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {recordClick, recordNavigation, recordPageBlur, recordPageFocus, recordSearch, recordSettingChange, setUserActionRecorderForTesting} from '../../metrics_recorder.m.js'; +import {PermissionType, PermissionValue, TriState} from '../permission_constants.js'; +import {createBoolPermission, createTriStatePermission, getBoolPermissionValue, getTriStatePermissionValue, isBoolValue, isTriStateValue} from '../permission_util.js'; import {BrowserProxy} from './browser_proxy.js'; -import {AppManagementUserAction, Bool, PermissionType, PermissionValueType, TriState} from './constants.js'; +import {AppManagementUserAction} from './constants.js'; import {AppManagementStoreClient} from './store_client.js'; -import {createPermission, getPermission, getPermissionValueBool, getSelectedApp, recordAppManagementUserAction} from './util.js'; +import {getPermission, getPermissionValueBool, getSelectedApp, recordAppManagementUserAction} from './util.js'; Polymer({ _template: html`{__html_template__}`, @@ -166,20 +168,21 @@ let newPermission; let newBoolState = false; // to keep the closure compiler happy. - switch (getPermission(this.app_, this.permissionType).valueType) { - case PermissionValueType.kBool: - newPermission = - this.getUIPermissionBoolean_(this.app_, this.permissionType); - newBoolState = newPermission.value === Bool.kTrue; - break; - case PermissionValueType.kTriState: - newPermission = - this.getUIPermissionTriState_(this.app_, this.permissionType); - newBoolState = newPermission.value === TriState.kAllow; - break; - default: - assertNotReached(); + const permissionValue = getPermission(this.app_, this.permissionType).value; + if (isBoolValue(permissionValue)) { + newPermission = + this.getUIPermissionBoolean_(this.app_, this.permissionType); + newBoolState = getBoolPermissionValue(newPermission.value); + } else if (isTriStateValue(permissionValue)) { + newPermission = + this.getUIPermissionTriState_(this.app_, this.permissionType); + + newBoolState = + getTriStatePermissionValue(newPermission.value) === TriState.kAllow; + } else { + assertNotReached(); } + BrowserProxy.getInstance().handler.setPermission( this.app_.id, newPermission); @@ -199,23 +202,15 @@ * @private */ getUIPermissionBoolean_(app, permissionType) { - let newPermissionValue; const currentPermission = getPermission(app, permissionType); - switch (currentPermission.value) { - case Bool.kFalse: - newPermissionValue = Bool.kTrue; - break; - case Bool.kTrue: - newPermissionValue = Bool.kFalse; - break; - default: - assertNotReached(); - } - assert(newPermissionValue !== undefined); - return createPermission( - PermissionType[permissionType], PermissionValueType.kBool, - newPermissionValue, currentPermission.isManaged); + assert(isBoolValue(currentPermission.value)); + + const newPermissionValue = !getBoolPermissionValue(currentPermission.value); + + return createBoolPermission( + PermissionType[permissionType], newPermissionValue, + currentPermission.isManaged); }, /** @@ -230,7 +225,9 @@ let newPermissionValue; const currentPermission = getPermission(app, permissionType); - switch (currentPermission.value) { + assert(isTriStateValue(currentPermission.value)); + + switch (getTriStatePermissionValue(currentPermission.value)) { case TriState.kBlock: newPermissionValue = TriState.kAllow; break; @@ -249,9 +246,9 @@ } assert(newPermissionValue !== undefined); - return createPermission( - PermissionType[permissionType], PermissionValueType.kTriState, - newPermissionValue, currentPermission.isManaged); + return createTriStatePermission( + PermissionType[permissionType], newPermissionValue, + currentPermission.isManaged); }, /**
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/util.js b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/util.js index 1e83aa05..e674fd2 100644 --- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/util.js +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/util.js
@@ -8,8 +8,11 @@ import {Route, Router} from '../../../router.js'; import {routes} from '../../os_route.m.js'; +import {PermissionType, PermissionValue, TriState} from '../permission_constants.js'; +import {getBoolPermissionValue, getTriStatePermissionValue, isPermissionEnabled} from '../permission_util.js'; -import {AppManagementUserAction, AppType, Bool, OptionalBool, PermissionType, PermissionValueType, TriState, WindowMode} from './constants.js'; +import {AppManagementUserAction, AppType, OptionalBool, WindowMode} from './constants.js'; + /** * @fileoverview Utility functions for the App Management page. @@ -40,22 +43,6 @@ } /** - * @param {PermissionType} permissionType - * @param {!PermissionValueType} valueType - * @param {number} value - * @param {boolean} isManaged - * @return {!Permission} - */ -export function createPermission(permissionType, valueType, value, isManaged) { - return { - permissionType, - valueType, - value, - isManaged, - }; -} - -/** * @param {App} app * @return {string} */ @@ -104,14 +91,7 @@ const permission = getPermission(app, permissionType); assert(permission); - switch (permission.valueType) { - case PermissionValueType.kBool: - return permission.value === Bool.kTrue; - case PermissionValueType.kTriState: - return permission.value === TriState.kAllow; - default: - assertNotReached(); - } + return isPermissionEnabled(permission.value); } /**
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 be4ab14..3e27d53d 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
@@ -18,6 +18,7 @@ closure_flags = os_settings_closure_flags is_polymer3 = true deps = [ + ":app_notification_row", ":app_notifications_subpage", ":mojo_interface_provider", ] @@ -39,6 +40,8 @@ js_library("app_notification_row") { deps = [ + "../:permission_constants", + "../:permission_util", "../..:metrics_recorder.m", "//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.js b/chrome/browser/resources/settings/chromeos/os_apps_page/app_notifications_page/app_notification_row.js index ae449a7..0249cc84 100644 --- 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
@@ -14,6 +14,7 @@ import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {recordSettingChange} from '../../metrics_recorder.m.js'; +import {createBoolPermissionValue, createTriStatePermissionValue, isBoolValue, isPermissionEnabled, isTriStateValue} from '../permission_util.js'; import {getAppNotificationProvider} from './mojo_interface_provider.js'; @@ -58,34 +59,20 @@ } isNotificationPermissionEnabled_() { - if (this.app.notificationPermission.valueType === - apps.mojom.PermissionValueType.kBool && - this.app.notificationPermission.value === 1) { - this.checked_ = true; - return; - } - - if (this.app.notificationPermission.valueType === - apps.mojom.PermissionValueType.kTriState && - this.app.notificationPermission.value === apps.mojom.TriState.kAllow) { - this.checked_ = true; - return; - } - - this.checked_ = false; + this.checked_ = isPermissionEnabled(this.app.notificationPermission.value); } /** @param {!Event} event */ onNotificationRowClicked_(event) { const permission = this.app.notificationPermission; - if (permission.valueType === apps.mojom.PermissionValueType.kBool) { - // apps.mojom.permission.value expects a number type. - permission.value = this.checked_ ? 0 : 1; - } else if ( - permission.valueType === apps.mojom.PermissionValueType.kTriState) { - permission.value = this.checked_ ? apps.mojom.TriState.kBlock : - apps.mojom.TriState.kAllow; + if (isBoolValue(permission.value)) { + permission.value = + createBoolPermissionValue(this.checked_ ? false : true); + } else if (isTriStateValue(permission.value)) { + permission.value = createTriStatePermissionValue( + this.checked_ ? apps.mojom.TriState.kBlock : + apps.mojom.TriState.kAllow); } this.mojoInterfaceProvider_.setNotificationPermission(
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/permission_constants.js b/chrome/browser/resources/settings/chromeos/os_apps_page/permission_constants.js new file mode 100644 index 0000000..75256e57 --- /dev/null +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/permission_constants.js
@@ -0,0 +1,14 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js'; + +import '/app-management/types.mojom-lite.js'; + + +export const TriState = apps.mojom.TriState; + +export const PermissionType = apps.mojom.PermissionType; + +export const PermissionValue = apps.mojom.PermissionValue;
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/permission_util.js b/chrome/browser/resources/settings/chromeos/os_apps_page/permission_util.js new file mode 100644 index 0000000..962b0ad --- /dev/null +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/permission_util.js
@@ -0,0 +1,109 @@ +// 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 {assert, assertNotReached} from 'chrome://resources/js/assert.m.js'; + +import {PermissionType, PermissionValue, TriState} from './permission_constants.js'; + +/** + * @param {PermissionType} permissionType + * @param {PermissionValue} value + * @param {boolean} isManaged + * @return {!apps.mojom.Permission} + */ +export function createPermission(permissionType, value, isManaged) { + return { + permissionType, + value, + isManaged, + }; +} + +/** + * @param {TriState} value + * @returns {PermissionValue} + */ +export function createTriStatePermissionValue(value) { + return {tristateValue: value}; +} + +/** + * @param {PermissionValue} permissionValue + * @returns {TriState} + */ +export function getTriStatePermissionValue(permissionValue) { + assert(isTriStateValue(permissionValue)); + return permissionValue['tristateValue']; +} + +/** + * @param {boolean} value + * @returns {PermissionValue} + */ +export function createBoolPermissionValue(value) { + return {boolValue: value}; +} + +/** + * @param {PermissionValue} permissionValue + * @returns {boolean} + */ +export function getBoolPermissionValue(permissionValue) { + assert(isBoolValue(permissionValue)); + return permissionValue['boolValue']; +} + +/** + * @param {PermissionValue} permissionValue + * @returns {boolean} + */ +export function isTriStateValue(permissionValue) { + return permissionValue['tristateValue'] !== undefined && + permissionValue['boolValue'] === undefined; +} + +/** + * @param {PermissionValue} permissionValue + * @returns {boolean} + */ +export function isBoolValue(permissionValue) { + return permissionValue['boolValue'] !== undefined && + permissionValue['tristateValue'] === undefined; +} + +/** + * @param {PermissionType} permissionType + * @param {boolean} value + * @param {boolean} isManaged + * @return {!apps.mojom.Permission} + */ +export function createBoolPermission(permissionType, value, isManaged) { + return createPermission( + permissionType, createBoolPermissionValue(value), isManaged); +} + +/** + * @param {PermissionType} permissionType + * @param {TriState} value + * @param {boolean} isManaged + * @return {!apps.mojom.Permission} + */ +export function createTriStatePermission(permissionType, value, isManaged) { + return createPermission( + permissionType, createTriStatePermissionValue(value), isManaged); +} + +/** + * @param {PermissionValue} permissionValue + * @returns {boolean} + */ +export function isPermissionEnabled(permissionValue) { + if (isBoolValue(permissionValue)) { + return getBoolPermissionValue(permissionValue); + } else if (isTriStateValue(permissionValue)) { + return getTriStatePermissionValue(permissionValue) === TriState.kAllow; + } else { + assertNotReached(); + } +}
diff --git a/chrome/browser/resources/settings/chromeos/os_settings.js b/chrome/browser/resources/settings/chromeos/os_settings.js index b25e535..d6aff2d7 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings.js +++ b/chrome/browser/resources/settings/chromeos/os_settings.js
@@ -129,14 +129,16 @@ export {AndroidAppsBrowserProxyImpl} from './os_apps_page/android_apps_browser_proxy.js'; export {addApp, changeApp, removeApp, updateSelectedAppId} from './os_apps_page/app_management_page/actions.js'; export {BrowserProxy} from './os_apps_page/app_management_page/browser_proxy.js'; -export {Bool, PageType, PermissionType, PermissionValueType, TriState, WindowMode} from './os_apps_page/app_management_page/constants.js'; +export {PageType, WindowMode} from './os_apps_page/app_management_page/constants.js'; export {FakePageHandler} from './os_apps_page/app_management_page/fake_page_handler.js'; export {PluginVmBrowserProxyImpl} from './os_apps_page/app_management_page/plugin_vm_page/plugin_vm_browser_proxy.js'; export {AppState, reduceAction} from './os_apps_page/app_management_page/reducers.js'; export {AppManagementStore} from './os_apps_page/app_management_page/store.js'; export {AppManagementStoreClientImpl} from './os_apps_page/app_management_page/store_client.js'; -export {convertOptionalBoolToBool, createEmptyState, createInitialState, createPermission, getPermissionValueBool} from './os_apps_page/app_management_page/util.js'; +export {convertOptionalBoolToBool, createEmptyState, createInitialState, getPermissionValueBool} from './os_apps_page/app_management_page/util.js'; export {setAppNotificationProviderForTesting} from './os_apps_page/app_notifications_page/mojo_interface_provider.js'; +export {PermissionType, TriState} from './os_apps_page/permission_constants.js'; +export {createBoolPermission, createTriStatePermission, getBoolPermissionValue, isBoolValue} from './os_apps_page/permission_util.js'; export {osPageVisibility} from './os_page_visibility.m.js'; export {AccountManagerBrowserProxy, AccountManagerBrowserProxyImpl} from './os_people_page/account_manager_browser_proxy.js'; export {FingerprintBrowserProxyImpl, FingerprintResultType} from './os_people_page/fingerprint_browser_proxy.m.js';
diff --git a/chrome/browser/translate/chrome_translate_client.cc b/chrome/browser/translate/chrome_translate_client.cc index 9dd9050..7d880b1 100644 --- a/chrome/browser/translate/chrome_translate_client.cc +++ b/chrome/browser/translate/chrome_translate_client.cc
@@ -102,9 +102,8 @@ *web_contents, &web_contents->GetController(), UrlLanguageHistogramFactory::GetForBrowserContext( web_contents->GetBrowserContext()), - TranslateModelServiceFactory::GetOrBuildForKey( - Profile::FromBrowserContext(web_contents->GetBrowserContext()) - ->GetProfileKey())); + TranslateModelServiceFactory::GetForProfile( + Profile::FromBrowserContext(web_contents->GetBrowserContext()))); } translate_manager_ = std::make_unique<translate::TranslateManager>( this,
diff --git a/chrome/browser/translate/translate_model_service_browsertest.cc b/chrome/browser/translate/translate_model_service_browsertest.cc index 6af8880..6e98855 100644 --- a/chrome/browser/translate/translate_model_service_browsertest.cc +++ b/chrome/browser/translate/translate_model_service_browsertest.cc
@@ -101,8 +101,8 @@ IN_PROC_BROWSER_TEST_F(TranslateModelServiceDisabledBrowserTest, TranslateModelServiceDisabled) { - EXPECT_FALSE(TranslateModelServiceFactory::GetOrBuildForKey( - browser()->profile()->GetProfileKey())); + EXPECT_FALSE( + TranslateModelServiceFactory::GetForProfile(browser()->profile())); } class TranslateModelServiceWithoutOptimizationGuideBrowserTest @@ -125,8 +125,8 @@ // the optimization guide does not exist. IN_PROC_BROWSER_TEST_F(TranslateModelServiceWithoutOptimizationGuideBrowserTest, TranslateModelServiceEnabled) { - EXPECT_FALSE(TranslateModelServiceFactory::GetOrBuildForKey( - browser()->profile()->GetProfileKey())); + EXPECT_FALSE( + TranslateModelServiceFactory::GetForProfile(browser()->profile())); } IN_PROC_BROWSER_TEST_F(TranslateModelServiceDisabledBrowserTest, @@ -167,8 +167,7 @@ ~TranslateModelServiceBrowserTest() override = default; translate::TranslateModelService* translate_model_service() { - return TranslateModelServiceFactory::GetOrBuildForKey( - browser()->profile()->GetProfileKey()); + return TranslateModelServiceFactory::GetForProfile(browser()->profile()); } const GURL& english_url() const { return english_url_; } @@ -215,11 +214,8 @@ IN_PROC_BROWSER_TEST_F(TranslateModelServiceBrowserTest, TranslateModelServiceEnabled_OffTheRecord) { - EXPECT_TRUE(TranslateModelServiceFactory::GetOrBuildForKey( - browser() - ->profile() - ->GetPrimaryOTRProfile(/*create_if_needed=*/true) - ->GetProfileKey())); + EXPECT_TRUE(TranslateModelServiceFactory::GetForProfile( + browser()->profile()->GetPrimaryOTRProfile(/*create_if_needed=*/true))); } IN_PROC_BROWSER_TEST_F(TranslateModelServiceBrowserTest, @@ -303,17 +299,6 @@ } IN_PROC_BROWSER_TEST_F(TranslateModelServiceBrowserTest, - LanguageDetectionModelCreated) { - base::HistogramTester histogram_tester; - ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), english_url())); - RetryForHistogramUntilCountReached( - &histogram_tester, - "LanguageDetection.TFLiteModel.WasModelAvailableForDetection", 1); - histogram_tester.ExpectUniqueSample( - "LanguageDetection.TFLiteModel.WasModelAvailableForDetection", false, 1); -} - -IN_PROC_BROWSER_TEST_F(TranslateModelServiceBrowserTest, LanguageDetectionModelAvailableForDetection) { base::HistogramTester histogram_tester; OptimizationGuideKeyedServiceFactory::GetForProfile(browser()->profile())
diff --git a/chrome/browser/translate/translate_model_service_factory.cc b/chrome/browser/translate/translate_model_service_factory.cc index c0c0718..6ca5eb9 100644 --- a/chrome/browser/translate/translate_model_service_factory.cc +++ b/chrome/browser/translate/translate_model_service_factory.cc
@@ -10,19 +10,17 @@ #include "base/task/thread_pool.h" #include "chrome/browser/optimization_guide/optimization_guide_keyed_service.h" #include "chrome/browser/optimization_guide/optimization_guide_keyed_service_factory.h" +#include "chrome/browser/profiles/incognito_helpers.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/profiles/profile_key.h" -#include "chrome/browser/profiles/profile_manager.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" -#include "components/keyed_service/core/simple_dependency_manager.h" #include "components/translate/content/browser/translate_model_service.h" #include "components/translate/core/common/translate_util.h" // static -translate::TranslateModelService* -TranslateModelServiceFactory::GetOrBuildForKey(SimpleFactoryKey* key) { +translate::TranslateModelService* TranslateModelServiceFactory::GetForProfile( + Profile* profile) { return static_cast<translate::TranslateModelService*>( - GetInstance()->GetServiceForKey(key, true)); + GetInstance()->GetServiceForBrowserContext(profile, true)); } // static @@ -32,36 +30,33 @@ } TranslateModelServiceFactory::TranslateModelServiceFactory() - : SimpleKeyedServiceFactory("TranslateModelService", - SimpleDependencyManager::GetInstance()) {} + : BrowserContextKeyedServiceFactory( + "TranslateModelService", + BrowserContextDependencyManager::GetInstance()) {} TranslateModelServiceFactory::~TranslateModelServiceFactory() = default; -std::unique_ptr<KeyedService> -TranslateModelServiceFactory::BuildServiceInstanceFor( - SimpleFactoryKey* key) const { +KeyedService* TranslateModelServiceFactory::BuildServiceInstanceFor( + content::BrowserContext* context) const { if (!translate::IsTFLiteLanguageDetectionEnabled()) return nullptr; + // The optimization guide service must be available for the translate model // service to be created. auto* opt_guide = OptimizationGuideKeyedServiceFactory::GetForProfile( - ProfileManager::GetProfileFromProfileKey( - ProfileKey::FromSimpleFactoryKey(key))); + Profile::FromBrowserContext(context)); + if (opt_guide) { scoped_refptr<base::SequencedTaskRunner> background_task_runner = base::ThreadPool::CreateSequencedTaskRunner( {base::MayBlock(), base::TaskPriority::BEST_EFFORT}); - return std::make_unique<translate::TranslateModelService>( - opt_guide, background_task_runner); + return new translate::TranslateModelService(opt_guide, + background_task_runner); } return nullptr; } -SimpleFactoryKey* TranslateModelServiceFactory::GetKeyToUse( - SimpleFactoryKey* key) const { - // The translate model service should be able to - // operate in off the record sessions if the model is available from the - // optimization guide. - ProfileKey* profile_key = ProfileKey::FromSimpleFactoryKey(key); - return profile_key->GetOriginalKey(); +content::BrowserContext* TranslateModelServiceFactory::GetBrowserContextToUse( + content::BrowserContext* context) const { + return chrome::GetBrowserContextOwnInstanceInIncognito(context); }
diff --git a/chrome/browser/translate/translate_model_service_factory.h b/chrome/browser/translate/translate_model_service_factory.h index b474b38..1695d21 100644 --- a/chrome/browser/translate/translate_model_service_factory.h +++ b/chrome/browser/translate/translate_model_service_factory.h
@@ -7,22 +7,25 @@ #include "base/macros.h" #include "base/no_destructor.h" -#include "components/keyed_service/core/simple_keyed_service_factory.h" +#include "components/keyed_service/content/browser_context_keyed_service_factory.h" #include "components/translate/content/browser/translate_model_service.h" -class SimpleFactoryKey; +namespace content { +class BrowserContext; +} // namespace content + +class Profile; // LazyInstance that owns all TranslateModelService(s) and associates // them with Profiles. -class TranslateModelServiceFactory : public SimpleKeyedServiceFactory { +class TranslateModelServiceFactory : public BrowserContextKeyedServiceFactory { public: // Gets the TranslateModelService for the profile. // // Returns null if the features that allow for this to provide useful // information are disabled. Importantly, only available when the // optimization guide service is. - static translate::TranslateModelService* GetOrBuildForKey( - SimpleFactoryKey* key); + static translate::TranslateModelService* GetForProfile(Profile* profile); // Gets the LazyInstance that owns all TranslateModelService(s). static TranslateModelServiceFactory* GetInstance(); @@ -33,10 +36,11 @@ TranslateModelServiceFactory(); ~TranslateModelServiceFactory() override; - // SimpleKeyedServiceFactory overrides: - std::unique_ptr<KeyedService> BuildServiceInstanceFor( - SimpleFactoryKey* key) const override; - SimpleFactoryKey* GetKeyToUse(SimpleFactoryKey* key) const override; + // BrowserContextKeyedServiceFactory: + KeyedService* BuildServiceInstanceFor( + content::BrowserContext* context) const override; + content::BrowserContext* GetBrowserContextToUse( + content::BrowserContext* context) const override; }; #endif // CHROME_BROWSER_TRANSLATE_TRANSLATE_MODEL_SERVICE_FACTORY_H_
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 23332db..64480ad 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -5205,6 +5205,8 @@ if (enable_side_search) { sources += [ + "side_search/side_search_config.cc", + "side_search/side_search_config.h", "side_search/side_search_metrics.cc", "side_search/side_search_metrics.h", "side_search/side_search_prefs.cc",
diff --git a/chrome/browser/ui/app_list/app_list_model_updater.h b/chrome/browser/ui/app_list/app_list_model_updater.h index 9044625..edfdeae3 100644 --- a/chrome/browser/ui/app_list/app_list_model_updater.h +++ b/chrome/browser/ui/app_list/app_list_model_updater.h
@@ -61,7 +61,8 @@ virtual void UpdateSearchBox(const std::u16string& text, bool initiated_by_user) {} virtual void PublishSearchResults( - const std::vector<ChromeSearchResult*>& results) {} + const std::vector<ChromeSearchResult*>& results, + const std::vector<ash::AppListSearchResultCategory>& categories) {} virtual std::vector<ChromeSearchResult*> GetPublishedSearchResultsForTest(); // Item field setters only used by ChromeAppListItem and its derived classes.
diff --git a/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc b/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc index c291ee8a..4d0c786 100644 --- a/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc +++ b/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc
@@ -137,7 +137,8 @@ } void ChromeAppListModelUpdater::PublishSearchResults( - const std::vector<ChromeSearchResult*>& results) { + const std::vector<ChromeSearchResult*>& results, + const std::vector<ash::AppListSearchResultCategory>& categories) { published_results_ = results; for (auto* const result : results) result->set_model_updater(this); @@ -146,7 +147,8 @@ std::vector<std::unique_ptr<ash::SearchResultMetadata>> result_data; for (auto* result : results) result_data.push_back(result->CloneMetadata()); - app_list_controller_->PublishSearchResults(std::move(result_data)); + app_list_controller_->PublishSearchResults(std::move(result_data), + categories); } std::vector<ChromeSearchResult*>
diff --git a/chrome/browser/ui/app_list/chrome_app_list_model_updater.h b/chrome/browser/ui/app_list/chrome_app_list_model_updater.h index 00df8dc6..4fbbc85 100644 --- a/chrome/browser/ui/app_list/chrome_app_list_model_updater.h +++ b/chrome/browser/ui/app_list/chrome_app_list_model_updater.h
@@ -41,7 +41,8 @@ void UpdateSearchBox(const std::u16string& text, bool initiated_by_user) override; void PublishSearchResults( - const std::vector<ChromeSearchResult*>& results) override; + const std::vector<ChromeSearchResult*>& results, + const std::vector<ash::AppListSearchResultCategory>& categories) override; std::vector<ChromeSearchResult*> GetPublishedSearchResultsForTest() override; // Methods only used by ChromeAppListItem that talk to ash directly.
diff --git a/chrome/browser/ui/app_list/search/app_list_search_browsertest.cc b/chrome/browser/ui/app_list/search/app_list_search_browsertest.cc index 5738db14..a8fc31b 100644 --- a/chrome/browser/ui/app_list/search/app_list_search_browsertest.cc +++ b/chrome/browser/ui/app_list/search/app_list_search_browsertest.cc
@@ -41,6 +41,7 @@ #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" #include "chrome/browser/ui/web_applications/web_app_launch_manager.h" #include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" +#include "chrome/browser/web_applications/test/web_app_install_test_utils.h" #include "chrome/browser/web_applications/test/with_crosapi_param.h" #include "chrome/browser/web_applications/web_app_id.h" #include "chrome/browser/web_applications/web_app_id_constants.h" @@ -81,6 +82,13 @@ AppListSearchBrowserTest(const AppListSearchBrowserTest&) = delete; AppListSearchBrowserTest& operator=(const AppListSearchBrowserTest&) = delete; + // InProcessBrowserTest: + void SetUpOnMainThread() override { + InProcessBrowserTest::SetUpOnMainThread(); + web_app::test::WaitUntilReady( + web_app::WebAppProvider::GetForTest(browser()->profile())); + } + //--------------- // Search helpers //---------------
diff --git a/chrome/browser/ui/app_list/search/common/types_util.cc b/chrome/browser/ui/app_list/search/common/types_util.cc index c0e6a8c..8eb323fd 100644 --- a/chrome/browser/ui/app_list/search/common/types_util.cc +++ b/chrome/browser/ui/app_list/search/common/types_util.cc
@@ -168,6 +168,8 @@ return "Card"; case ash::SearchResultDisplayType::kChip: return "Chip"; + case ash::SearchResultDisplayType::kContinue: + return "Continue"; } NOTREACHED(); }
diff --git a/chrome/browser/ui/app_list/search/files/zero_state_drive_provider.cc b/chrome/browser/ui/app_list/search/files/zero_state_drive_provider.cc index 27a94b3..dee9a71 100644 --- a/chrome/browser/ui/app_list/search/files/zero_state_drive_provider.cc +++ b/chrome/browser/ui/app_list/search/files/zero_state_drive_provider.cc
@@ -8,6 +8,7 @@ #include <memory> #include <utility> +#include "ash/constants/ash_features.h" #include "ash/constants/ash_pref_names.h" #include "ash/public/cpp/app_list/app_list_features.h" #include "ash/public/cpp/app_list/app_list_types.h" @@ -33,6 +34,8 @@ namespace { // Schemas of result IDs for the results list and suggestion chips. +// TODO(crbug.com/1258415): kChipSchema can be removed once the new launcher is +// launched. constexpr char kListSchema[] = "zero_state_drive://"; constexpr char kChipSchema[] = "drive_chip://"; @@ -77,6 +80,14 @@ return drive_service->GetMountPointPath().Append(path.value()); } +// TODO(crbug.com/1258415): This exists to reroute results depending on which +// launcher is enabled, and should be removed after the new launcher launch. +ash::SearchResultDisplayType GetDisplayType() { + return ash::features::IsProductivityLauncherEnabled() + ? ash::SearchResultDisplayType::kContinue + : ash::SearchResultDisplayType::kList; +} + } // namespace ZeroStateDriveProvider::ZeroStateDriveProvider( @@ -243,8 +254,8 @@ const float relevance) { return std::make_unique<FileResult>( kListSchema, ReparentToDriveMount(filepath, drive_service_), - ash::AppListSearchResultType::kZeroStateDrive, - ash::SearchResultDisplayType::kList, relevance, profile_); + ash::AppListSearchResultType::kZeroStateDrive, GetDisplayType(), + relevance, profile_); } std::unique_ptr<FileResult> ZeroStateDriveProvider::MakeChipResult(
diff --git a/chrome/browser/ui/app_list/search/files/zero_state_drive_provider.h b/chrome/browser/ui/app_list/search/files/zero_state_drive_provider.h index 9c1ca13..1a13f05 100644 --- a/chrome/browser/ui/app_list/search/files/zero_state_drive_provider.h +++ b/chrome/browser/ui/app_list/search/files/zero_state_drive_provider.h
@@ -52,6 +52,8 @@ std::unique_ptr<FileResult> MakeListResult(const base::FilePath& filepath, const float relevance); + // TODO(crbug.com/1258415): Chip results don't exist in the new launcher. + // MakeChipResult can be removed after launch. std::unique_ptr<FileResult> MakeChipResult(const base::FilePath& filepath, const float relevance);
diff --git a/chrome/browser/ui/app_list/search/files/zero_state_file_provider.cc b/chrome/browser/ui/app_list/search/files/zero_state_file_provider.cc index 314b337..20ed3761 100644 --- a/chrome/browser/ui/app_list/search/files/zero_state_file_provider.cc +++ b/chrome/browser/ui/app_list/search/files/zero_state_file_provider.cc
@@ -6,6 +6,7 @@ #include <string> +#include "ash/constants/ash_features.h" #include "ash/constants/ash_pref_names.h" #include "ash/public/cpp/app_list/app_list_features.h" #include "base/bind.h" @@ -30,6 +31,8 @@ namespace app_list { namespace { +// TODO(crbug.com/1258415): kFileChipSchema can be removed once the new +// launcher is launched. constexpr char kFileChipSchema[] = "file_chip://"; constexpr char kZeroStateFileSchema[] = "zero_state_file://"; @@ -60,6 +63,14 @@ chromeos::prefs::kSuggestedContentEnabled); } +// TODO(crbug.com/1258415): This exists to reroute results depending on which +// launcher is enabled, and should be removed after the new launcher launch. +ash::SearchResultDisplayType GetDisplayType() { + return ash::features::IsProductivityLauncherEnabled() + ? ash::SearchResultDisplayType::kContinue + : ash::SearchResultDisplayType::kList; +} + } // namespace ZeroStateFileProvider::ZeroStateFileProvider(Profile* profile) @@ -119,12 +130,14 @@ for (const auto& filepath_score : results.first) { auto result = std::make_unique<FileResult>( kZeroStateFileSchema, filepath_score.first, - ash::AppListSearchResultType::kZeroStateFile, - ash::SearchResultDisplayType::kList, filepath_score.second, profile_); + ash::AppListSearchResultType::kZeroStateFile, GetDisplayType(), + filepath_score.second, profile_); result->RequestThumbnail(&thumbnail_loader_); new_results.push_back(std::move(result)); // Add suggestion chip file results + // TODO(crbug.com/1258415): This can be removed once the new launcher is + // launched. if (app_list_features::IsSuggestedLocalFilesEnabled() && IsSuggestedContentEnabled(profile_)) { new_results.emplace_back(
diff --git a/chrome/browser/ui/app_list/search/mixer.cc b/chrome/browser/ui/app_list/search/mixer.cc index 7522e81..0bdf8ae 100644 --- a/chrome/browser/ui/app_list/search/mixer.cc +++ b/chrome/browser/ui/app_list/search/mixer.cc
@@ -191,7 +191,8 @@ new_results.push_back(sort_data.result); } search_controller_->NotifyResultsAdded(new_results); - model_updater_->PublishSearchResults(new_results); + // Categories are unused in old search. + model_updater_->PublishSearchResults(new_results, /*categories=*/{}); } void Mixer::FetchResults(const std::u16string& query) {
diff --git a/chrome/browser/ui/app_list/search/search_controller_impl_new.cc b/chrome/browser/ui/app_list/search/search_controller_impl_new.cc index 1260ab4..a5f670f1 100644 --- a/chrome/browser/ui/app_list/search/search_controller_impl_new.cc +++ b/chrome/browser/ui/app_list/search/search_controller_impl_new.cc
@@ -202,7 +202,8 @@ observer.OnResultsAdded(last_query_, observer_results); } - model_updater_->PublishSearchResults(all_results); + // TODO(crbug.com/1199206): Send category ranks. + model_updater_->PublishSearchResults(all_results, /*categories=*/{}); } ChromeSearchResult* SearchControllerImplNew::FindSearchResult(
diff --git a/chrome/browser/ui/app_list/test/fake_app_list_model_updater.cc b/chrome/browser/ui/app_list/test/fake_app_list_model_updater.cc index 9ef9239..4b45e7a 100644 --- a/chrome/browser/ui/app_list/test/fake_app_list_model_updater.cc +++ b/chrome/browser/ui/app_list/test/fake_app_list_model_updater.cc
@@ -169,7 +169,8 @@ } void FakeAppListModelUpdater::PublishSearchResults( - const std::vector<ChromeSearchResult*>& results) { + const std::vector<ChromeSearchResult*>& results, + const std::vector<ash::AppListSearchResultCategory>& categories) { search_results_ = results; }
diff --git a/chrome/browser/ui/app_list/test/fake_app_list_model_updater.h b/chrome/browser/ui/app_list/test/fake_app_list_model_updater.h index 7ff5e55..fe6d1df 100644 --- a/chrome/browser/ui/app_list/test/fake_app_list_model_updater.h +++ b/chrome/browser/ui/app_list/test/fake_app_list_model_updater.h
@@ -47,7 +47,8 @@ // For SearchModel: void SetSearchEngineIsGoogle(bool is_google) override; void PublishSearchResults( - const std::vector<ChromeSearchResult*>& results) override; + const std::vector<ChromeSearchResult*>& results, + const std::vector<ash::AppListSearchResultCategory>& categories) override; void ActivateChromeItem(const std::string& id, int event_flags) override; void LoadAppIcon(const std::string& id) override;
diff --git a/chrome/browser/ui/ash/shelf/chrome_shelf_controller_browsertest.cc b/chrome/browser/ui/ash/shelf/chrome_shelf_controller_browsertest.cc index 8659ce4..68a8329 100644 --- a/chrome/browser/ui/ash/shelf/chrome_shelf_controller_browsertest.cc +++ b/chrome/browser/ui/ash/shelf/chrome_shelf_controller_browsertest.cc
@@ -459,6 +459,8 @@ os_hooks_suppress_ = web_app::OsIntegrationManager::ScopedSuppressOsHooksForTesting(); + web_app::test::WaitUntilReady( + web_app::WebAppProvider::GetForTest(browser()->profile())); } private: @@ -1244,7 +1246,8 @@ // Verifies that native browser window properties are properly set when showing // a PWA tab. -IN_PROC_BROWSER_TEST_F(ShelfWebAppBrowserTest, AppIDForPWA) { +// DISABLED due to flakiness (http://crbug.com/1258995). +IN_PROC_BROWSER_TEST_F(ShelfWebAppBrowserTest, DISABLED_AppIDForPWA) { // Start server and open test page. ASSERT_TRUE(embedded_test_server()->Start()); ASSERT_TRUE(ui_test_utils::NavigateToURL(
diff --git a/chrome/browser/ui/autofill/payments/offer_notification_bubble_controller_impl.cc b/chrome/browser/ui/autofill/payments/offer_notification_bubble_controller_impl.cc index 753ed18..12756eb 100644 --- a/chrome/browser/ui/autofill/payments/offer_notification_bubble_controller_impl.cc +++ b/chrome/browser/ui/autofill/payments/offer_notification_bubble_controller_impl.cc
@@ -167,22 +167,12 @@ Show(); } -void OfferNotificationBubbleControllerImpl::DidFinishNavigation( - content::NavigationHandle* navigation_handle) { - // TODO(https://crbug.com/1218946): With MPArch there may be multiple main - // frames. This caller was converted automatically to the primary main frame - // to preserve its semantics. Follow up to confirm correctness. - if (!navigation_handle->IsInPrimaryMainFrame() || - !navigation_handle->HasCommitted()) - return; - - // Don't react to same-document (fragment) navigations. - if (navigation_handle->IsSameDocument()) - return; - +void OfferNotificationBubbleControllerImpl::PrimaryPageChanged( + content::Page& page) { // Don't do anything if user is still on an eligible origin for this offer. - if (base::ranges::count(origins_to_display_bubble_, - navigation_handle->GetURL().GetOrigin())) { + if (base::ranges::count( + origins_to_display_bubble_, + page.GetMainDocument().GetLastCommittedURL().GetOrigin())) { return; }
diff --git a/chrome/browser/ui/autofill/payments/offer_notification_bubble_controller_impl.h b/chrome/browser/ui/autofill/payments/offer_notification_bubble_controller_impl.h index d02132c..81ab0ae6 100644 --- a/chrome/browser/ui/autofill/payments/offer_notification_bubble_controller_impl.h +++ b/chrome/browser/ui/autofill/payments/offer_notification_bubble_controller_impl.h
@@ -63,8 +63,7 @@ content::WebContents* web_contents); // AutofillBubbleControllerBase: - void DidFinishNavigation( - content::NavigationHandle* navigation_handle) override; + void PrimaryPageChanged(content::Page& page) override; PageActionIconType GetPageActionIconType() override; void DoShowBubble() override;
diff --git a/chrome/browser/ui/autofill/payments/offer_notification_bubble_controller_impl_unittest.cc b/chrome/browser/ui/autofill/payments/offer_notification_bubble_controller_impl_unittest.cc index 596e4a65..676ff95 100644 --- a/chrome/browser/ui/autofill/payments/offer_notification_bubble_controller_impl_unittest.cc +++ b/chrome/browser/ui/autofill/payments/offer_notification_bubble_controller_impl_unittest.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/ui/autofill/payments/offer_notification_bubble_controller_impl.h" +#include "base/test/scoped_feature_list.h" #include "chrome/browser/ui/autofill/autofill_bubble_base.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" @@ -11,8 +12,11 @@ #include "components/autofill/core/browser/autofill_test_utils.h" #include "components/autofill/core/browser/data_model/autofill_offer_data.h" #include "content/public/test/mock_navigation_handle.h" +#include "content/public/test/navigation_simulator.h" +#include "content/public/test/web_contents_tester.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/features.h" namespace autofill { @@ -32,13 +36,6 @@ content::WebContents* web_contents) : OfferNotificationBubbleControllerImpl(web_contents) {} - void SimulateNavigation(std::string url) { - content::RenderFrameHost* rfh = web_contents()->GetMainFrame(); - content::MockNavigationHandle navigation_handle(GURL(url), rfh); - navigation_handle.set_has_committed(true); - DidFinishNavigation(&navigation_handle); - } - private: // Overrides to bypass the IsWebContentsActive check. void DoShowBubble() override { @@ -65,10 +62,16 @@ void SetUp() override { BrowserWithTestWindowTest::SetUp(); - AddTab(browser(), GURL("about:blank")); - content::WebContents* web_contents = - browser()->tab_strip_model()->GetActiveWebContents(); - TestOfferNotificationBubbleControllerImpl::CreateForTesting(web_contents); + AddTab(GURL("about:blank")); + TestOfferNotificationBubbleControllerImpl::CreateForTesting(web_contents()); + } + + content::WebContents* web_contents() { + return browser()->tab_strip_model()->GetActiveWebContents(); + } + + virtual void AddTab(const GURL& url) { + BrowserWithTestWindowTest::AddTab(browser(), url); } protected: @@ -98,7 +101,7 @@ TestOfferNotificationBubbleControllerImpl* controller() { return static_cast<TestOfferNotificationBubbleControllerImpl*>( TestOfferNotificationBubbleControllerImpl::FromWebContents( - browser()->tab_strip_model()->GetActiveWebContents())); + web_contents())); } private: @@ -152,4 +155,65 @@ EXPECT_EQ(&offer, controller()->GetOffer()); } +class OfferNotificationBubbleControllerImplPrerenderTest + : public OfferNotificationBubbleControllerImplTest { + public: + OfferNotificationBubbleControllerImplPrerenderTest() { + scoped_feature_list_.InitWithFeatures( + {blink::features::kPrerender2}, + // This feature is to run test on any bot. + {blink::features::kPrerender2MemoryControls}); + } + + // BrowserWithTestWindowTest::AddTab creates a real WebContentsImpl object, + // but we need a TestWebContents object to unit test prerendering, so we + // override AddTab to create a TestWebContents instead. + void AddTab(const GURL& url) override { + std::unique_ptr<content::WebContents> contents( + content::WebContentsTester::CreateTestWebContents(profile(), nullptr)); + content::WebContents* raw_contents = contents.get(); + browser()->tab_strip_model()->AppendWebContents(std::move(contents), true); + EXPECT_EQ(web_contents(), raw_contents); + content::WebContentsTester::For(raw_contents)->NavigateAndCommit(url); + } + + private: + base::test::ScopedFeatureList scoped_feature_list_; +}; + +TEST_F(OfferNotificationBubbleControllerImplPrerenderTest, + DoNotHideBubbleForPrerender) { + const GURL& original_url = GURL("https://www.example.com/first/"); + NavigateAndCommitActiveTab(original_url); + + // Ensure a bubble is visible on the primary page. + AutofillOfferData offer = + CreateTestOfferWithOrigins({original_url.GetOrigin()}); + ShowBubble(&offer); + EXPECT_TRUE(controller()->GetOfferNotificationBubbleView()); + + // Start a prerender and navigate the test page. + const GURL& prerender_url = GURL("https://www.example.com/second/"); + content::RenderFrameHost* prerender_frame = + content::WebContentsTester::For(web_contents()) + ->AddPrerenderAndCommitNavigation(prerender_url); + ASSERT_EQ(prerender_frame->GetLifecycleState(), + content::RenderFrameHost::LifecycleState::kPrerendering); + + // Ensure a bubble is still visible on the primary page. + EXPECT_TRUE(controller()->GetOfferNotificationBubbleView()); + + // Activate the prerendered page. + content::NavigationSimulator::CreateRendererInitiated( + prerender_url, web_contents()->GetMainFrame()) + ->Commit(); + + // Ensure a bubble is still visible on the activated page since it has the + // same-origin as the original url. Cross-origin prerendering is unsupported + // right now, so this navigation will always be same-origin. + // TODO(crbug.com/1176054): Add a cross-origin test when prerendering + // eventually support it. + EXPECT_TRUE(controller()->GetOfferNotificationBubbleView()); +} + } // namespace autofill
diff --git a/chrome/browser/ui/profile_picker.h b/chrome/browser/ui/profile_picker.h index e3dfb0c..2019a45b 100644 --- a/chrome/browser/ui/profile_picker.h +++ b/chrome/browser/ui/profile_picker.h
@@ -127,9 +127,6 @@ // Returns the web view (embedded in the picker) for testing. static views::WebView* GetWebViewForTesting(); - // Returns the simple toolbar (embedded in the picker) for testing. - static views::View* GetToolbarForTesting(); - // Add a callback that will be called the next time the picker is opened. static void AddOnProfilePickerOpenedCallbackForTesting( base::OnceClosure callback);
diff --git a/chrome/browser/ui/side_search/side_search_config.cc b/chrome/browser/ui/side_search/side_search_config.cc new file mode 100644 index 0000000..9a5ba7be --- /dev/null +++ b/chrome/browser/ui/side_search/side_search_config.cc
@@ -0,0 +1,64 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/side_search/side_search_config.h" + +#include "chrome/common/webui_url_constants.h" +#include "components/google/core/common/google_util.h" +#include "content/public/browser/browser_context.h" +#include "url/gurl.h" + +namespace { + +constexpr char kSideSearchConfigKey[] = "side_search_config_key"; + +// Default condition test for CanShowSidePanelForURL() for the Google DSE. +// TODO(tluk): This should be defined elsewhere as we move to support generic +// DSEs. +bool GoogleSRPShouldNavigateInSidePanel(const GURL& url) { + return !google_util::IsGoogleSearchUrl(url) && + !google_util::IsGoogleHomePageUrl(url) && + url.spec() != chrome::kChromeUINewTabURL; +} + +} // namespace + +SideSearchConfig::SideSearchConfig() + : should_navigate_in_side_panel_callback_( + base::BindRepeating(google_util::IsGoogleSearchUrl)), + can_show_side_panel_for_url_callback_(base::BindRepeating( + base::BindRepeating(GoogleSRPShouldNavigateInSidePanel))) {} + +SideSearchConfig::~SideSearchConfig() = default; + +// static +SideSearchConfig* SideSearchConfig::Get(content::BrowserContext* context) { + SideSearchConfig* data = static_cast<SideSearchConfig*>( + context->GetUserData(kSideSearchConfigKey)); + if (!data) { + auto new_data = std::make_unique<SideSearchConfig>(); + data = new_data.get(); + context->SetUserData(kSideSearchConfigKey, std::move(new_data)); + } + return data; +} + +bool SideSearchConfig::ShouldNavigateInSidePanel(const GURL& url) { + return should_navigate_in_side_panel_callback_.Run(url); +} + +void SideSearchConfig::SetShouldNavigateInSidePanelCalback( + URLTestConditionCallback callback) { + should_navigate_in_side_panel_callback_ = std::move(callback); +} + +bool SideSearchConfig::CanShowSidePanelForURL(const GURL& url) { + return is_side_panel_srp_available_ && + can_show_side_panel_for_url_callback_.Run(url); +} + +void SideSearchConfig::SetCanShowSidePanelForURLCallback( + URLTestConditionCallback callback) { + can_show_side_panel_for_url_callback_ = std::move(callback); +}
diff --git a/chrome/browser/ui/side_search/side_search_config.h b/chrome/browser/ui/side_search/side_search_config.h new file mode 100644 index 0000000..4bd57d7 --- /dev/null +++ b/chrome/browser/ui/side_search/side_search_config.h
@@ -0,0 +1,57 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_SIDE_SEARCH_SIDE_SEARCH_CONFIG_H_ +#define CHROME_BROWSER_UI_SIDE_SEARCH_SIDE_SEARCH_CONFIG_H_ + +#include "base/callback.h" +#include "base/supports_user_data.h" + +namespace content { +class BrowserContext; +} // namespace content + +class GURL; + +// Stores per-profile configuration data for side search. +class SideSearchConfig : public base::SupportsUserData::Data { + public: + using URLTestConditionCallback = base::RepeatingCallback<bool(const GURL&)>; + + SideSearchConfig(); + SideSearchConfig(const SideSearchConfig&) = delete; + SideSearchConfig& operator=(const SideSearchConfig&) = delete; + ~SideSearchConfig() override; + + // Gets the instance of the config for `context`. + static SideSearchConfig* Get(content::BrowserContext* context); + + // Returns whether a `url` in the side panel should be allowed to commit in + // the side panel or if it should be redirected to the content frame. + bool ShouldNavigateInSidePanel(const GURL& url); + void SetShouldNavigateInSidePanelCalback(URLTestConditionCallback callback); + + // Returns whether the side panel can be shown for the `url`. This is used to + // avoid having the side panel on pages on which it doesn't make sense to have + // it appear (e.g. NTP). + bool CanShowSidePanelForURL(const GURL& url); + void SetCanShowSidePanelForURLCallback(URLTestConditionCallback callback); + + // Gets and sets the bit that determines whether or not the SRP is available. + // TODO(tluk): Move the code that tests for availability into this class. + bool is_side_panel_srp_available() { return is_side_panel_srp_available_; } + void set_is_side_panel_srp_available(bool is_side_panel_srp_available) { + is_side_panel_srp_available_ = is_side_panel_srp_available; + } + + private: + // Whether or not the service providing the SRP for the side panel is + // available or not. + bool is_side_panel_srp_available_ = false; + + URLTestConditionCallback should_navigate_in_side_panel_callback_; + URLTestConditionCallback can_show_side_panel_for_url_callback_; +}; + +#endif // CHROME_BROWSER_UI_SIDE_SEARCH_SIDE_SEARCH_CONFIG_H_
diff --git a/chrome/browser/ui/side_search/side_search_side_contents_helper.cc b/chrome/browser/ui/side_search/side_search_side_contents_helper.cc index 9ab00f0..e3271b3 100644 --- a/chrome/browser/ui/side_search/side_search_side_contents_helper.cc +++ b/chrome/browser/ui/side_search/side_search_side_contents_helper.cc
@@ -4,12 +4,13 @@ #include "chrome/browser/ui/side_search/side_search_side_contents_helper.h" +#include "chrome/browser/ui/side_search/side_search_config.h" #include "chrome/browser/ui/side_search/side_search_metrics.h" #include "chrome/browser/ui/side_search/side_search_tab_contents_helper.h" -#include "components/google/core/common/google_util.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/navigation_throttle.h" #include "content/public/browser/page_navigator.h" +#include "content/public/browser/web_contents.h" #include "net/base/url_util.h" #include "third_party/blink/public/common/user_agent/user_agent_metadata.h" #include "url/gurl.h" @@ -47,7 +48,10 @@ const auto& url = navigation_handle()->GetURL(); // Allow Google search navigations to proceed in the side panel. - if (google_util::IsGoogleSearchUrl(url)) { + auto* config = SideSearchConfig::Get( + navigation_handle()->GetWebContents()->GetBrowserContext()); + DCHECK(config); + if (config->ShouldNavigateInSidePanel(url)) { return NavigationThrottle::PROCEED; } @@ -106,7 +110,7 @@ } const auto& url = navigation_handle->GetURL(); - DCHECK(google_util::IsGoogleSearchUrl(url)); + DCHECK(GetConfig()->ShouldNavigateInSidePanel(url)); DCHECK(delegate_); delegate_->LastSearchURLUpdated(url); @@ -151,7 +155,7 @@ } void SideSearchSideContentsHelper::LoadURL(const GURL& url) { - DCHECK(google_util::IsGoogleSearchUrl(url)); + DCHECK(GetConfig()->ShouldNavigateInSidePanel(url)); // Do not reload the side contents if already navigated to `url`. if (web_contents()->GetLastCommittedURL() == url) @@ -210,4 +214,8 @@ redirection_to_tab_count_ = 0; } +SideSearchConfig* SideSearchSideContentsHelper::GetConfig() { + return SideSearchConfig::Get(web_contents()->GetBrowserContext()); +} + WEB_CONTENTS_USER_DATA_KEY_IMPL(SideSearchSideContentsHelper);
diff --git a/chrome/browser/ui/side_search/side_search_side_contents_helper.h b/chrome/browser/ui/side_search/side_search_side_contents_helper.h index cea37f9..366ef407 100644 --- a/chrome/browser/ui/side_search/side_search_side_contents_helper.h +++ b/chrome/browser/ui/side_search/side_search_side_contents_helper.h
@@ -17,6 +17,7 @@ } // namespace content class GURL; +class SideSearchConfig; // Side Search helper for the WebContents hosted in the side panel. class SideSearchSideContentsHelper @@ -91,6 +92,8 @@ // Emits metrics data for the previous user journey if present. void MaybeRecordMetricsPerJourney(); + SideSearchConfig* GetConfig(); + // `delegate_` will outlive the SideContentsWrapper. Delegate* delegate_ = nullptr;
diff --git a/chrome/browser/ui/side_search/side_search_tab_contents_helper.cc b/chrome/browser/ui/side_search/side_search_tab_contents_helper.cc index c715422..449dd9f 100644 --- a/chrome/browser/ui/side_search/side_search_tab_contents_helper.cc +++ b/chrome/browser/ui/side_search/side_search_tab_contents_helper.cc
@@ -6,24 +6,16 @@ #include "chrome/browser/task_manager/web_contents_tags.h" #include "chrome/browser/ui/prefs/prefs_tab_helper.h" -#include "chrome/common/webui_url_constants.h" -#include "components/google/core/common/google_util.h" +#include "chrome/browser/ui/side_search/side_search_config.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/navigation_controller.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/storage_partition.h" +#include "content/public/browser/web_contents.h" #include "net/http/http_request_headers.h" #include "services/network/public/cpp/resource_request.h" #include "services/network/public/cpp/simple_url_loader.h" -namespace { - -// A flag to track whether the last call to `TestSRPAvailability()` returned -// successfully. Currently only called once per browser session. -bool g_is_side_panel_srp_available = false; - -} // namespace - SideSearchTabContentsHelper::~SideSearchTabContentsHelper() = default; void SideSearchTabContentsHelper::NavigateInTabContents( @@ -33,7 +25,7 @@ } void SideSearchTabContentsHelper::LastSearchURLUpdated(const GURL& url) { - DCHECK(google_util::IsGoogleSearchUrl(url)); + DCHECK(GetConfig()->ShouldNavigateInSidePanel(url)); last_search_url_ = url; } @@ -58,8 +50,9 @@ } const auto& url = navigation_handle->GetURL(); + auto* config = GetConfig(); - if (google_util::IsGoogleSearchUrl(url)) { + if (config->ShouldNavigateInSidePanel(url)) { returned_to_previous_srp_ = navigation_handle->GetPageTransition() & ui::PAGE_TRANSITION_FORWARD_BACK; @@ -67,7 +60,7 @@ // navigation completes. last_search_url_ = url; - if (!g_is_side_panel_srp_available) + if (!config->is_side_panel_srp_available()) TestSRPAvailability(); if (side_panel_contents_) @@ -102,10 +95,7 @@ bool SideSearchTabContentsHelper::CanShowSidePanelForCommittedNavigation() { const GURL& url = web_contents()->GetLastCommittedURL(); - return last_search_url_ && g_is_side_panel_srp_available && - !google_util::IsGoogleSearchUrl(url) && - !google_util::IsGoogleHomePageUrl(url) && - url.spec() != chrome::kChromeUINewTabURL; + return last_search_url_ && GetConfig()->CanShowSidePanelForURL(url); } void SideSearchTabContentsHelper::SetDelegate( @@ -121,11 +111,6 @@ GetSideContentsHelper()->SetDelegate(this); } -void SideSearchTabContentsHelper::SetIsSidePanelSRPAvailableForTesting( - bool is_side_panel_srp_available) { - g_is_side_panel_srp_available = is_side_panel_srp_available; -} - SideSearchTabContentsHelper::SideSearchTabContentsHelper( content::WebContents* web_contents) : content::WebContentsObserver(web_contents) {} @@ -154,17 +139,17 @@ DCHECK(side_panel_contents_); // Only update the side panel contents with the latest `last_search_url_` if // present - if (last_search_url_ && g_is_side_panel_srp_available) + if (last_search_url_ && GetConfig()->is_side_panel_srp_available()) GetSideContentsHelper()->LoadURL(last_search_url_.value()); } void SideSearchTabContentsHelper::TestSRPAvailability() { - if (g_is_side_panel_srp_available) + if (GetConfig()->is_side_panel_srp_available()) return; // TODO(tluk): Add rate limiting to the SRP test to permanently disable the // feature for a given session if the availability check fails enough times. DCHECK(last_search_url_.has_value()); - DCHECK(google_util::IsGoogleSearchUrl(last_search_url_.value())); + DCHECK(GetConfig()->ShouldNavigateInSidePanel(last_search_url_.value())); auto traffic_annotation = net::DefineNetworkTrafficAnnotation("side_search_availability_test", R"( semantics { @@ -208,7 +193,8 @@ void SideSearchTabContentsHelper::OnResponseLoaded( scoped_refptr<net::HttpResponseHeaders> headers) { - g_is_side_panel_srp_available = simple_loader_->NetError() == net::OK; + GetConfig()->set_is_side_panel_srp_available(simple_loader_->NetError() == + net::OK); // The test for availability is performed async so alert `delegate_` that the // side panel SRP is available to give it the opportunity to update @@ -217,4 +203,8 @@ delegate_->SidePanelAvailabilityChanged(false); } +SideSearchConfig* SideSearchTabContentsHelper::GetConfig() { + return SideSearchConfig::Get(web_contents()->GetBrowserContext()); +} + WEB_CONTENTS_USER_DATA_KEY_IMPL(SideSearchTabContentsHelper);
diff --git a/chrome/browser/ui/side_search/side_search_tab_contents_helper.h b/chrome/browser/ui/side_search/side_search_tab_contents_helper.h index 97bfb32..0246591 100644 --- a/chrome/browser/ui/side_search/side_search_tab_contents_helper.h +++ b/chrome/browser/ui/side_search/side_search_tab_contents_helper.h
@@ -20,6 +20,7 @@ } // namespace network class GURL; +class SideSearchConfig; // Side Search helper for the WebContents hosted in the browser's main tab area. class SideSearchTabContentsHelper @@ -86,8 +87,6 @@ void SetSidePanelContentsForTesting( std::unique_ptr<content::WebContents> side_panel_contents); - void SetIsSidePanelSRPAvailableForTesting(bool is_side_panel_srp_available); - content::WebContents* side_panel_contents_for_testing() const { return side_panel_contents_.get(); } @@ -116,6 +115,8 @@ void TestSRPAvailability(); void OnResponseLoaded(scoped_refptr<net::HttpResponseHeaders> headers); + SideSearchConfig* GetConfig(); + // Use a weak ptr for the delegate to avoid issues whereby the tab contents // could outlive the delegate. base::WeakPtr<Delegate> delegate_;
diff --git a/chrome/browser/ui/side_search/side_search_tab_contents_helper_unittest.cc b/chrome/browser/ui/side_search/side_search_tab_contents_helper_unittest.cc index 718b4ac8..4433e06b 100644 --- a/chrome/browser/ui/side_search/side_search_tab_contents_helper_unittest.cc +++ b/chrome/browser/ui/side_search/side_search_tab_contents_helper_unittest.cc
@@ -7,6 +7,7 @@ #include <memory> #include "base/test/scoped_feature_list.h" +#include "chrome/browser/ui/side_search/side_search_config.h" #include "chrome/browser/ui/ui_features.h" #include "chrome/test/base/testing_profile.h" #include "content/public/browser/browser_context.h" @@ -51,7 +52,7 @@ SideSearchTabContentsHelper::CreateForWebContents(web_contents_.get()); helper()->SetSidePanelContentsForTesting( content::WebContentsTester::CreateTestWebContents(&profile_, nullptr)); - helper()->SetIsSidePanelSRPAvailableForTesting(true); + SideSearchConfig::Get(&profile_)->set_is_side_panel_srp_available(true); Test::SetUp(); }
diff --git a/chrome/browser/ui/views/apps/app_info_dialog/app_info_panel.cc b/chrome/browser/ui/views/apps/app_info_dialog/app_info_panel.cc index 3db8354..d35c2c0 100644 --- a/chrome/browser/ui/views/apps/app_info_dialog/app_info_panel.cc +++ b/chrome/browser/ui/views/apps/app_info_dialog/app_info_panel.cc
@@ -8,6 +8,7 @@ #include "chrome/browser/ui/browser_navigator_params.h" #include "chrome/browser/ui/views/apps/app_info_dialog/app_info_label.h" #include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "extensions/common/extension.h" #include "ui/base/metadata/metadata_impl_macros.h" #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/geometry/insets.h" @@ -24,6 +25,8 @@ AppInfoPanel::AppInfoPanel(Profile* profile, const extensions::Extension* app) : profile_(profile), app_(app) { + // Bookmark Apps have been replaced by Web Apps. + DCHECK(!app_->from_bookmark()); } AppInfoPanel::~AppInfoPanel() {
diff --git a/chrome/browser/ui/views/apps/app_info_dialog/app_info_panel.h b/chrome/browser/ui/views/apps/app_info_dialog/app_info_panel.h index 2a12ad74..1a9c47b 100644 --- a/chrome/browser/ui/views/apps/app_info_dialog/app_info_panel.h +++ b/chrome/browser/ui/views/apps/app_info_dialog/app_info_panel.h
@@ -59,8 +59,8 @@ std::unique_ptr<views::View> key, std::unique_ptr<views::View> value) const; - Profile* profile_; - const extensions::Extension* app_; + Profile* const profile_; + const extensions::Extension* const app_; }; BEGIN_VIEW_BUILDER(/* no export */, AppInfoPanel, views::View)
diff --git a/chrome/browser/ui/views/apps/app_info_dialog/app_info_summary_panel.cc b/chrome/browser/ui/views/apps/app_info_dialog/app_info_summary_panel.cc index 43d1596..319e8f24 100644 --- a/chrome/browser/ui/views/apps/app_info_dialog/app_info_summary_panel.cc +++ b/chrome/browser/ui/views/apps/app_info_dialog/app_info_summary_panel.cc
@@ -175,17 +175,14 @@ details_list->AddChildView( CreateKeyValueField(std::move(size_title), std::move(size_value))); - // The version doesn't make sense for bookmark apps. - if (!app_->from_bookmark()) { - auto version_title = std::make_unique<AppInfoLabel>( - l10n_util::GetStringUTF16(IDS_APPLICATION_INFO_VERSION_LABEL)); + auto version_title = std::make_unique<AppInfoLabel>( + l10n_util::GetStringUTF16(IDS_APPLICATION_INFO_VERSION_LABEL)); - auto version_value = std::make_unique<AppInfoLabel>( - base::UTF8ToUTF16(app_->GetVersionForDisplay())); + auto version_value = std::make_unique<AppInfoLabel>( + base::UTF8ToUTF16(app_->GetVersionForDisplay())); - details_list->AddChildView(CreateKeyValueField(std::move(version_title), - std::move(version_value))); - } + details_list->AddChildView( + CreateKeyValueField(std::move(version_title), std::move(version_value))); vertical_stack->AddChildView(std::move(details_list)); }
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc index 2731df1..e003075 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc
@@ -184,7 +184,7 @@ .SetTitle(l10n_util::GetStringUTF16( already_bookmarked ? IDS_BOOKMARK_BUBBLE_PAGE_BOOKMARK : IDS_BOOKMARK_BUBBLE_PAGE_BOOKMARKED)) - .SetWindowClosingCallback( + .SetDialogDestroyingCallback( base::BindOnce(&BookmarkBubbleDelegate::OnWindowClosing, base::Unretained(bubble_delegate))) .AddOkButton(base::BindOnce(&BookmarkBubbleDelegate::ApplyEdits,
diff --git a/chrome/browser/ui/views/direct_sockets_connection_bubble_dialog.cc b/chrome/browser/ui/views/direct_sockets_connection_bubble_dialog.cc index 9a08f67..3fc1b40 100644 --- a/chrome/browser/ui/views/direct_sockets_connection_bubble_dialog.cc +++ b/chrome/browser/ui/views/direct_sockets_connection_bubble_dialog.cc
@@ -71,7 +71,7 @@ ui::DialogModel::Builder(std::move(bubble_delegate_unique)) .SetTitle(l10n_util::GetStringUTF16( IDS_DIRECT_SOCKETS_CONNECTION_BUBBLE_TITLE_LABEL)) - .SetWindowClosingCallback( + .SetDialogDestroyingCallback( base::BindOnce(&DirectSocketsConnectionBubbleDelegate::OnClose, base::Unretained(bubble_delegate))) .AddOkButton(
diff --git a/chrome/browser/ui/views/extensions/extension_uninstall_dialog_view.cc b/chrome/browser/ui/views/extensions/extension_uninstall_dialog_view.cc index 28ac557..9c25f33d 100644 --- a/chrome/browser/ui/views/extensions/extension_uninstall_dialog_view.cc +++ b/chrome/browser/ui/views/extensions/extension_uninstall_dialog_view.cc
@@ -93,7 +93,7 @@ l10n_util::GetStringFUTF16(IDS_EXTENSION_PROMPT_UNINSTALL_TITLE, base::UTF8ToUTF16(extension()->name()))) .OverrideShowCloseButton(false) - .SetWindowClosingCallback( + .SetDialogDestroyingCallback( base::BindOnce(&ExtensionUninstallDialogViews::DialogClosing, weak_ptr_factory_.GetWeakPtr())) .SetIcon(ui::ImageModel::FromImageSkia(
diff --git a/chrome/browser/ui/views/outdated_upgrade_bubble_view.cc b/chrome/browser/ui/views/outdated_upgrade_bubble_view.cc index 3dc38bb..0ee087ce 100644 --- a/chrome/browser/ui/views/outdated_upgrade_bubble_view.cc +++ b/chrome/browser/ui/views/outdated_upgrade_bubble_view.cc
@@ -137,8 +137,8 @@ : IDS_REENABLE_UPDATES)) .AddBodyText( ui::DialogModelLabel(IDS_UPGRADE_BUBBLE_TEXT).set_is_secondary()) - .SetWindowClosingCallback(base::BindOnce(&OnWindowClosing)) - .SetCloseCallback(base::BindOnce( + .SetDialogDestroyingCallback(base::BindOnce(&OnWindowClosing)) + .SetCloseActionCallback(base::BindOnce( &base::RecordAction, base::UserMetricsAction("OutdatedUpgradeBubble.Later"))) .Build();
diff --git a/chrome/browser/ui/views/page_action/pwa_install_view_browsertest.cc b/chrome/browser/ui/views/page_action/pwa_install_view_browsertest.cc index d94e202..b8638ec 100644 --- a/chrome/browser/ui/views/page_action/pwa_install_view_browsertest.cc +++ b/chrome/browser/ui/views/page_action/pwa_install_view_browsertest.cc
@@ -23,6 +23,7 @@ #include "chrome/browser/ui/web_applications/web_app_dialog_utils.h" #include "chrome/browser/web_applications/install_bounce_metric.h" #include "chrome/browser/web_applications/os_integration_manager.h" +#include "chrome/browser/web_applications/test/web_app_install_test_utils.h" #include "chrome/browser/web_applications/web_app_helpers.h" #include "chrome/browser/web_applications/web_app_install_finalizer.h" #include "chrome/browser/web_applications/web_app_prefs_utils.h" @@ -166,6 +167,8 @@ web_contents_ = GetCurrentTab(); app_banner_manager_ = webapps::TestAppBannerManagerDesktop::FromWebContents(web_contents_); + web_app::test::WaitUntilReady( + web_app::WebAppProvider::GetForTest(browser()->profile())); } std::unique_ptr<net::test_server::HttpResponse> RequestInterceptor(
diff --git a/chrome/browser/ui/views/profiles/profile_picker_interactive_uitest.cc b/chrome/browser/ui/views/profiles/profile_picker_interactive_uitest.cc index 6ae7d54..4d965aa 100644 --- a/chrome/browser/ui/views/profiles/profile_picker_interactive_uitest.cc +++ b/chrome/browser/ui/views/profiles/profile_picker_interactive_uitest.cc
@@ -60,9 +60,10 @@ ProfilePickerInteractiveUiTest() = default; ~ProfilePickerInteractiveUiTest() override = default; - void ShowAndFocusPicker(ProfilePicker::EntryPoint entry_point) { + void ShowAndFocusPicker(ProfilePicker::EntryPoint entry_point, + const GURL& expected_url) { ProfilePicker::Show(entry_point); - WaitForLayoutWithoutToolbar(); + WaitForLoadStop(expected_url); EXPECT_TRUE( ui_test_utils::ShowAndFocusNativeWindow(widget()->GetNativeWindow())); } @@ -120,8 +121,8 @@ // Checks that the main picker view can be closed with keyboard shortcut. IN_PROC_BROWSER_TEST_F(ProfilePickerInteractiveUiTest, CloseWithKeyboard) { // Open a new picker. - ShowAndFocusPicker(ProfilePicker::EntryPoint::kProfileMenuManageProfiles); - WaitForLoadStop(web_contents(), GURL("chrome://profile-picker")); + ShowAndFocusPicker(ProfilePicker::EntryPoint::kProfileMenuManageProfiles, + GURL("chrome://profile-picker")); EXPECT_TRUE(ProfilePicker::IsOpen()); SendCloseWindowKeyboardCommand(); WaitForPickerClosed(); @@ -134,8 +135,8 @@ // keyboard shortcut to exit Chrome. IN_PROC_BROWSER_TEST_F(ProfilePickerInteractiveUiTest, ExitWithKeyboard) { // Open a new picker. - ShowAndFocusPicker(ProfilePicker::EntryPoint::kProfileMenuManageProfiles); - WaitForLoadStop(web_contents(), GURL("chrome://profile-picker")); + ShowAndFocusPicker(ProfilePicker::EntryPoint::kProfileMenuManageProfiles, + GURL("chrome://profile-picker")); EXPECT_TRUE(ProfilePicker::IsOpen()); content::WindowedNotificationObserver terminate_observer( @@ -154,8 +155,8 @@ // Checks that the main picker view can switch to full screen. IN_PROC_BROWSER_TEST_F(ProfilePickerInteractiveUiTest, FullscreenWithKeyboard) { // Open a new picker. - ShowAndFocusPicker(ProfilePicker::EntryPoint::kProfileMenuManageProfiles); - WaitForLoadStop(web_contents(), GURL("chrome://profile-picker")); + ShowAndFocusPicker(ProfilePicker::EntryPoint::kProfileMenuManageProfiles, + GURL("chrome://profile-picker")); EXPECT_TRUE(ProfilePicker::IsOpen()); EXPECT_FALSE(widget()->IsFullscreen()); WidgetBoundsChangeWaiter bounds_waiter(widget()); @@ -187,7 +188,8 @@ #endif IN_PROC_BROWSER_TEST_F(ProfilePickerInteractiveUiTest, MAYBE_CloseSigninWithKeyboard) { - ShowAndFocusPicker(ProfilePicker::EntryPoint::kProfileMenuAddNewProfile); + ShowAndFocusPicker(ProfilePicker::EntryPoint::kProfileMenuAddNewProfile, + GURL("chrome://profile-picker/new-profile")); // Simulate a click on the signin button. base::MockCallback<base::OnceCallback<void(bool)>> switch_finished_callback; @@ -196,9 +198,7 @@ switch_finished_callback.Get()); // Switch to the signin webview. - WaitForLayoutWithToolbar(); - WaitForLoadStop(web_contents(), - GaiaUrls::GetInstance()->signin_chrome_sync_dice()); + WaitForLoadStop(GaiaUrls::GetInstance()->signin_chrome_sync_dice()); // Close the picker with the keyboard. EXPECT_TRUE(ProfilePicker::IsOpen()); @@ -219,14 +219,14 @@ // Simulate walking through the flow starting at the picker so that navigating // back to the picker makes sense. Check that the navigation list is populated // correctly. - ShowAndFocusPicker(ProfilePicker::EntryPoint::kProfileMenuManageProfiles); - WaitForLoadStop(web_contents(), GURL("chrome://profile-picker")); + ShowAndFocusPicker(ProfilePicker::EntryPoint::kProfileMenuManageProfiles, + GURL("chrome://profile-picker")); EXPECT_EQ(1, web_contents()->GetController().GetEntryCount()); EXPECT_EQ(0, web_contents()->GetController().GetLastCommittedEntryIndex()); web_contents()->GetController().LoadURL( GURL("chrome://profile-picker/new-profile"), content::Referrer(), ui::PAGE_TRANSITION_AUTO_TOPLEVEL, std::string()); - WaitForLoadStop(web_contents(), GURL("chrome://profile-picker/new-profile")); + WaitForLoadStop(GURL("chrome://profile-picker/new-profile")); EXPECT_EQ(2, web_contents()->GetController().GetEntryCount()); EXPECT_EQ(1, web_contents()->GetController().GetLastCommittedEntryIndex()); @@ -237,19 +237,16 @@ switch_finished_callback.Get()); // Switch to the signin webview. - WaitForLayoutWithToolbar(); - WaitForLoadStop(web_contents(), - GaiaUrls::GetInstance()->signin_chrome_sync_dice()); + WaitForLoadStop(GaiaUrls::GetInstance()->signin_chrome_sync_dice()); // Navigate back with the keyboard. SendBackKeyboardCommand(); - WaitForLayoutWithoutToolbar(); - WaitForLoadStop(web_contents(), GURL("chrome://profile-picker/new-profile")); + WaitForLoadStop(GURL("chrome://profile-picker/new-profile")); EXPECT_EQ(1, web_contents()->GetController().GetLastCommittedEntryIndex()); // Navigate again back with the keyboard. SendBackKeyboardCommand(); - WaitForLoadStop(web_contents(), GURL("chrome://profile-picker")); + WaitForLoadStop(GURL("chrome://profile-picker")); EXPECT_EQ(0, web_contents()->GetController().GetLastCommittedEntryIndex()); // Navigating back once again does nothing.
diff --git a/chrome/browser/ui/views/profiles/profile_picker_test_base.cc b/chrome/browser/ui/views/profiles/profile_picker_test_base.cc index f49a10fa..b0ee655f 100644 --- a/chrome/browser/ui/views/profiles/profile_picker_test_base.cc +++ b/chrome/browser/ui/views/profiles/profile_picker_test_base.cc
@@ -19,15 +19,14 @@ namespace { -// Waits until a view's visibility has the expected value. -class ViewVisibilityChangedWaiter : public views::ViewObserver { +// Waits until a view gets attached to its widget. +class WidgetAttachedWaiter : public views::ViewObserver { public: - ViewVisibilityChangedWaiter(views::View* view, bool expect_toolbar_visible) - : view_(view), expect_toolbar_visible_(expect_toolbar_visible) {} - ~ViewVisibilityChangedWaiter() override = default; + explicit WidgetAttachedWaiter(views::View* view) : view_(view) {} + ~WidgetAttachedWaiter() override = default; void Wait() { - if (view_->GetVisible() == expect_toolbar_visible_) + if (view_->GetWidget()) return; observation_.Observe(view_); run_loop_.Run(); @@ -35,17 +34,13 @@ private: // ViewObserver: - void OnViewVisibilityChanged(views::View* observed_view, - views::View* starting_view) override { - if (observed_view == starting_view && - starting_view->GetVisible() == expect_toolbar_visible_) { + void OnViewAddedToWidget(views::View* observed_view) override { + if (observed_view == view_) run_loop_.Quit(); - } } base::RunLoop run_loop_; views::View* const view_; - bool expect_toolbar_visible_; base::ScopedObservation<views::View, views::ViewObserver> observation_{this}; }; @@ -91,28 +86,23 @@ return ProfilePicker::GetWebViewForTesting(); } -void ProfilePickerTestBase::WaitForLayoutWithToolbar() { - ViewVisibilityChangedWaiter(ProfilePicker::GetToolbarForTesting(), - /*expect_toolbar_visible=*/true) - .Wait(); +void ProfilePickerTestBase::WaitForPickerWidgetCreated() { + WidgetAttachedWaiter(view()).Wait(); } -void ProfilePickerTestBase::WaitForLayoutWithoutToolbar() { - ViewVisibilityChangedWaiter(ProfilePicker::GetToolbarForTesting(), - /*expect_toolbar_visible=*/false) - .Wait(); -} - -void ProfilePickerTestBase::WaitForLoadStop(content::WebContents* contents, - const GURL& url) { - DCHECK(contents); - if (contents->GetLastCommittedURL() == url && !contents->IsLoading()) +void ProfilePickerTestBase::WaitForLoadStop(const GURL& url, + content::WebContents* target) { + content::WebContents* wc = target ? target : web_contents(); + if (wc && wc->GetLastCommittedURL() == url && !wc->IsLoading()) return; ui_test_utils::UrlLoadObserver url_observer( url, content::NotificationService::AllSources()); url_observer.Wait(); - EXPECT_EQ(contents->GetLastCommittedURL(), url); + + // Update the pointer (as web_contents() could have changed in the mean-time). + wc = target ? target : web_contents(); + EXPECT_EQ(wc->GetLastCommittedURL(), url); } void ProfilePickerTestBase::WaitForPickerClosed() {
diff --git a/chrome/browser/ui/views/profiles/profile_picker_test_base.h b/chrome/browser/ui/views/profiles/profile_picker_test_base.h index c712ec3..6940fea50b 100644 --- a/chrome/browser/ui/views/profiles/profile_picker_test_base.h +++ b/chrome/browser/ui/views/profiles/profile_picker_test_base.h
@@ -33,13 +33,15 @@ // Returns the internal web view for the profile picker. views::WebView* web_view(); - // Waits until a relayout of the main view has been performed. This implies - // the appropriate web_contents() is attached to the layout. - void WaitForLayoutWithToolbar(); - void WaitForLayoutWithoutToolbar(); + // Wait until the widget of the picker gets created and the initialization of + // the picker is thus finished (and notably `widget()` is not null). + void WaitForPickerWidgetCreated(); - // Waits until the web contents stops loading `url`. - void WaitForLoadStop(content::WebContents* contents, const GURL& url); + // Waits until `target` WebContents stops loading `url`. If no `target` is + // provided, it checks for the current `web_contents()` to stop loading `url`. + // This also works if `web_contents()` changes throughout the waiting as it is + // technically observing all web contents. + void WaitForLoadStop(const GURL& url, content::WebContents* target = nullptr); // Waits until the picker gets closed. void WaitForPickerClosed();
diff --git a/chrome/browser/ui/views/profiles/profile_picker_view.cc b/chrome/browser/ui/views/profiles/profile_picker_view.cc index a6980dea..32c12dd 100644 --- a/chrome/browser/ui/views/profiles/profile_picker_view.cc +++ b/chrome/browser/ui/views/profiles/profile_picker_view.cc
@@ -241,17 +241,6 @@ } // static -views::View* ProfilePicker::GetToolbarForTesting() { -#if BUILDFLAG(ENABLE_DICE_SUPPORT) - if (!g_profile_picker_view) - return nullptr; - return g_profile_picker_view->toolbar_; -#else - return nullptr; -#endif -} - -// static void ProfilePicker::AddOnProfilePickerOpenedCallbackForTesting( base::OnceClosure callback) { DCHECK(!g_profile_picker_opened_callback_for_testing); @@ -552,11 +541,6 @@ #endif ShowScreenInSystemContents(CreateURLForEntryPoint(entry_point_)); -#if BUILDFLAG(ENABLE_DICE_SUPPORT) - // It's important for tests that the toolbar container starts visible (but - // empty) and gets hidden later when setting up the layout. - toolbar_->SetVisible(false); -#endif GetWidget()->Show(); state_ = kReady; @@ -785,9 +769,9 @@ #if BUILDFLAG(ENABLE_DICE_SUPPORT) auto toolbar = std::make_unique<ProfilePickerDiceSignInToolbar>(); - // It is important for tests that the top container starts visible (being - // empty). toolbar_ = AddChildView(std::move(toolbar)); + // Toolbar gets built and set visible once we it's needed for the Dice signin. + toolbar_->SetVisible(false); #endif auto web_view = std::make_unique<views::WebView>();
diff --git a/chrome/browser/ui/views/profiles/profile_picker_view_browsertest.cc b/chrome/browser/ui/views/profiles/profile_picker_view_browsertest.cc index 42b8034..c28616d 100644 --- a/chrome/browser/ui/views/profiles/profile_picker_view_browsertest.cc +++ b/chrome/browser/ui/views/profiles/profile_picker_view_browsertest.cc
@@ -281,9 +281,8 @@ // profile that was created. Profile* StartSigninFlow() { ProfilePicker::Show(ProfilePicker::EntryPoint::kProfileMenuAddNewProfile); - WaitForLayoutWithoutToolbar(); // Wait until webUI is fully initialized. - content::WaitForLoadStop(web_contents()); + WaitForLoadStop(GURL("chrome://profile-picker/new-profile")); // Simulate a click on the signin button. base::MockCallback<base::OnceCallback<void(bool)>> switch_finished_callback; @@ -293,9 +292,7 @@ // The DICE navigation happens in a new web contents (for the profile being // created), wait for it. - WaitForLayoutWithToolbar(); - WaitForLoadStop(web_contents(), - GaiaUrls::GetInstance()->signin_chrome_sync_dice()); + WaitForLoadStop(GaiaUrls::GetInstance()->signin_chrome_sync_dice()); return static_cast<Profile*>(web_contents()->GetBrowserContext()); } @@ -399,25 +396,25 @@ IN_PROC_BROWSER_TEST_F(ProfilePickerCreationFlowBrowserTest, ShowPicker) { ProfilePicker::Show(ProfilePicker::EntryPoint::kOnStartup); - WaitForLayoutWithoutToolbar(); EXPECT_TRUE(ProfilePicker::IsOpen()); + WaitForPickerWidgetCreated(); // Check that non-default accessible title is provided both before the page // loads and after it loads. views::WidgetDelegate* delegate = widget()->widget_delegate(); EXPECT_NE(delegate->GetWindowTitle(), delegate->GetAccessibleWindowTitle()); - WaitForLoadStop(web_contents(), GURL("chrome://profile-picker")); + WaitForLoadStop(GURL("chrome://profile-picker")); EXPECT_NE(delegate->GetWindowTitle(), delegate->GetAccessibleWindowTitle()); } IN_PROC_BROWSER_TEST_F(ProfilePickerCreationFlowBrowserTest, ShowChoice) { ProfilePicker::Show(ProfilePicker::EntryPoint::kProfileMenuAddNewProfile); - WaitForLayoutWithoutToolbar(); EXPECT_TRUE(ProfilePicker::IsOpen()); + WaitForPickerWidgetCreated(); // Check that non-default accessible title is provided both before the page // loads and after it loads. views::WidgetDelegate* delegate = widget()->widget_delegate(); EXPECT_NE(delegate->GetWindowTitle(), delegate->GetAccessibleWindowTitle()); - WaitForLoadStop(web_contents(), GURL("chrome://profile-picker/new-profile")); + WaitForLoadStop(GURL("chrome://profile-picker/new-profile")); EXPECT_NE(delegate->GetWindowTitle(), delegate->GetAccessibleWindowTitle()); } @@ -431,14 +428,14 @@ // Wait for the sign-in to propagate to the flow, resulting in sync // confirmation screen getting displayed. - WaitForLoadStop(web_contents(), GURL("chrome://sync-confirmation/")); + WaitForLoadStop(GURL("chrome://sync-confirmation/")); // Simulate closing the UI with "No, thanks". LoginUIServiceFactory::GetForProfile(profile_being_created) ->SyncConfirmationUIClosed(LoginUIService::ABORT_SYNC); Browser* new_browser = BrowserAddedWaiter(2u).Wait(); - WaitForLoadStop(new_browser->tab_strip_model()->GetActiveWebContents(), - GURL("chrome://newtab/")); + WaitForLoadStop(GURL("chrome://newtab/"), + new_browser->tab_strip_model()->GetActiveWebContents()); // Check expectations when the profile creation flow is done. WaitForPickerClosed(); @@ -468,7 +465,7 @@ // Wait for the sign-in to propagate to the flow, resulting in sync // confirmation screen getting displayed. - WaitForLoadStop(web_contents(), GURL("chrome://sync-confirmation/")); + WaitForLoadStop(GURL("chrome://sync-confirmation/")); // Close the flow with the [X] button. widget()->CloseWithReason(views::Widget::ClosedReason::kCloseButtonClicked); @@ -480,14 +477,14 @@ // As the flow for `profile_to_cancel` got aborted, it's disregarded. Instead // of the profile switch screen, the normal sync confirmation should appear. - WaitForLoadStop(web_contents(), GURL("chrome://sync-confirmation/")); + WaitForLoadStop(GURL("chrome://sync-confirmation/")); // Simulate closing the UI with "No, thanks". LoginUIServiceFactory::GetForProfile(profile_being_created) ->SyncConfirmationUIClosed(LoginUIService::ABORT_SYNC); Browser* new_browser = BrowserAddedWaiter(2u).Wait(); - WaitForLoadStop(new_browser->tab_strip_model()->GetActiveWebContents(), - GURL("chrome://newtab/")); + WaitForLoadStop(GURL("chrome://newtab/"), + new_browser->tab_strip_model()->GetActiveWebContents()); // Check expectations when the profile creation flow is done. WaitForPickerClosed(); @@ -524,14 +521,14 @@ // Wait for the sign-in to propagate to the flow, resulting in sync // confirmation screen getting displayed. - WaitForLoadStop(web_contents(), GURL("chrome://sync-confirmation/")); + WaitForLoadStop(GURL("chrome://sync-confirmation/")); // Simulate closing the UI with "No, thanks". LoginUIServiceFactory::GetForProfile(profile_being_created) ->SyncConfirmationUIClosed(LoginUIService::ABORT_SYNC); Browser* new_browser = BrowserAddedWaiter(2u).Wait(); - WaitForLoadStop(new_browser->tab_strip_model()->GetActiveWebContents(), - GURL("chrome://newtab/")); + WaitForLoadStop(GURL("chrome://newtab/"), + new_browser->tab_strip_model()->GetActiveWebContents()); // Check expectations when the profile creation flow is done. WaitForPickerClosed(); @@ -560,14 +557,14 @@ // Wait for the sign-in to propagate to the flow, resulting in sync // confirmation screen getting displayed. - WaitForLoadStop(web_contents(), GURL("chrome://sync-confirmation/")); + WaitForLoadStop(GURL("chrome://sync-confirmation/")); // Simulate closing the UI with "Yes, I'm in". LoginUIServiceFactory::GetForProfile(profile_being_created) ->SyncConfirmationUIClosed(LoginUIService::CONFIGURE_SYNC_FIRST); Browser* new_browser = BrowserAddedWaiter(2u).Wait(); - WaitForLoadStop(new_browser->tab_strip_model()->GetActiveWebContents(), - GURL("chrome://settings/syncSetup")); + WaitForLoadStop(GURL("chrome://settings/syncSetup"), + new_browser->tab_strip_model()->GetActiveWebContents()); // Check expectations when the profile creation flow is done. WaitForPickerClosed(); @@ -606,7 +603,7 @@ // A new pppup browser is displayed (with the specified URL). Browser* new_browser = BrowserAddedWaiter(2u).Wait(); EXPECT_EQ(new_browser->type(), Browser::TYPE_POPUP); - WaitForLoadStop(new_browser->tab_strip_model()->GetActiveWebContents(), kURL); + WaitForLoadStop(kURL, new_browser->tab_strip_model()->GetActiveWebContents()); } // Regression test for crbug.com/1219980. @@ -648,14 +645,14 @@ // Wait for the sign-in to propagate to the flow, resulting in sync // confirmation screen getting displayed. - WaitForLoadStop(web_contents(), GURL("chrome://sync-confirmation/")); + WaitForLoadStop(GURL("chrome://sync-confirmation/")); // Simulate closing the UI with "Yes, I'm in". LoginUIServiceFactory::GetForProfile(profile_being_created) ->SyncConfirmationUIClosed(LoginUIService::ABORT_SYNC); Browser* new_browser = BrowserAddedWaiter(2u).Wait(); - WaitForLoadStop(new_browser->tab_strip_model()->GetActiveWebContents(), - GURL("chrome://newtab/")); + WaitForLoadStop(GURL("chrome://newtab/"), + new_browser->tab_strip_model()->GetActiveWebContents()); // Check expectations when the profile creation flow is done. WaitForPickerClosed(); @@ -687,7 +684,7 @@ wc->GetController().LoadURL(kNonGaiaURL, content::Referrer(), ui::PAGE_TRANSITION_AUTO_TOPLEVEL, std::string()); Browser* new_browser = BrowserAddedWaiter(2u).Wait(); - WaitForLoadStop(wc, kNonGaiaURL); + WaitForLoadStop(kNonGaiaURL, wc); WaitForPickerClosed(); // Check that the web contents got actually moved to the browser. @@ -773,7 +770,7 @@ IN_PROC_BROWSER_TEST_F(ProfilePickerCreationFlowBrowserTest, OpenPickerAndClose) { ProfilePicker::Show(ProfilePicker::EntryPoint::kProfileMenuManageProfiles); - WaitForLayoutWithoutToolbar(); + WaitForLoadStop(GURL("chrome://profile-picker")); EXPECT_TRUE(ProfilePicker::IsOpen()); ProfilePicker::Hide(); WaitForPickerClosed(); @@ -784,7 +781,7 @@ OpenPickerWhileClosing) { // Open the first picker. ProfilePicker::Show(ProfilePicker::EntryPoint::kProfileMenuManageProfiles); - WaitForLayoutWithoutToolbar(); + WaitForLoadStop(GURL("chrome://profile-picker")); EXPECT_TRUE(ProfilePicker::IsOpen()); // Request to open the second picker window while the first one is still @@ -805,13 +802,13 @@ base::FilePath other_path = CreateNewProfileWithoutBrowser(); // Open the picker. ProfilePicker::Show(ProfilePicker::EntryPoint::kProfileMenuManageProfiles); - WaitForLayoutWithoutToolbar(); + WaitForLoadStop(GURL("chrome://profile-picker")); // Open the other profile. OpenProfileFromPicker(other_path, /*open_settings=*/false); // Browser for the profile is displayed. Browser* new_browser = BrowserAddedWaiter(2u).Wait(); - WaitForLoadStop(new_browser->tab_strip_model()->GetActiveWebContents(), - GURL("chrome://newtab/")); + WaitForLoadStop(GURL("chrome://newtab/"), + new_browser->tab_strip_model()->GetActiveWebContents()); EXPECT_EQ(new_browser->profile()->GetPath(), other_path); WaitForPickerClosed(); // IPH is shown. @@ -826,13 +823,13 @@ base::FilePath other_path = CreateNewProfileWithoutBrowser(); // Open the picker. ProfilePicker::Show(ProfilePicker::EntryPoint::kProfileMenuManageProfiles); - WaitForLayoutWithoutToolbar(); + WaitForLoadStop(GURL("chrome://profile-picker")); // Open the other profile. OpenProfileFromPicker(other_path, /*open_settings=*/true); // Browser for the profile is displayed. Browser* new_browser = BrowserAddedWaiter(2u).Wait(); - WaitForLoadStop(new_browser->tab_strip_model()->GetActiveWebContents(), - GURL("chrome://settings/manageProfile")); + WaitForLoadStop(GURL("chrome://settings/manageProfile"), + new_browser->tab_strip_model()->GetActiveWebContents()); EXPECT_EQ(new_browser->profile()->GetPath(), other_path); WaitForPickerClosed(); // IPH is not shown. @@ -848,13 +845,13 @@ // Open the picker. ProfilePicker::Show(ProfilePicker::EntryPoint::kProfileMenuManageProfiles, kTargetURL); - WaitForLayoutWithoutToolbar(); + WaitForLoadStop(GURL("chrome://profile-picker")); // Open the profile. OpenProfileFromPicker(profile_path, /*open_settings=*/false); // Browser for the profile is displayed. Browser* new_browser = BrowserAddedWaiter(2u).Wait(); - WaitForLoadStop(new_browser->tab_strip_model()->GetActiveWebContents(), - kTargetURL); + WaitForLoadStop(kTargetURL, + new_browser->tab_strip_model()->GetActiveWebContents()); EXPECT_EQ(new_browser->profile()->GetPath(), profile_path); WaitForPickerClosed(); } @@ -867,7 +864,7 @@ base::FilePath profile_path = CreateNewProfileWithoutBrowser(); // Open the picker without target URL. ProfilePicker::Show(ProfilePicker::EntryPoint::kProfileMenuManageProfiles); - WaitForLayoutWithoutToolbar(); + WaitForLoadStop(GURL("chrome://profile-picker")); // Request a URL when the picker is already open. ProfilePicker::Show(ProfilePicker::EntryPoint::kProfileMenuManageProfiles, kTargetURL); @@ -875,8 +872,8 @@ OpenProfileFromPicker(profile_path, /*open_settings=*/false); // Browser for the profile is displayed. Browser* new_browser = BrowserAddedWaiter(2u).Wait(); - WaitForLoadStop(new_browser->tab_strip_model()->GetActiveWebContents(), - kTargetURL); + WaitForLoadStop(kTargetURL, + new_browser->tab_strip_model()->GetActiveWebContents()); EXPECT_EQ(new_browser->profile()->GetPath(), profile_path); WaitForPickerClosed(); } @@ -890,13 +887,13 @@ base::FilePath other_path = CreateNewProfileWithoutBrowser(); // Open the picker. ProfilePicker::Show(ProfilePicker::EntryPoint::kProfileMenuManageProfiles); - WaitForLayoutWithoutToolbar(); + WaitForLoadStop(GURL("chrome://profile-picker")); // Open a Guest profile. OpenGuestFromPicker(); // Browser for the guest profile is displayed. Browser* new_browser = BrowserAddedWaiter(2u).Wait(); - WaitForLoadStop(new_browser->tab_strip_model()->GetActiveWebContents(), - GURL("chrome://newtab")); + WaitForLoadStop(GURL("chrome://newtab"), + new_browser->tab_strip_model()->GetActiveWebContents()); EXPECT_TRUE(new_browser->profile()->IsGuestSession()); WaitForPickerClosed(); // IPH is not shown. @@ -912,8 +909,7 @@ // Open the picker. ProfilePicker::Show(ProfilePicker::EntryPoint::kProfileMenuManageProfiles); - WaitForLayoutWithoutToolbar(); - WaitForLoadStop(web_contents(), GURL("chrome://profile-picker")); + WaitForLoadStop(GURL("chrome://profile-picker")); // Close the browser window. BrowserList::GetInstance()->CloseAllBrowsersWithProfile(browser()->profile()); @@ -976,21 +972,21 @@ // Wait for the sign-in to propagate to the flow, resulting in enterprise // welcome screen getting displayed. - WaitForLoadStop(web_contents(), GURL("chrome://enterprise-profile-welcome/")); + WaitForLoadStop(GURL("chrome://enterprise-profile-welcome/")); ExpectEnterpriseScreenTypeAndProceed( /*expected_type=*/EnterpriseProfileWelcomeUI::ScreenType:: kEntepriseAccountSyncEnabled, /*proceed=*/true); - WaitForLoadStop(web_contents(), GURL("chrome://sync-confirmation/")); + WaitForLoadStop(GURL("chrome://sync-confirmation/")); // Simulate finishing the flow with "No, thanks". LoginUIServiceFactory::GetForProfile(profile_being_created) ->SyncConfirmationUIClosed(LoginUIService::ABORT_SYNC); Browser* new_browser = BrowserAddedWaiter(2u).Wait(); - WaitForLoadStop(new_browser->tab_strip_model()->GetActiveWebContents(), - GURL("chrome://newtab/")); + WaitForLoadStop(GURL("chrome://newtab/"), + new_browser->tab_strip_model()->GetActiveWebContents()); WaitForPickerClosed(); // Check expectations when the profile creation flow is done. @@ -1028,7 +1024,7 @@ // Wait for the sign-in to propagate to the flow, resulting in enterprise // welcome screen getting displayed. - WaitForLoadStop(web_contents(), GURL("chrome://enterprise-profile-welcome/")); + WaitForLoadStop(GURL("chrome://enterprise-profile-welcome/")); ExpectEnterpriseScreenTypeAndProceed( /*expected_type=*/EnterpriseProfileWelcomeUI::ScreenType:: @@ -1036,8 +1032,8 @@ /*proceed=*/true); Browser* new_browser = BrowserAddedWaiter(2u).Wait(); - WaitForLoadStop(new_browser->tab_strip_model()->GetActiveWebContents(), - GURL("chrome://newtab/")); + WaitForLoadStop(GURL("chrome://newtab/"), + new_browser->tab_strip_model()->GetActiveWebContents()); WaitForPickerClosed(); // Check expectations when the profile creation flow is done. @@ -1072,21 +1068,21 @@ // Wait for the sign-in to propagate to the flow, resulting in enterprise // welcome screen getting displayed. - WaitForLoadStop(web_contents(), GURL("chrome://enterprise-profile-welcome/")); + WaitForLoadStop(GURL("chrome://enterprise-profile-welcome/")); ExpectEnterpriseScreenTypeAndProceed( /*expected_type=*/EnterpriseProfileWelcomeUI::ScreenType:: kEntepriseAccountSyncEnabled, /*proceed=*/true); - WaitForLoadStop(web_contents(), GURL("chrome://sync-confirmation/")); + WaitForLoadStop(GURL("chrome://sync-confirmation/")); // Simulate finishing the flow with "Configure sync". LoginUIServiceFactory::GetForProfile(profile_being_created) ->SyncConfirmationUIClosed(LoginUIService::CONFIGURE_SYNC_FIRST); Browser* new_browser = BrowserAddedWaiter(2u).Wait(); - WaitForLoadStop(new_browser->tab_strip_model()->GetActiveWebContents(), - GURL("chrome://settings/syncSetup")); + WaitForLoadStop(GURL("chrome://settings/syncSetup"), + new_browser->tab_strip_model()->GetActiveWebContents()); WaitForPickerClosed(); // Check expectations when the profile creation flow is done. @@ -1121,7 +1117,7 @@ // Wait for the sign-in to propagate to the flow, resulting in enterprise // welcome screen getting displayed. - WaitForLoadStop(web_contents(), GURL("chrome://enterprise-profile-welcome/")); + WaitForLoadStop(GURL("chrome://enterprise-profile-welcome/")); ProfileDeletionObserver observer; ExpectEnterpriseScreenTypeAndProceed( @@ -1165,11 +1161,10 @@ // Simulate a successful Gaia sign-in. SignIn(profile_being_created, "joe.consumer@gmail.com", "Joe"); - // The profile switch screen should be displayed. - WaitForLayoutWithoutToolbar(); - WaitForLoadStop(web_contents(), GURL("chrome://sync-confirmation/loading")); - WaitForLoadStop(web_contents(), - GURL("chrome://profile-picker/profile-switch")); + // The profile switch screen should be displayed (in between, + // chrome://sync-confirmation/loading gets displayed but that page may not + // finish loading and anyway is not so relevant). + WaitForLoadStop(GURL("chrome://profile-picker/profile-switch")); EXPECT_EQ(ProfilePicker::GetSwitchProfilePath(), other_path); // Simulate clicking on the confirm switch button. @@ -1180,8 +1175,8 @@ // Browser for a pre-existing profile is displayed. Browser* new_browser = BrowserAddedWaiter(2u).Wait(); - WaitForLoadStop(new_browser->tab_strip_model()->GetActiveWebContents(), - GURL("chrome://newtab/")); + WaitForLoadStop(GURL("chrome://newtab/"), + new_browser->tab_strip_model()->GetActiveWebContents()); EXPECT_EQ(new_browser->profile()->GetPath(), other_path); // Check expectations when the profile creation flow is done. @@ -1215,11 +1210,10 @@ // Simulate a successful Gaia sign-in. SignIn(profile_being_created, "joe.consumer@gmail.com", "Joe"); - // The profile switch screen should be displayed. - WaitForLayoutWithoutToolbar(); - WaitForLoadStop(web_contents(), GURL("chrome://sync-confirmation/loading")); - WaitForLoadStop(web_contents(), - GURL("chrome://profile-picker/profile-switch")); + // The profile switch screen should be displayed (in between, + // chrome://sync-confirmation/loading gets displayed but that page may not + // finish loading and anyway is not so relevant). + WaitForLoadStop(GURL("chrome://profile-picker/profile-switch")); EXPECT_EQ(ProfilePicker::GetSwitchProfilePath(), other_path); // Simulate clicking on the cancel button. @@ -1351,14 +1345,14 @@ // Wait for the sign-in to propagate to the flow, resulting in sync // confirmation screen getting displayed. - WaitForLoadStop(web_contents(), GURL("chrome://sync-confirmation/")); + WaitForLoadStop(GURL("chrome://sync-confirmation/")); // Simulate closing the UI with "No, thanks". LoginUIServiceFactory::GetForProfile(profile_being_created) ->SyncConfirmationUIClosed(LoginUIService::ABORT_SYNC); Browser* new_browser = BrowserAddedWaiter(2u).Wait(); - WaitForLoadStop(new_browser->tab_strip_model()->GetActiveWebContents(), - GURL("chrome://newtab/")); + WaitForLoadStop(GURL("chrome://newtab/"), + new_browser->tab_strip_model()->GetActiveWebContents()); WaitForPickerClosed(); EXPECT_EQ(2u, profile_manager()->GetNumberOfProfiles());
diff --git a/chrome/browser/ui/views/session_crashed_bubble_view.cc b/chrome/browser/ui/views/session_crashed_bubble_view.cc index a78d5f1..bef9e38 100644 --- a/chrome/browser/ui/views/session_crashed_bubble_view.cc +++ b/chrome/browser/ui/views/session_crashed_bubble_view.cc
@@ -248,7 +248,7 @@ .SetTitle(l10n_util::GetStringUTF16(IDS_SESSION_CRASHED_BUBBLE_TITLE)) .DisableCloseOnDeactivate() .SetIsAlertDialog() - .SetWindowClosingCallback( + .SetDialogDestroyingCallback( base::BindOnce(&SessionCrashedBubbleDelegate::OnWindowClosing, base::Unretained(bubble_delegate))) .AddBodyText(ui::DialogModelLabel(IDS_SESSION_CRASHED_VIEW_MESSAGE));
diff --git a/chrome/browser/ui/views/side_search/side_search_browser_controller_browsertest.cc b/chrome/browser/ui/views/side_search/side_search_browser_controller_browsertest.cc index d15514aa..852b169 100644 --- a/chrome/browser/ui/views/side_search/side_search_browser_controller_browsertest.cc +++ b/chrome/browser/ui/views/side_search/side_search_browser_controller_browsertest.cc
@@ -10,13 +10,16 @@ #include "build/build_config.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_tabstrip.h" +#include "chrome/browser/ui/side_search/side_search_config.h" #include "chrome/browser/ui/side_search/side_search_tab_contents_helper.h" #include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/side_panel.h" #include "chrome/browser/ui/views/toolbar/toolbar_view.h" +#include "chrome/common/webui_url_constants.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" +#include "components/google/core/common/google_util.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" #include "content/public/common/result_codes.h" @@ -29,32 +32,76 @@ namespace { -constexpr char kGoogleSearchURL[] = "https://www.google.com/search?q=test1"; -constexpr char kGoogleSearchHomePageURL[] = "https://www.google.com"; -constexpr char kNonGoogleURL[] = "https://www.test.com"; - ui::MouseEvent GetDummyEvent() { return ui::MouseEvent(ui::ET_MOUSE_PRESSED, gfx::PointF(), gfx::PointF(), base::TimeTicks::Now(), 0, 0); } +// Strips out the port from a given `url`. Useful when testing side search with +// the EmbeddedTestServer. +GURL GetFilteredURL(const GURL& url) { + GURL filtered_url = url; + if (url.has_port()) { + GURL::Replacements remove_port; + remove_port.ClearPort(); + filtered_url = filtered_url.ReplaceComponents(remove_port); + } + return filtered_url; +} + +// In the spirit of testing for the current use of side search for the Google +// DSE set the callback to allow Google SRP urls to proceed in the side panel. +// Note we clear away the port here since google_util::IsGoogleSearchUrl does +// not allow arbitrary ports in the url but the EmbeddedTestServer requires us +// to use URLs with the specific non-standard port it listens on. +// TODO(tluk): Eliminate the Google specific nature of both of these. We should +// be able to update tests to use URLs that satisfy a combination of the below +// two checks without needing such complicated and specific logic. +bool ShouldNavigateInSidePanel(const GURL& url) { + return google_util::IsGoogleSearchUrl(GetFilteredURL(url)); +} + +bool CanShowSidePanelForURL(const GURL& url) { + GURL filtered_url = GetFilteredURL(url); + return !google_util::IsGoogleSearchUrl(filtered_url) && + !google_util::IsGoogleHomePageUrl(filtered_url) && + filtered_url.spec() != chrome::kChromeUINewTabURL; +} + } // namespace -// TODO(tluk): Add more tests for the different side panel configurations. +// TODO(tluk): Refactor out google specific references and have this apply +// more generically to DSEs. class SideSearchBrowserControllerTest : public InProcessBrowserTest { public: // InProcessBrowserTest: void SetUp() override { scoped_feature_list_.InitWithFeatures(GetEnabledFeatures(), {}); + ASSERT_TRUE(embedded_test_server()->InitializeAndListen()); InProcessBrowserTest::SetUp(); } + void SetUpOnMainThread() override { host_resolver()->AddRule("*", "127.0.0.1"); - ASSERT_TRUE(embedded_test_server()->Start()); + embedded_test_server()->RegisterDefaultHandler( + base::BindRepeating(&SideSearchBrowserControllerTest::HandleRequest, + base::Unretained(this))); + embedded_test_server()->StartAcceptingConnections(); + InProcessBrowserTest::SetUpOnMainThread(); + auto* config = SideSearchConfig::Get(browser()->profile()); + config->SetShouldNavigateInSidePanelCalback( + base::BindRepeating(ShouldNavigateInSidePanel)); + config->SetCanShowSidePanelForURLCallback( + base::BindRepeating(CanShowSidePanelForURL)); SetIsSidePanelSRPAvailableAt(browser(), 0, true); } + void TearDownOnMainThread() override { + EXPECT_TRUE(embedded_test_server()->ShutdownAndWaitUntilComplete()); + InProcessBrowserTest::TearDownOnMainThread(); + } + virtual std::vector<base::Feature> GetEnabledFeatures() { return {features::kSideSearch}; } @@ -63,14 +110,14 @@ browser->tab_strip_model()->ActivateTabAt(index); } - void AppendTab(Browser* browser, const std::string& url) { - chrome::AddTabAt(browser, GURL(url), -1, true); + void AppendTab(Browser* browser, const GURL& url) { + chrome::AddTabAt(browser, url, -1, true); SetIsSidePanelSRPAvailableAt( browser, browser->tab_strip_model()->GetTabCount() - 1, true); } - void NavigateActiveTab(Browser* browser, const std::string& url) { - ASSERT_TRUE(ui_test_utils::NavigateToURL(browser, GURL(url))); + void NavigateActiveTab(Browser* browser, const GURL& url) { + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser, url)); } void NotifyButtonClick(Browser* browser) { @@ -87,9 +134,8 @@ void SetIsSidePanelSRPAvailableAt(Browser* browser, int index, bool is_available) { - auto* tab_contents_helper = SideSearchTabContentsHelper::FromWebContents( - browser->tab_strip_model()->GetWebContentsAt(index)); - tab_contents_helper->SetIsSidePanelSRPAvailableForTesting(is_available); + SideSearchConfig::Get(browser->profile()) + ->set_is_side_panel_srp_available(is_available); } BrowserView* BrowserViewFor(Browser* browser) { @@ -116,21 +162,26 @@ return tab_contents_helper->side_panel_contents_for_testing(); } - void NavigateToSRPAndNonGoogleUrl(Browser* browser) { + void NavigateToSRPAndNonGoogleUrl( + Browser* browser, + absl::optional<GURL> google_url = absl::nullopt) { // The side panel button should never be visible on the Google search page. - NavigateActiveTab(browser, kGoogleSearchURL); + NavigateActiveTab(browser, google_url.value_or(google_search_url())); EXPECT_FALSE(GetSidePanelButtonFor(browser)->GetVisible()); EXPECT_FALSE(GetSidePanelFor(browser)->GetVisible()); // The side panel button should be visible if on a non-Google page and the // current tab has previously encountered a Google search page. - NavigateActiveTab(browser, kNonGoogleURL); + NavigateActiveTab(browser, non_google_url()); EXPECT_TRUE(GetSidePanelButtonFor(browser)->GetVisible()); EXPECT_FALSE(GetSidePanelFor(browser)->GetVisible()); } - void NavigateToSRPAndOpenSidePanel(Browser* browser) { - NavigateToSRPAndNonGoogleUrl(browser); + void NavigateToSRPAndOpenSidePanel( + Browser* browser, + absl::optional<GURL> google_url = absl::nullopt) { + NavigateToSRPAndNonGoogleUrl(browser, + google_url.value_or(google_search_url())); NotifyButtonClick(browser); EXPECT_TRUE(GetSidePanelButtonFor(browser)->GetVisible()); @@ -138,6 +189,26 @@ } protected: + GURL google_search_url() { + return embedded_test_server()->GetURL("www.google.com", "/search?q=test"); + } + + GURL google_homepage_url() { + return embedded_test_server()->GetURL("www.google.com", "/"); + } + + GURL non_google_url() { + return embedded_test_server()->GetURL("www.test.com", "/"); + } + + std::unique_ptr<net::test_server::HttpResponse> HandleRequest( + const net::test_server::HttpRequest& request) { + auto http_response = + std::make_unique<net::test_server::BasicHttpResponse>(); + http_response->set_code(net::HTTP_OK); + return std::move(http_response); + } + base::HistogramTester histogram_tester_; private: @@ -147,21 +218,21 @@ IN_PROC_BROWSER_TEST_F(SideSearchBrowserControllerTest, SidePanelButtonShowsCorrectlySingleTab) { // The side panel button should never be visible on the Google home page. - NavigateActiveTab(browser(), kGoogleSearchHomePageURL); + NavigateActiveTab(browser(), google_homepage_url()); EXPECT_FALSE(GetSidePanelButtonFor(browser())->GetVisible()); // If no previous Google search page has been navigated to the button should // not be visible. - NavigateActiveTab(browser(), kNonGoogleURL); + NavigateActiveTab(browser(), non_google_url()); EXPECT_FALSE(GetSidePanelButtonFor(browser())->GetVisible()); // The side panel button should never be visible on the Google search page. - NavigateActiveTab(browser(), kGoogleSearchURL); + NavigateActiveTab(browser(), google_search_url()); EXPECT_FALSE(GetSidePanelButtonFor(browser())->GetVisible()); // The side panel button should be visible if on a non-Google page and the // current tab has previously encountered a Google search page. - NavigateActiveTab(browser(), kNonGoogleURL); + NavigateActiveTab(browser(), non_google_url()); EXPECT_TRUE(GetSidePanelButtonFor(browser())->GetVisible()); histogram_tester_.ExpectBucketCount( "SideSearch.AvailabilityChanged", @@ -169,7 +240,7 @@ // The side panel button should never be visible on the Google home page even // if it has already been navigated to a Google search page. - NavigateActiveTab(browser(), kGoogleSearchHomePageURL); + NavigateActiveTab(browser(), google_homepage_url()); EXPECT_FALSE(GetSidePanelButtonFor(browser())->GetVisible()); histogram_tester_.ExpectBucketCount( "SideSearch.AvailabilityChanged", @@ -177,7 +248,7 @@ // The side panel button should be visible if on a non-Google page and the // current tab has previously encountered a Google search page. - NavigateActiveTab(browser(), kNonGoogleURL); + NavigateActiveTab(browser(), non_google_url()); EXPECT_TRUE(GetSidePanelButtonFor(browser())->GetVisible()); histogram_tester_.ExpectBucketCount( "SideSearch.AvailabilityChanged", @@ -187,16 +258,16 @@ IN_PROC_BROWSER_TEST_F(SideSearchBrowserControllerTest, SidePanelButtonShowsCorrectlyMultipleTabs) { // The side panel button should never be visible on the Google home page. - AppendTab(browser(), kGoogleSearchHomePageURL); + AppendTab(browser(), google_homepage_url()); ActivateTabAt(browser(), 1); EXPECT_FALSE(GetSidePanelButtonFor(browser())->GetVisible()); // Navigate to a Google search page and then to a non-Google search page. This // should show the side panel button in the toolbar. - AppendTab(browser(), kGoogleSearchURL); + AppendTab(browser(), google_search_url()); ActivateTabAt(browser(), 2); EXPECT_FALSE(GetSidePanelButtonFor(browser())->GetVisible()); - NavigateActiveTab(browser(), kNonGoogleURL); + NavigateActiveTab(browser(), non_google_url()); EXPECT_TRUE(GetSidePanelButtonFor(browser())->GetVisible()); // Switch back to the Google search page, the side panel button should no @@ -212,13 +283,13 @@ IN_PROC_BROWSER_TEST_F(SideSearchBrowserControllerTest, SidePanelTogglesCorrectlySingleTab) { - NavigateActiveTab(browser(), kGoogleSearchURL); + NavigateActiveTab(browser(), google_search_url()); EXPECT_FALSE(GetSidePanelButtonFor(browser())->GetVisible()); EXPECT_FALSE(GetSidePanelFor(browser())->GetVisible()); // The side panel button should be visible if on a non-Google page and the // current tab has previously encountered a Google search page. - NavigateActiveTab(browser(), kNonGoogleURL); + NavigateActiveTab(browser(), non_google_url()); EXPECT_TRUE(GetSidePanelButtonFor(browser())->GetVisible()); EXPECT_FALSE(GetSidePanelFor(browser())->GetVisible()); @@ -245,19 +316,19 @@ // independent browser tabs such that both have the side panel ready. // Tab 1. - NavigateActiveTab(browser(), kGoogleSearchURL); + NavigateActiveTab(browser(), google_search_url()); EXPECT_FALSE(GetSidePanelButtonFor(browser())->GetVisible()); EXPECT_FALSE(GetSidePanelFor(browser())->GetVisible()); - NavigateActiveTab(browser(), kNonGoogleURL); + NavigateActiveTab(browser(), non_google_url()); EXPECT_TRUE(GetSidePanelButtonFor(browser())->GetVisible()); EXPECT_FALSE(GetSidePanelFor(browser())->GetVisible()); // Tab 2. - AppendTab(browser(), kGoogleSearchURL); + AppendTab(browser(), google_search_url()); ActivateTabAt(browser(), 1); EXPECT_FALSE(GetSidePanelButtonFor(browser())->GetVisible()); EXPECT_FALSE(GetSidePanelFor(browser())->GetVisible()); - NavigateActiveTab(browser(), kNonGoogleURL); + NavigateActiveTab(browser(), non_google_url()); EXPECT_TRUE(GetSidePanelButtonFor(browser())->GetVisible()); EXPECT_FALSE(GetSidePanelFor(browser())->GetVisible()); @@ -315,8 +386,8 @@ SideSearchNotAvailableInOTR) { Browser* browser2 = CreateIncognitoBrowser(); EXPECT_TRUE(browser2->profile()->IsOffTheRecord()); - NavigateActiveTab(browser2, kGoogleSearchURL); - NavigateActiveTab(browser2, kNonGoogleURL); + NavigateActiveTab(browser2, google_search_url()); + NavigateActiveTab(browser2, non_google_url()); EXPECT_EQ(nullptr, GetSidePanelButtonFor(browser2)); EXPECT_EQ(nullptr, GetSidePanelFor(browser2)); @@ -328,21 +399,21 @@ SetIsSidePanelSRPAvailableAt(browser(), 0, false); // The side panel button should never be visible on the Google home page. - NavigateActiveTab(browser(), kGoogleSearchHomePageURL); + NavigateActiveTab(browser(), google_homepage_url()); EXPECT_FALSE(GetSidePanelFor(browser())->GetVisible()); // If no previous Google search page has been navigated to the button should // not be visible. - NavigateActiveTab(browser(), kNonGoogleURL); + NavigateActiveTab(browser(), non_google_url()); EXPECT_FALSE(GetSidePanelFor(browser())->GetVisible()); // The side panel button should never be visible on the Google search page. - NavigateActiveTab(browser(), kGoogleSearchURL); + NavigateActiveTab(browser(), google_search_url()); EXPECT_FALSE(GetSidePanelFor(browser())->GetVisible()); // The side panel button should not be visible if the side panel SRP is not // available. - NavigateActiveTab(browser(), kNonGoogleURL); + NavigateActiveTab(browser(), non_google_url()); EXPECT_FALSE(GetSidePanelFor(browser())->GetVisible()); } @@ -446,19 +517,19 @@ // side panel should respect the state-per-tab flag. // Tab 1. - NavigateActiveTab(browser(), kGoogleSearchURL); + NavigateActiveTab(browser(), google_search_url()); EXPECT_FALSE(GetSidePanelButtonFor(browser())->GetVisible()); EXPECT_FALSE(GetSidePanelFor(browser())->GetVisible()); - NavigateActiveTab(browser(), kNonGoogleURL); + NavigateActiveTab(browser(), non_google_url()); EXPECT_TRUE(GetSidePanelButtonFor(browser())->GetVisible()); EXPECT_FALSE(GetSidePanelFor(browser())->GetVisible()); // Tab 2. - AppendTab(browser(), kGoogleSearchURL); + AppendTab(browser(), google_search_url()); ActivateTabAt(browser(), 1); EXPECT_FALSE(GetSidePanelButtonFor(browser())->GetVisible()); EXPECT_FALSE(GetSidePanelFor(browser())->GetVisible()); - NavigateActiveTab(browser(), kNonGoogleURL); + NavigateActiveTab(browser(), non_google_url()); EXPECT_TRUE(GetSidePanelButtonFor(browser())->GetVisible()); EXPECT_FALSE(GetSidePanelFor(browser())->GetVisible()); @@ -510,7 +581,7 @@ // Switch to another tab and open the side panel. The side panel should still // have focus as it was opened via the toolbar button. - AppendTab(browser(), kNonGoogleURL); + AppendTab(browser(), non_google_url()); ActivateTabAt(browser(), 1); NavigateToSRPAndOpenSidePanel(browser()); EXPECT_TRUE(side_panel->GetVisible()); @@ -541,12 +612,12 @@ // Navigating to a Google SRP URL should automatically hide the side panel as // it should not be available. EXPECT_TRUE(side_panel->GetVisible()); - NavigateActiveTab(browser(), kGoogleSearchURL); + NavigateActiveTab(browser(), google_search_url()); EXPECT_FALSE(side_panel->GetVisible()); // When navigating again to a non-Google / non-NTP page the side panel will // become available again but should not automatically reopen. - NavigateActiveTab(browser(), kGoogleSearchURL); + NavigateActiveTab(browser(), google_search_url()); EXPECT_FALSE(side_panel->GetVisible()); } @@ -554,7 +625,7 @@ SidePanelCrashesCloseSidePanel) { // Open two tabs with the side panel open. NavigateToSRPAndOpenSidePanel(browser()); - AppendTab(browser(), kNonGoogleURL); + AppendTab(browser(), non_google_url()); ActivateTabAt(browser(), 1); NavigateToSRPAndOpenSidePanel(browser());
diff --git a/chrome/browser/ui/views/toolbar/chrome_labs_bubble_view.cc b/chrome/browser/ui/views/toolbar/chrome_labs_bubble_view.cc index 431ea80..1b07b71 100644 --- a/chrome/browser/ui/views/toolbar/chrome_labs_bubble_view.cc +++ b/chrome/browser/ui/views/toolbar/chrome_labs_bubble_view.cc
@@ -8,6 +8,7 @@ #include "base/metrics/histogram_functions.h" #include "base/timer/elapsed_timer.h" #include "build/build_config.h" +#include "build/buildflag.h" #include "chrome/browser/about_flags.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/flag_descriptions.h" @@ -51,7 +52,8 @@ kTabScrollingSelected = 3, kSidePanelSelected = 4, kLensRegionSearchSelected = 5, - kMaxValue = kLensRegionSearchSelected, + kWebUITabStripSelected = 6, + kMaxValue = kWebUITabStripSelected, }; void EmitToHistogram(const std::u16string& selected_lab_state, @@ -81,6 +83,10 @@ } else if (internal_name == flag_descriptions::kEnableLensRegionSearchFlagId) { return ChromeLabsSelectedLab::kLensRegionSearchSelected; +#if BUILDFLAG(ENABLE_WEBUI_TAB_STRIP) && defined(OS_WIN) + } else if (internal_name == flag_descriptions::kWebUITabStripFlagId) { + return ChromeLabsSelectedLab::kWebUITabStripSelected; +#endif } else { return ChromeLabsSelectedLab::kUnspecifiedSelected; }
diff --git a/chrome/browser/ui/views/toolbar/chrome_labs_bubble_view_model.cc b/chrome/browser/ui/views/toolbar/chrome_labs_bubble_view_model.cc index 52b3afb..dd6d76b1 100644 --- a/chrome/browser/ui/views/toolbar/chrome_labs_bubble_view_model.cc +++ b/chrome/browser/ui/views/toolbar/chrome_labs_bubble_view_model.cc
@@ -6,6 +6,7 @@ #include "base/no_destructor.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" +#include "build/buildflag.h" #include "chrome/browser/flag_descriptions.h" #include "chrome/grit/generated_resources.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -65,6 +66,16 @@ "chrome-labs-tab-scrolling", version_info::Channel::BETA, tab_scrolling_variation_descriptions)); + // Thumbnail Tab Strip for Windows +#if BUILDFLAG(ENABLE_WEBUI_TAB_STRIP) && defined(OS_WIN) + lab_info.emplace_back(LabInfo( + flag_descriptions::kWebUITabStripFlagId, + l10n_util::GetStringUTF16(IDS_THUMBNAIL_TAB_STRIP_EXPERIMENT_NAME), + l10n_util::GetStringUTF16( + IDS_THUMBNAIL_TAB_STRIP_EXPERIMENT_DESCRIPTION), + "chrome-labs-thumbnail-tab-strip", version_info::Channel::BETA)); +#endif + return lab_info; }());
diff --git a/chrome/browser/ui/views/web_apps/web_app_integration_browsertest_base.cc b/chrome/browser/ui/views/web_apps/web_app_integration_browsertest_base.cc index eb324811..07fb1e2 100644 --- a/chrome/browser/ui/views/web_apps/web_app_integration_browsertest_base.cc +++ b/chrome/browser/ui/views/web_apps/web_app_integration_browsertest_base.cc
@@ -42,6 +42,7 @@ #include "chrome/browser/web_applications/manifest_update_manager.h" #include "chrome/browser/web_applications/policy/web_app_policy_constants.h" #include "chrome/browser/web_applications/policy/web_app_policy_manager.h" +#include "chrome/browser/web_applications/test/web_app_install_test_utils.h" #include "chrome/browser/web_applications/test/web_app_test_observers.h" #include "chrome/browser/web_applications/web_app_constants.h" #include "chrome/browser/web_applications/web_app_id.h" @@ -325,6 +326,8 @@ if (!delegate_->IsSyncTest()) { observation_.Observe(&GetProvider()->registrar()); } + web_app::test::WaitUntilReady( + web_app::WebAppProvider::GetForTest(browser()->profile())); } void WebAppIntegrationBrowserTestBase::TearDownOnMainThread() {
diff --git a/chrome/browser/ui/web_applications/web_app_browser_controller.cc b/chrome/browser/ui/web_applications/web_app_browser_controller.cc index f88e647..f1ce366 100644 --- a/chrome/browser/ui/web_applications/web_app_browser_controller.cc +++ b/chrome/browser/ui/web_applications/web_app_browser_controller.cc
@@ -36,6 +36,7 @@ #include "url/gurl.h" #if BUILDFLAG(IS_CHROMEOS_ASH) +#include "ash/constants/ash_features.h" #include "ash/public/cpp/style/color_provider.h" #include "chrome/browser/ash/apps/apk_web_app_service.h" @@ -225,10 +226,16 @@ return web_theme_color; #if BUILDFLAG(IS_CHROMEOS_ASH) - absl::optional<SkColor> dark_mode_color = - registrar().GetAppDarkModeThemeColor(app_id()); - if (ash::ColorProvider::Get()->IsDarkModeEnabled() && dark_mode_color) { - return dark_mode_color; + // ash::ColorProvider::Get()->IsDarkModeEnabled() flips semantics depending on + // the status of ash::Features::IsDarkLightModeEnabled(), so we have to check + // both. + if (ash::features::IsDarkLightModeEnabled()) { + absl::optional<SkColor> dark_mode_color = + registrar().GetAppDarkModeThemeColor(app_id()); + + if (ash::ColorProvider::Get()->IsDarkModeEnabled() && dark_mode_color) { + return dark_mode_color; + } } #endif
diff --git a/chrome/browser/ui/web_applications/web_app_browsertest.cc b/chrome/browser/ui/web_applications/web_app_browsertest.cc index cd680b58..37f10e8 100644 --- a/chrome/browser/ui/web_applications/web_app_browsertest.cc +++ b/chrome/browser/ui/web_applications/web_app_browsertest.cc
@@ -227,7 +227,7 @@ features::kDesktopPWAsTabStrip}; }; -// TODO(crbug.com/1257751): Stabilize the test. +// TODO(crbug.com/1175536): Stabilize the test. #if defined(OS_POSIX) #define DISABLE_POSIX(TEST) DISABLED_##TEST #else @@ -427,7 +427,7 @@ /*open_as_window=*/false)); } -IN_PROC_BROWSER_TEST_F(WebAppBrowserTest, DISABLE_POSIX(DisplayOverride)) { +IN_PROC_BROWSER_TEST_F(WebAppBrowserTest, DisplayOverride) { GURL test_url = https_server()->GetURL( "/banners/" "manifest_test_page.html?manifest=manifest_display_override.json"); @@ -867,8 +867,7 @@ } // Tests that an installed PWA is not used when out of scope by one path level. -IN_PROC_BROWSER_TEST_F(WebAppBrowserTest, - DISABLE_POSIX(MenuOptionsOutsideInstalledPwaScope)) { +IN_PROC_BROWSER_TEST_F(WebAppBrowserTest, MenuOptionsOutsideInstalledPwaScope) { NavigateToURLAndWait( browser(), https_server()->GetURL("/banners/scope_is_start_url/index.html")); @@ -884,8 +883,7 @@ kNotPresent); } -IN_PROC_BROWSER_TEST_F(WebAppBrowserTest, - DISABLE_POSIX(InstallInstallableSite)) { +IN_PROC_BROWSER_TEST_F(WebAppBrowserTest, InstallInstallableSite) { base::Time before_install_time = base::Time::Now(); base::UserActionTester user_action_tester; NavigateToURLAndWait(browser(), GetInstallableAppURL()); @@ -912,7 +910,7 @@ #endif } -IN_PROC_BROWSER_TEST_F(WebAppBrowserTest, DISABLE_POSIX(CanInstallOverTabPwa)) { +IN_PROC_BROWSER_TEST_F(WebAppBrowserTest, CanInstallOverTabPwa) { NavigateToURLAndWait(browser(), GetInstallableAppURL()); const AppId app_id = InstallPwaForCurrentUrl(); @@ -930,8 +928,7 @@ kNotPresent); } -IN_PROC_BROWSER_TEST_F(WebAppBrowserTest, - DISABLE_POSIX(CannotInstallOverWindowPwa)) { +IN_PROC_BROWSER_TEST_F(WebAppBrowserTest, CannotInstallOverWindowPwa) { NavigateToURLAndWait(browser(), GetInstallableAppURL()); InstallPwaForCurrentUrl(); @@ -1002,8 +999,7 @@ } #if defined(OS_MAC) || defined(OS_WIN) -IN_PROC_BROWSER_TEST_F(WebAppBrowserTest, - DISABLE_POSIX(ShortcutIconCorrectColor)) { +IN_PROC_BROWSER_TEST_F(WebAppBrowserTest, ShortcutIconCorrectColor) { os_hooks_suppress_.reset(); base::ScopedAllowBlockingForTesting allow_blocking; @@ -1606,7 +1602,7 @@ } IN_PROC_BROWSER_TEST_F(WebAppBrowserTest_WindowControlsOverlay, - DISABLE_POSIX(WindowControlsOverlay)) { + WindowControlsOverlay) { GURL test_url = https_server()->GetURL( "/banners/" "manifest_test_page.html?manifest=manifest_window_controls_overlay.json"); @@ -1626,8 +1622,7 @@ app_browser->app_controller()->AppUsesWindowControlsOverlay()); } -IN_PROC_BROWSER_TEST_F(WebAppBrowserTest_Tabbed, - DISABLE_POSIX(TabbedDisplayOverride)) { +IN_PROC_BROWSER_TEST_F(WebAppBrowserTest_Tabbed, TabbedDisplayOverride) { GURL test_url = https_server()->GetURL( "/banners/" "manifest_test_page.html?manifest=manifest_tabbed_display_override.json"); @@ -1653,8 +1648,7 @@ features::kRemoveStatusBarInWebApps}; }; -IN_PROC_BROWSER_TEST_F(WebAppBrowserTest_RemoveStatusBar, - DISABLE_POSIX(RemoveStatusBar)) { +IN_PROC_BROWSER_TEST_F(WebAppBrowserTest_RemoveStatusBar, RemoveStatusBar) { NavigateToURLAndWait(browser(), GetInstallableAppURL()); const AppId app_id = InstallPwaForCurrentUrl(); Browser* const app_browser = LaunchWebAppBrowser(app_id); @@ -1704,8 +1698,7 @@ blink::features::kWebAppEnableManifestId}; }; -IN_PROC_BROWSER_TEST_F(WebAppBrowserTest_ManifestId, - DISABLE_POSIX(NoManifestId)) { +IN_PROC_BROWSER_TEST_F(WebAppBrowserTest_ManifestId, NoManifestId) { NavigateToURLAndWait(browser(), GetInstallableAppURL()); const AppId app_id = InstallPwaForCurrentUrl();
diff --git a/chrome/browser/ui/web_applications/web_app_controller_browsertest.cc b/chrome/browser/ui/web_applications/web_app_controller_browsertest.cc index 1e501ac..e29d88d7 100644 --- a/chrome/browser/ui/web_applications/web_app_controller_browsertest.cc +++ b/chrome/browser/ui/web_applications/web_app_controller_browsertest.cc
@@ -201,6 +201,8 @@ cert_verifier_.mock_cert_verifier()->set_default_result(net::OK); os_hooks_suppress_ = OsIntegrationManager::ScopedSuppressOsHooksForTesting(); + web_app::test::WaitUntilReady( + web_app::WebAppProvider::GetForTest(browser()->profile())); } } // namespace web_app
diff --git a/chrome/browser/ui/web_applications/web_app_launch_manager.cc b/chrome/browser/ui/web_applications/web_app_launch_manager.cc index 59497f1..7347edb 100644 --- a/chrome/browser/ui/web_applications/web_app_launch_manager.cc +++ b/chrome/browser/ui/web_applications/web_app_launch_manager.cc
@@ -177,16 +177,15 @@ const apps::ShareTarget* MaybeGetShareTarget() const; std::tuple<GURL, bool /*is_file_handling*/> GetLaunchUrl( const apps::ShareTarget* share_target) const; - WindowOpenDisposition GetNavigationDisposition() const; + WindowOpenDisposition GetNavigationDisposition(bool is_new_browser) const; content::WebContents* MaybeLaunchSystemWebApp(const GURL& launch_url); - std::tuple<Browser*, WindowOpenDisposition> EnsureBrowser(); + std::tuple<Browser*, bool /*is_new_browser*/> EnsureBrowser(); Browser* MaybeFindBrowserForLaunch() const; Browser* CreateBrowserForLaunch(); - content::WebContents* NavigateBrowser( - Browser* browser, - const GURL& launch_url, - WindowOpenDisposition navigation_disposition, - const apps::ShareTarget* share_target); + content::WebContents* NavigateBrowser(Browser* browser, + bool is_new_browser, + const GURL& launch_url, + const apps::ShareTarget* share_target); void MaybeEnqueueWebLaunchParams(const GURL& launch_url, bool is_file_handling, content::WebContents* web_contents); @@ -228,11 +227,11 @@ return web_contents; Browser* browser = nullptr; - WindowOpenDisposition navigation_disposition; - std::tie(browser, navigation_disposition) = EnsureBrowser(); + bool is_new_browser; + std::tie(browser, is_new_browser) = EnsureBrowser(); - web_contents = NavigateBrowser(browser, launch_url, navigation_disposition, - share_target); + web_contents = + NavigateBrowser(browser, is_new_browser, launch_url, share_target); if (!web_contents) return nullptr; @@ -295,7 +294,21 @@ return {launch_url, is_file_handling}; } -WindowOpenDisposition LaunchProcess::GetNavigationDisposition() const { +WindowOpenDisposition LaunchProcess::GetNavigationDisposition( + bool is_new_browser) const { + if (is_new_browser) { + // By opening a new window we've already performed part of a "disposition", + // the only remaining thing for Navigate() to do is navigate the new window. + return WindowOpenDisposition::CURRENT_TAB; + // TODO(crbug.com/1200944): Use NEW_FOREGROUND_TAB instead of CURRENT_TAB. + // The window has no tabs so it doesn't make sense to open the "current" + // tab. We use it anyway because it happens to work. + // If NEW_FOREGROUND_TAB is used the the WindowCanOpenTabs() check fails + // when `launch_url` is out of scope for web app windows causing it to + // open another separate browser window. It should be updated to check the + // extended scope. + } + // Only CURRENT_TAB and NEW_FOREGROUND_TAB dispositions are supported for web // app launches. return params_.disposition == WindowOpenDisposition::CURRENT_TAB @@ -315,26 +328,17 @@ return browser->tab_strip_model()->GetActiveWebContents(); } -std::tuple<Browser*, WindowOpenDisposition> LaunchProcess::EnsureBrowser() { +std::tuple<Browser*, bool /*is_new_browser*/> LaunchProcess::EnsureBrowser() { Browser* browser = MaybeFindBrowserForLaunch(); - WindowOpenDisposition navigation_disposition = GetNavigationDisposition(); + bool is_new_browser = false; if (browser) { browser->window()->Activate(); } else { browser = CreateBrowserForLaunch(); - // By opening a new window we've already performed part of a "disposition", - // the only remaining thing for Navigate() to do is navigate the new window. - navigation_disposition = WindowOpenDisposition::CURRENT_TAB; - // TODO(crbug.com/1200944): Use NEW_FOREGROUND_TAB instead of CURRENT_TAB. - // The window has no tabs so it doesn't make sense to open the "current" - // tab. We use it anyway because it happens to work. - // If NEW_FOREGROUND_TAB is used the the WindowCanOpenTabs() check fails - // when `launch_url` is out of scope for web app windows causing it to - // open another separate browser window. It should be updated to check the - // extended scope. + is_new_browser = true; } browser->window()->Show(); - return {browser, navigation_disposition}; + return {browser, is_new_browser}; } Browser* LaunchProcess::MaybeFindBrowserForLaunch() const { @@ -373,9 +377,12 @@ content::WebContents* LaunchProcess::NavigateBrowser( Browser* browser, + bool is_new_browser, const GURL& launch_url, - WindowOpenDisposition navigation_disposition, const apps::ShareTarget* share_target) { + WindowOpenDisposition navigation_disposition = + GetNavigationDisposition(is_new_browser); + if (share_target) { NavigateParams nav_params = NavigateParamsForShareTarget(browser, *share_target, *params_.intent);
diff --git a/chrome/browser/ui/web_applications/web_app_ui_manager_impl_browsertest.cc b/chrome/browser/ui/web_applications/web_app_ui_manager_impl_browsertest.cc index 6e3d073..c0e48fe 100644 --- a/chrome/browser/ui/web_applications/web_app_ui_manager_impl_browsertest.cc +++ b/chrome/browser/ui/web_applications/web_app_ui_manager_impl_browsertest.cc
@@ -45,6 +45,13 @@ base::Unretained(this))) {} protected: + // InProcessBrowserTest: + void SetUpOnMainThread() override { + InProcessBrowserTest::SetUpOnMainThread(); + web_app::test::WaitUntilReady( + web_app::WebAppProvider::GetForTest(browser()->profile())); + } + Profile* profile() { return browser()->profile(); } const AppId InstallWebApp(const GURL& start_url) {
diff --git a/chrome/browser/ui/webui/settings/chromeos/os_apps_page/app_notification_handler_unittest.cc b/chrome/browser/ui/webui/settings/chromeos/os_apps_page/app_notification_handler_unittest.cc index b54a2f6..28d0f32 100644 --- a/chrome/browser/ui/webui/settings/chromeos/os_apps_page/app_notification_handler_unittest.cc +++ b/chrome/browser/ui/webui/settings/chromeos/os_apps_page/app_notification_handler_unittest.cc
@@ -125,13 +125,12 @@ std::string fake_id, apps::mojom::AppType app_type, apps::mojom::PermissionType permission_type, - apps::mojom::PermissionValueType permission_value_type, - uint32_t permission_value = 1) { + bool permission_value = true) { std::vector<apps::mojom::PermissionPtr> fake_permissions; apps::mojom::PermissionPtr fake_permission = apps::mojom::Permission::New(); fake_permission->permission_type = permission_type; - fake_permission->value_type = permission_value_type; - fake_permission->value = /*True=*/permission_value; + fake_permission->value = apps::mojom::PermissionValue::New(); + fake_permission->value->set_bool_value(permission_value); fake_permission->is_managed = false; fake_permissions.push_back(fake_permission.Clone()); @@ -205,69 +204,66 @@ TEST_F(AppNotificationHandlerTest, TestAppListUpdated) { CreateAndStoreFakeApp("arcAppWithNotifications", apps::mojom::AppType::kArc, apps::mojom::PermissionType::kNotifications, - apps::mojom::PermissionValueType::kBool, - /*permission_value=*/1); + /*permission_value=*/true); base::RunLoop().RunUntilIdle(); EXPECT_EQ(observer()->app_list_changed(), 1); EXPECT_EQ("arcAppWithNotifications", observer()->recently_updated_app()->id); - EXPECT_EQ(1, - observer()->recently_updated_app()->notification_permission->value); + EXPECT_TRUE(observer() + ->recently_updated_app() + ->notification_permission->value->get_bool_value()); CreateAndStoreFakeApp("webAppWithNotifications", apps::mojom::AppType::kWeb, apps::mojom::PermissionType::kNotifications, - apps::mojom::PermissionValueType::kBool, - /*permission_value=*/1); + /*permission_value=*/true); base::RunLoop().RunUntilIdle(); EXPECT_EQ(observer()->app_list_changed(), 2); EXPECT_EQ("webAppWithNotifications", observer()->recently_updated_app()->id); - EXPECT_EQ(1, - observer()->recently_updated_app()->notification_permission->value); + EXPECT_TRUE(observer() + ->recently_updated_app() + ->notification_permission->value->get_bool_value()); CreateAndStoreFakeApp("arcAppWithCamera", apps::mojom::AppType::kArc, - apps::mojom::PermissionType::kCamera, - apps::mojom::PermissionValueType::kBool); + apps::mojom::PermissionType::kCamera); base::RunLoop().RunUntilIdle(); EXPECT_EQ(observer()->app_list_changed(), 2); CreateAndStoreFakeApp("webAppWithGeolocation", apps::mojom::AppType::kWeb, - apps::mojom::PermissionType::kLocation, - apps::mojom::PermissionValueType::kBool); + apps::mojom::PermissionType::kLocation); base::RunLoop().RunUntilIdle(); EXPECT_EQ(observer()->app_list_changed(), 2); CreateAndStoreFakeApp("pluginVmAppWithPrinting", apps::mojom::AppType::kPluginVm, - apps::mojom::PermissionType::kPrinting, - apps::mojom::PermissionValueType::kBool); + apps::mojom::PermissionType::kPrinting); base::RunLoop().RunUntilIdle(); EXPECT_EQ(observer()->app_list_changed(), 2); CreateAndStoreFakeApp("arcAppWithNotifications", apps::mojom::AppType::kArc, apps::mojom::PermissionType::kNotifications, - apps::mojom::PermissionValueType::kBool, - /*permission_value=*/0); + /*permission_value=*/false); base::RunLoop().RunUntilIdle(); EXPECT_EQ(observer()->app_list_changed(), 3); EXPECT_EQ("arcAppWithNotifications", observer()->recently_updated_app()->id); - EXPECT_EQ(0, - observer()->recently_updated_app()->notification_permission->value); + EXPECT_FALSE(observer() + ->recently_updated_app() + ->notification_permission->value->get_bool_value()); CreateAndStoreFakeApp("webAppWithNotifications", apps::mojom::AppType::kWeb, apps::mojom::PermissionType::kNotifications, - apps::mojom::PermissionValueType::kBool, - /*permission_value=*/0); + /*permission_value=*/false); base::RunLoop().RunUntilIdle(); EXPECT_EQ(observer()->app_list_changed(), 4); EXPECT_EQ("webAppWithNotifications", observer()->recently_updated_app()->id); - EXPECT_EQ(0, - observer()->recently_updated_app()->notification_permission->value); + EXPECT_FALSE(observer() + ->recently_updated_app() + ->notification_permission->value->get_bool_value()); } TEST_F(AppNotificationHandlerTest, TestNotifyPageReady) {
diff --git a/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc b/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc index 6ec6ef29..ffc2340 100644 --- a/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc +++ b/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc
@@ -320,8 +320,8 @@ auto permission = apps::mojom::Permission::New(); permission->permission_type = GetPermissionType(type); - permission->value_type = apps::mojom::PermissionValueType::kTriState; - permission->value = static_cast<uint32_t>(setting_val); + permission->value = apps::mojom::PermissionValue::New(); + permission->value->set_tristate_value(setting_val); permission->is_managed = setting_info.source == content_settings::SETTING_SOURCE_POLICY; @@ -704,10 +704,9 @@ return; } - DCHECK_EQ(permission->value_type, - apps::mojom::PermissionValueType::kTriState); + DCHECK(permission->value->is_tristate_value()); ContentSetting permission_value = CONTENT_SETTING_DEFAULT; - switch (static_cast<apps::mojom::TriState>(permission->value)) { + switch (permission->value->get_tristate_value()) { case apps::mojom::TriState::kAllow: permission_value = CONTENT_SETTING_ALLOW; break;
diff --git a/chrome/browser/web_applications/app_service/web_apps_publisher_host_browsertest.cc b/chrome/browser/web_applications/app_service/web_apps_publisher_host_browsertest.cc index f0268872..69da02b 100644 --- a/chrome/browser/web_applications/app_service/web_apps_publisher_host_browsertest.cc +++ b/chrome/browser/web_applications/app_service/web_apps_publisher_host_browsertest.cc
@@ -339,10 +339,9 @@ apps::mojom::PermissionType::kCamera; }); ASSERT_TRUE(camera_permission != permissions.end()); - EXPECT_EQ((*camera_permission)->value_type, - apps::mojom::PermissionValueType::kTriState); - EXPECT_EQ((*camera_permission)->value, - static_cast<uint32_t>(apps::mojom::TriState::kAllow)); + EXPECT_TRUE((*camera_permission)->value->is_tristate_value()); + EXPECT_EQ((*camera_permission)->value->get_tristate_value(), + apps::mojom::TriState::kAllow); } IN_PROC_BROWSER_TEST_F(WebAppsPublisherHostBrowserTest, MediaRequest) {
diff --git a/chrome/browser/web_applications/manifest_update_manager_browsertest.cc b/chrome/browser/web_applications/manifest_update_manager_browsertest.cc index 4ef235a5..cceed3a 100644 --- a/chrome/browser/web_applications/manifest_update_manager_browsertest.cc +++ b/chrome/browser/web_applications/manifest_update_manager_browsertest.cc
@@ -31,6 +31,7 @@ #include "chrome/browser/web_applications/os_integration_manager.h" #include "chrome/browser/web_applications/system_web_apps/test/test_system_web_app_installation.h" #include "chrome/browser/web_applications/test/web_app_icon_test_utils.h" +#include "chrome/browser/web_applications/test/web_app_install_test_utils.h" #include "chrome/browser/web_applications/test/web_app_sync_test_utils.h" #include "chrome/browser/web_applications/test/web_app_test.h" #include "chrome/browser/web_applications/test/web_app_test_observers.h" @@ -228,6 +229,8 @@ void SetUpOnMainThread() override { // Cannot construct RunLoop in constructor due to threading restrictions. shortcut_run_loop_.emplace(); + web_app::test::WaitUntilReady( + web_app::WebAppProvider::GetForTest(browser()->profile())); } void OnShortcutInfoRetrieved(std::unique_ptr<ShortcutInfo> shortcut_info) {
diff --git a/chrome/browser/web_applications/preinstalled_web_app_manager_browsertest.cc b/chrome/browser/web_applications/preinstalled_web_app_manager_browsertest.cc index 6a80099..bff4b20 100644 --- a/chrome/browser/web_applications/preinstalled_web_app_manager_browsertest.cc +++ b/chrome/browser/web_applications/preinstalled_web_app_manager_browsertest.cc
@@ -24,6 +24,7 @@ #include "chrome/browser/web_applications/test/fake_os_integration_manager.h" #include "chrome/browser/web_applications/test/test_file_utils.h" #include "chrome/browser/web_applications/test/web_app_icon_test_utils.h" +#include "chrome/browser/web_applications/test/web_app_install_test_utils.h" #include "chrome/browser/web_applications/web_app.h" #include "chrome/browser/web_applications/web_app_helpers.h" #include "chrome/browser/web_applications/web_app_provider.h" @@ -136,6 +137,12 @@ PreinstalledWebAppManager::SkipStartupForTesting(); } + // InProcessBrowserTest: + void SetUpOnMainThread() override { + InProcessBrowserTest::SetUpOnMainThread(); + web_app::test::WaitUntilReady( + web_app::WebAppProvider::GetForTest(browser()->profile())); + } void TearDownOnMainThread() override { ResetInterceptor(); InProcessBrowserTest::TearDownOnMainThread(); @@ -418,6 +425,11 @@ PreinstalledWebAppManagerExtensionBrowserTest() = default; ~PreinstalledWebAppManagerExtensionBrowserTest() override = default; + void SetUpOnMainThread() override { + extensions::ExtensionBrowserTest::SetUpOnMainThread(); + web_app::test::WaitUntilReady( + web_app::WebAppProvider::GetForTest(browser()->profile())); + } void TearDownOnMainThread() override { ResetInterceptor(); extensions::ExtensionBrowserTest::TearDownOnMainThread();
diff --git a/chrome/browser/web_applications/web_app_icon_downloader.cc b/chrome/browser/web_applications/web_app_icon_downloader.cc index 348f905..5c9a3eb 100644 --- a/chrome/browser/web_applications/web_app_icon_downloader.cc +++ b/chrome/browser/web_applications/web_app_icon_downloader.cc
@@ -41,7 +41,8 @@ void WebAppIconDownloader::Start() { // Favicons are supported only in HTTP or HTTPS WebContents. - if (!web_contents()->GetLastCommittedURL().SchemeIsHTTPOrHTTPS()) + const GURL& url = web_contents()->GetLastCommittedURL(); + if (!url.is_empty() && !url.inner_url() && !url.SchemeIsHTTPOrHTTPS()) SkipPageFavicons(); // If the candidates aren't loaded, icons will be fetched when
diff --git a/chrome/browser/web_applications/web_app_mover_browsertest.cc b/chrome/browser/web_applications/web_app_mover_browsertest.cc index 801412b..08c6928 100644 --- a/chrome/browser/web_applications/web_app_mover_browsertest.cc +++ b/chrome/browser/web_applications/web_app_mover_browsertest.cc
@@ -9,6 +9,7 @@ #include "base/test/scoped_feature_list.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/web_applications/os_integration_manager.h" +#include "chrome/browser/web_applications/test/web_app_install_test_utils.h" #include "chrome/browser/web_applications/test/web_app_test.h" #include "chrome/browser/web_applications/test/web_app_test_utils.h" #include "chrome/browser/web_applications/web_app_helpers.h" @@ -51,6 +52,13 @@ ~WebAppMoverBrowsertestBase() override = default; protected: + // InProcessBrowserTest: + void SetUpOnMainThread() override { + InProcessBrowserTest::SetUpOnMainThread(); + web_app::test::WaitUntilReady( + web_app::WebAppProvider::GetForTest(browser()->profile())); + } + GURL GetMigratingFromAppA() { return embedded_test_server()->GetURL( "/web_apps/mover/migrate_from/a/index.html");
diff --git a/chrome/browser/xsurface/android/java/src/org/chromium/chrome/browser/xsurface/FeedActionsHandler.java b/chrome/browser/xsurface/android/java/src/org/chromium/chrome/browser/xsurface/FeedActionsHandler.java index 0e28809..1aa05e9 100644 --- a/chrome/browser/xsurface/android/java/src/org/chromium/chrome/browser/xsurface/FeedActionsHandler.java +++ b/chrome/browser/xsurface/android/java/src/org/chromium/chrome/browser/xsurface/FeedActionsHandler.java
@@ -117,4 +117,11 @@ * Opens the settings to manager autoplay. */ default void openAutoplaySettings() {} + + /** + * Tracks the interaction, i.e. viewed/clicked, state of a card specific notice. + * @param key Key to identify the type of the notice. + * @param data A serialized ContentId protobuf message. + */ + default void trackInteractionForNotice(String key, byte[] data) {} }
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index 4b9111a..8d3c936 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-main-1633975157-70b540de0293ec8e4308ac55c767c2b80cb02bc7.profdata +chrome-linux-main-1633996760-4c081f0e822b7bfe51ac50ea0226a61779e53fea.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index 64f4c018..b145b4f 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-main-1633975157-aa36f13d6fbb11046f40b07a1281b0acd069c0df.profdata +chrome-mac-main-1634018394-7d049de9168eebccc73c1f52f17c3554f041aee4.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index a91da5c0..1215d18 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1633985928-8976cc68b02f6ef4f34ada6121a0c67c1f80db29.profdata +chrome-win32-main-1634007276-255923810f65f018d6e74d98f2eec5dd8022a181.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index f8ea82eb..e14929d 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1633975157-6e01b9278dd15cb5b5d387ee549aea30551eac75.profdata +chrome-win64-main-1634007276-7a6d9187b564ade39002b683418de3fe62e4980e.profdata
diff --git a/chrome/common/extensions/api/terminal_private.json b/chrome/common/extensions/api/terminal_private.json index ce805c6..ee39739 100644 --- a/chrome/common/extensions/api/terminal_private.json +++ b/chrome/common/extensions/api/terminal_private.json
@@ -177,12 +177,20 @@ "name": "openWindow", "type": "function", "description": "Open the Terminal tabbed window.", - "parameters": [], - "returns_async": { - "name": "callback", - "description": "Callback that will be called when complete.", - "parameters": [] - } + "parameters": [ + { + "name": "data", + "type": "object", + "optional": true, + "properties": { + "url": { + "description": "The url for the new Terminal window.", + "optional": true, + "type": "string" + } + } + } + ] }, { "name": "openOptionsPage",
diff --git a/chrome/renderer/cart/commerce_hint_agent.cc b/chrome/renderer/cart/commerce_hint_agent.cc index 5f52a3d..272693f0 100644 --- a/chrome/renderer/cart/commerce_hint_agent.cc +++ b/chrome/renderer/cart/commerce_hint_agent.cc
@@ -730,6 +730,7 @@ return; } is_extraction_pending_ = true; + extraction_count_++; DVLOG(1) << "Scheduled extraction"; base::SequencedTaskRunnerHandle::Get()->PostDelayedTask( FROM_HERE, @@ -739,16 +740,16 @@ } void CommerceHintAgent::ExtractProducts() { - is_extraction_pending_ = false; if (is_extraction_running_) { DVLOG(1) << "Extraction is running. Try again later."; base::SequencedTaskRunnerHandle::Get()->PostDelayedTask( FROM_HERE, - base::BindOnce(&CommerceHintAgent::MaybeExtractProducts, + base::BindOnce(&CommerceHintAgent::ExtractProducts, weak_factory_.GetWeakPtr()), kCartExtractionGapTime.Get()); return; } + is_extraction_pending_ = false; is_extraction_running_ = true; DVLOG(2) << "is_extraction_running_ = " << is_extraction_running_; @@ -898,7 +899,6 @@ OnCartProductUpdated(render_frame(), std::move(products)); is_extraction_running_ = false; - extraction_count_++; DVLOG(2) << "is_extraction_running_ = " << is_extraction_running_; }
diff --git a/chrome/renderer/cart/commerce_hint_agent_browsertest.cc b/chrome/renderer/cart/commerce_hint_agent_browsertest.cc index 9d8ce3d..eb7fdf8a 100644 --- a/chrome/renderer/cart/commerce_hint_agent_browsertest.cc +++ b/chrome/renderer/cart/commerce_hint_agent_browsertest.cc
@@ -242,7 +242,7 @@ run_loop.Run(); if (satisfied_) break; - base::PlatformThread::Sleep(TestTimeouts::tiny_timeout()); + base::PlatformThread::Sleep(TestTimeouts::tiny_timeout() * 10); } } @@ -263,8 +263,8 @@ expected[i].second.merchant_cart_url()); } } else { - VLOG(3) << "Found " << found.size() << " but expecting " - << expected.size(); + LOG(INFO) << "WaitForCartCount() is expecting " << expected.size() + << " but found " << found.size(); } std::move(closure).Run(); } @@ -280,7 +280,7 @@ run_loop.Run(); if (satisfied_) break; - base::PlatformThread::Sleep(TestTimeouts::tiny_timeout()); + base::PlatformThread::Sleep(TestTimeouts::tiny_timeout() * 10); } } @@ -299,6 +299,9 @@ .ReplaceComponents(remove_port) .spec() == expected[i].second.merchant_cart_url(); } + } else { + LOG(INFO) << "WaitForCarts() is expecting " << expected.size() + << " but found " << found.size(); } std::move(closure).Run(); } @@ -314,7 +317,7 @@ run_loop.Run(); if (satisfied_) break; - base::PlatformThread::Sleep(TestTimeouts::tiny_timeout()); + base::PlatformThread::Sleep(TestTimeouts::tiny_timeout() * 10); } } @@ -324,8 +327,11 @@ ShoppingCarts found) { bool fail = false; bool same_size = found.size() == expected.size(); - if (!same_size) + if (!same_size) { fail = true; + LOG(INFO) << "WaitForProductCount() is expecting " << expected.size() + << " but found " << found.size(); + } for (size_t i = 0; i < std::min(found.size(), expected.size()); i++) { EXPECT_EQ(found[i].first, expected[i].first); GURL::Replacements remove_port; @@ -846,7 +852,8 @@ void SetUpInProcessBrowserTestFixture() override { scoped_feature_list_.InitWithFeaturesAndParameters( {{ntp_features::kNtpChromeCartModule, - {{"cart-extraction-timeout", "0"}}}}, + {{"cart-extraction-max-count", "1"}, + {"cart-extraction-timeout", "0"}}}}, {optimization_guide::features::kOptimizationHints}); } @@ -882,9 +889,7 @@ base::test::ScopedFeatureList scoped_feature_list_; }; -// Flaky on Linux: https://crbug.com/1257964. -// See definition of MAYBE_ExtractCart above. -IN_PROC_BROWSER_TEST_F(CommerceHintMaxCountTest, MAYBE_ExtractCart) { +IN_PROC_BROWSER_TEST_F(CommerceHintMaxCountTest, ExtractCart) { NavigateToURL("https://www.guitarcenter.com/cart.html"); WaitForUmaBucketCount("Commerce.Carts.ExtractionTimedOut", 0, 1);
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index da621592..92978c0 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -1053,6 +1053,7 @@ "//chrome/browser:theme_properties", "//chrome/browser/apps/app_service:test_support", "//chrome/browser/browsing_data:constants", + "//chrome/browser/commerce:feature_list", "//chrome/browser/continuous_search:browser_tests", "//chrome/browser/devtools", "//chrome/browser/devtools:test_support", @@ -1467,6 +1468,7 @@ "../browser/browsing_data/third_party_data_remover_browsertest.cc", "../browser/capability_delegation_browsertest.cc", "../browser/cart/cart_service_browsertest.cc", + "../browser/cart/fetch_discount_worker_browsertest.cc", "../browser/chrome_back_forward_cache_browsertest.cc", "../browser/chrome_content_browser_client_browsertest.cc", "../browser/chrome_do_not_track_browsertest.cc", @@ -2734,7 +2736,7 @@ "//components/keep_alive_registry", "//components/media_router/browser:test_support", "//components/media_router/common:test_support", - "//components/web_package:test_support", + "//components/web_package", "//google_apis/common:test_support", "//google_apis/drive",
diff --git a/chrome/test/data/cart/coupons/fl_codeless_discounts.json b/chrome/test/data/cart/coupons/fl_codeless_discounts.json new file mode 100644 index 0000000..af626c2d --- /dev/null +++ b/chrome/test/data/cart/coupons/fl_codeless_discounts.json
@@ -0,0 +1,35 @@ +{ + "discounts": [ + // Use case for: + // * FetchFLCodelessDiscountWorkerBrowserTest.SimplePercentOffTest + // * FetchFLCodelessDiscountWorkerBrowserTest.TwoCartsOneWithDiscountOneWithoutDiscount + { + "merchantIdentifier": { + "cartUrl": "https://www.merchant1.com/cart", + "merchantId": "10046" + }, + "couponDiscounts": [{ + "type": "FREE_LISTING_WITHOUT_CODE" + }], + "overallDiscountInfo": { + "text": "10% off", + "languageCode": "en-US" + } + }, + // Use case for FetchFLCodelessDiscountWorkerBrowserTest.SimpleDollarOffTest + { + "merchantIdentifier": { + "cartUrl": "https://www.merchant2.com/cart", + "merchantId": "10046" + }, + "couponDiscounts": [{ + "type": "FREE_LISTING_WITHOUT_CODE" + }], + "overallDiscountInfo": { + "text": "$2 off", + "languageCode": "en-US" + } + } + // cartUrl needs to be unique. Next cartUrl is https://www.merchant3.com/cart. + ] +} \ No newline at end of file
diff --git a/chrome/test/data/cart/coupons/fl_codeless_discounts.json.mock-http-headers b/chrome/test/data/cart/coupons/fl_codeless_discounts.json.mock-http-headers new file mode 100644 index 0000000..fb7791b --- /dev/null +++ b/chrome/test/data/cart/coupons/fl_codeless_discounts.json.mock-http-headers
@@ -0,0 +1,2 @@ +HTTP/1.1 200 OK +Content-Type: application/json; charset=utf-8 \ No newline at end of file
diff --git a/chrome/test/data/webui/settings/chromeos/app_management/borealis_detail_view_test.js b/chrome/test/data/webui/settings/chromeos/app_management/borealis_detail_view_test.js index f5cef8bc..10b4467a 100644 --- a/chrome/test/data/webui/settings/chromeos/app_management/borealis_detail_view_test.js +++ b/chrome/test/data/webui/settings/chromeos/app_management/borealis_detail_view_test.js
@@ -5,7 +5,7 @@ // clang-format off // #import 'chrome://os-settings/chromeos/os_settings.js'; -// #import {PermissionType, createPermission, PermissionValueType, Bool, AppManagementStore, updateSelectedAppId, getPermissionValueBool, convertOptionalBoolToBool} from 'chrome://os-settings/chromeos/os_settings.js'; +// #import {PermissionType, createBoolPermission, AppManagementStore, updateSelectedAppId, getPermissionValueBool, convertOptionalBoolToBool} from 'chrome://os-settings/chromeos/os_settings.js'; // #import {setupFakeHandler, replaceStore, replaceBody, getPermissionCrToggleByType, getPermissionToggleByType} from './test_util.m.js'; // #import {eventToPromise, flushTasks} from 'chrome://test/test_util.js'; // #import {Router, routes, Route} from 'chrome://os-settings/chromeos/os_settings.js'; @@ -41,9 +41,8 @@ const permissions = {}; const permissionTypes = [PermissionType.kMicrophone]; for (const permissionType of permissionTypes) { - permissions[permissionType] = app_management.util.createPermission( - permissionType, PermissionValueType.kBool, Bool.kTrue, - false /*is_managed*/); + permissions[permissionType] = createBoolPermission( + permissionType, true /*permission_value*/, false /*is_managed*/); } // Add main app, and make it the currently selected app.
diff --git a/chrome/test/data/webui/settings/chromeos/app_management/managed_apps_test.js b/chrome/test/data/webui/settings/chromeos/app_management/managed_apps_test.js index 8525b22..be44b71 100644 --- a/chrome/test/data/webui/settings/chromeos/app_management/managed_apps_test.js +++ b/chrome/test/data/webui/settings/chromeos/app_management/managed_apps_test.js
@@ -5,7 +5,7 @@ // clang-format off // #import 'chrome://os-settings/chromeos/os_settings.js'; -// #import {PermissionType, TriState, FakePageHandler, AppManagementStore, updateSelectedAppId} from 'chrome://os-settings/chromeos/os_settings.js'; +// #import {PermissionType, TriState, FakePageHandler, AppManagementStore, updateSelectedAppId, createTriStatePermission} from 'chrome://os-settings/chromeos/os_settings.js'; // #import {flushTasks} from 'chrome://test/test_util.js'; // #import {setupFakeHandler, replaceStore, replaceBody, getPermissionToggleByType } from './test_util.m.js'; // clang-format on @@ -23,14 +23,10 @@ // Create a Web app which is installed and pinned by policy // and has location set to on and camera set to off by policy. const permissionOptions = {}; - permissionOptions[PermissionType.kLocation] = { - permissionValue: TriState.kAllow, - isManaged: true, - }; - permissionOptions[PermissionType.kCamera] = { - permissionValue: TriState.kBlock, - isManaged: true - }; + permissionOptions[PermissionType.kLocation] = createTriStatePermission( + PermissionType.kLocation, TriState.kAllow, /*isManaged*/ true); + permissionOptions[PermissionType.kCamera] = createTriStatePermission( + PermissionType.kCamera, TriState.kBlock, /*isManaged*/ true); const policyAppOptions = { type: apps.mojom.AppType.kWeb, isPinned: apps.mojom.OptionalBool.kTrue,
diff --git a/chrome/test/data/webui/settings/chromeos/app_management/plugin_vm_detail_view_test.js b/chrome/test/data/webui/settings/chromeos/app_management/plugin_vm_detail_view_test.js index 6b1afc4..8023d6a 100644 --- a/chrome/test/data/webui/settings/chromeos/app_management/plugin_vm_detail_view_test.js +++ b/chrome/test/data/webui/settings/chromeos/app_management/plugin_vm_detail_view_test.js
@@ -5,7 +5,7 @@ // clang-format off // #import 'chrome://os-settings/chromeos/os_settings.js'; -// #import {PluginVmBrowserProxyImpl, PermissionType, createPermission, PermissionValueType, Bool, AppManagementStore, updateSelectedAppId, getPermissionValueBool, convertOptionalBoolToBool} from 'chrome://os-settings/chromeos/os_settings.js'; +// #import {PluginVmBrowserProxyImpl, PermissionType, createBoolPermission, AppManagementStore, updateSelectedAppId, getPermissionValueBool, convertOptionalBoolToBool} from 'chrome://os-settings/chromeos/os_settings.js'; // #import {TestPluginVmBrowserProxy} from './test_plugin_vm_browser_proxy.m.js'; // #import {setupFakeHandler, replaceStore, replaceBody, getPermissionCrToggleByType, getPermissionToggleByType} from './test_util.m.js'; // clang-format on @@ -123,9 +123,8 @@ PermissionType.kMicrophone, ]; for (const permissionType of permissionTypes) { - permissions[permissionType] = app_management.util.createPermission( - permissionType, PermissionValueType.kBool, Bool.kTrue, - false /*is_managed*/); + permissions[permissionType] = + createBoolPermission(permissionType, true, false /*is_managed*/); } pluginVmBrowserProxy.pluginVmRunning = false;
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 bd59f6c..9e74e37 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
@@ -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 {setAppNotificationProviderForTesting} from 'chrome://os-settings/chromeos/os_settings.js'; +import {createBoolPermission, getBoolPermissionValue, isBoolValue, setAppNotificationProviderForTesting} from 'chrome://os-settings/chromeos/os_settings.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {PromiseResolver} from 'chrome://resources/js/promise_resolver.m.js'; import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; @@ -221,22 +221,6 @@ } /** - * @param {!apps.mojom.PermissionType} permissionType - * @param {!apps.mojom.PermissionValueType} value_type - * @param {number} value - * @param {boolean} is_managed - * @return {!apps.mojom.Permission} - */ - function createPermission(permissionType, value_type, value, is_managed) { - return { - permissionType: permissionType, - valueType: value_type, - value: value, - isManaged: is_managed - }; - } - - /** * @param {string} id * @param {string} title * @param {!apps.mojom.Permission} permission @@ -254,12 +238,12 @@ } test('loadAppListAndClickToggle', async () => { - const permission1 = createPermission( - /**permissionType=*/ 1, /**value_type=*/ 0, - /**value=*/ 0, /**is_managed=*/ false); - const permission2 = createPermission( - /**permissionType=*/ 2, /**value_type=*/ 0, - /**value=*/ 1, /**is_managed=*/ false); + const permission1 = createBoolPermission( + /**permissionType=*/ 1, + /**value=*/ false, /**is_managed=*/ false); + const permission2 = createBoolPermission( + /**permissionType=*/ 2, + /**value=*/ true, /**is_managed=*/ false); const app1 = createApp('1', 'App1', permission1); const app2 = createApp('2', 'App2', permission2); @@ -292,18 +276,18 @@ assertEquals('1', mojoApi_.getLastUpdatedAppId()); const lastUpdatedPermission = mojoApi_.getLastUpdatedPermission(); assertEquals(1, lastUpdatedPermission.permissionType); - assertEquals(0, lastUpdatedPermission.valueType); + assertTrue(isBoolValue(lastUpdatedPermission.value)); assertEquals(false, lastUpdatedPermission.isManaged); - assertEquals(1, lastUpdatedPermission.value); + assertTrue(getBoolPermissionValue(lastUpdatedPermission.value)); }); test('RemovedApp', async () => { - const permission1 = createPermission( - /**permissionType=*/ 1, /**value_type=*/ 0, - /**value=*/ 0, /**is_managed=*/ false); - const permission2 = createPermission( - /**permissionType=*/ 2, /**value_type=*/ 0, - /**value=*/ 1, /**is_managed=*/ false); + const permission1 = createBoolPermission( + /**permissionType=*/ 1, + /**value=*/ false, /**is_managed=*/ false); + const permission2 = createBoolPermission( + /**permissionType=*/ 2, + /**value=*/ true, /**is_managed=*/ false); const app1 = createApp('1', 'App1', permission1); const app2 = createApp('2', 'App2', permission2); @@ -334,12 +318,12 @@ test('Each app-notification-row displays correctly', async () => { const appTitle1 = 'Files'; const appTitle2 = 'Chrome'; - const permission1 = createPermission( - /**permissionType=*/ 1, /**value_type=*/ 0, - /**value=*/ 0, /**is_managed=*/ true); - const permission2 = createPermission( - /**permissionType=*/ 2, /**value_type=*/ 0, - /**value=*/ 1, /**is_managed=*/ false); + const permission1 = createBoolPermission( + /**permissionType=*/ 1, + /**value=*/ false, /**is_managed=*/ true); + const permission2 = createBoolPermission( + /**permissionType=*/ 2, + /**value=*/ true, /**is_managed=*/ false); const app1 = createApp('file-id', appTitle1, permission1); const app2 = createApp('chrome-id', appTitle2, permission2);
diff --git a/chrome/test/data/webui/settings/chromeos/apps_page_test.js b/chrome/test/data/webui/settings/chromeos/apps_page_test.js index ef6bd8a..ece55ab 100644 --- a/chrome/test/data/webui/settings/chromeos/apps_page_test.js +++ b/chrome/test/data/webui/settings/chromeos/apps_page_test.js
@@ -7,7 +7,7 @@ // #import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; // #import {PromiseResolver} from 'chrome://resources/js/promise_resolver.m.js'; -// #import {AndroidAppsBrowserProxyImpl, Router, routes, setAppNotificationProviderForTesting} from 'chrome://os-settings/chromeos/os_settings.js'; +// #import {AndroidAppsBrowserProxyImpl, Router, routes, setAppNotificationProviderForTesting, createBoolPermission} from 'chrome://os-settings/chromeos/os_settings.js'; // #import {TestAndroidAppsBrowserProxy} from './test_android_apps_browser_proxy.m.js'; // #import {flush} from'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; // #import {waitAfterNextRender, flushTasks} from 'chrome://test/test_util.js'; @@ -192,22 +192,6 @@ let mojoApi_; /** - * @param {number} id - * @param {!apps.mojom.PermissionValueType} value_type - * @param {number} value - * @param {boolean} is_managed - * @return {!apps.mojom.Permission} - */ - function createPermission(id, value_type, value, is_managed) { - return { - permissionId: id, - valueType: value_type, - value: value, - isManaged: is_managed - }; - } - - /** * @param {string} id * @param {string} title * @param {!apps.mojom.Permission} permission @@ -307,12 +291,12 @@ // Test default is to have 0 apps. assertEquals('0 apps', rowLink.subLabel); - const permission1 = createPermission( - /**id=*/ 1, /**value_type=*/ 0, - /**value=*/ 0, /**is_managed=*/ false); - const permission2 = createPermission( - /**id=*/ 2, /**value_type=*/ 0, - /**value=*/ 1, /**is_managed=*/ false); + const permission1 = createBoolPermission( + /**id=*/ 1, + /**value=*/ false, /**is_managed=*/ false); + const permission2 = createBoolPermission( + /**id=*/ 2, + /**value=*/ true, /**is_managed=*/ false); const app1 = createApp('1', 'App1', permission1); const app2 = createApp('2', 'App2', permission2);
diff --git a/chromeos/crosapi/mojom/crosapi.mojom b/chromeos/crosapi/mojom/crosapi.mojom index c103657..92efef9 100644 --- a/chromeos/crosapi/mojom/crosapi.mojom +++ b/chromeos/crosapi/mojom/crosapi.mojom
@@ -580,6 +580,8 @@ kUnsupported = 2, kBrowserNotRunning = 3, kServiceDisconnected = 4, + [MinVersion=1] kProfileNotExist = 5, + [MinVersion=1] kBrowserWindowUnavailable = 6, }; // BrowserInitParams is a set of parameters for initialization of browsers
diff --git a/chromeos/services/cros_healthd/public/mojom/cros_healthd_probe.mojom b/chromeos/services/cros_healthd/public/mojom/cros_healthd_probe.mojom index 093ecbc5..eca29c8 100644 --- a/chromeos/services/cros_healthd/public/mojom/cros_healthd_probe.mojom +++ b/chromeos/services/cros_healthd/public/mojom/cros_healthd_probe.mojom
@@ -23,24 +23,27 @@ }; // An enumeration of each category of information that cros_healthd can report. +// +// NextMinVersion: 1, NextIndex: 17 [Extensible] enum ProbeCategoryEnum { - kBattery, - kNonRemovableBlockDevices, - kCpu, - kTimezone, - kMemory, - kBacklight, - kFan, - kStatefulPartition, - kBluetooth, - kSystem, - kNetwork, - kAudio, - kBootPerformance, - kBus, - kTpm, - kGraphics, + [Default] kUnknown = 16, + kBattery = 0, + kNonRemovableBlockDevices = 1, + kCpu = 2, + kTimezone = 3, + kMemory = 4, + kBacklight = 5, + kFan = 6, + kStatefulPartition = 7, + kBluetooth = 8, + kSystem = 9, + kNetwork = 10, + kAudio = 11, + kBootPerformance = 12, + kBus = 13, + kTpm = 14, + kGraphics = 15, // TODO(b/190459636): Rename it to kSystem after migration. kSystem2 = 0x10000, @@ -48,16 +51,19 @@ // An enumeration of the different categories of errors that can occur when // probing telemetry information. +// +// NextMinVersion: 1, NextIndex: 5 [Extensible] enum ErrorType { + [Default] kUnknown = 4, // An error reading a system file. - kFileReadError, + kFileReadError = 0, // An error parsing data into a consumable form. - kParseError, + kParseError = 1, // An error using a system utility. - kSystemUtilityError, + kSystemUtilityError = 2, // The external service used to probe the information is not available. - kServiceUnavailable, + kServiceUnavailable = 3, }; // Structure that contains error information for a telemetry probe.
diff --git a/components/app_restore/arc_save_handler.cc b/components/app_restore/arc_save_handler.cc index f09c8f8..f0f1c6d 100644 --- a/components/app_restore/arc_save_handler.cc +++ b/components/app_restore/arc_save_handler.cc
@@ -140,15 +140,11 @@ auto task_it = task_id_to_app_id_.find(task_id); if (task_it != task_id_to_app_id_.end()) { - // During the system shutdown phase, the ARC instance connection is lost, - // and the ARC windows are destroyed, but the ARC tasks are not destroyed - // yet. This might cause window bounds lost, and ghost window can't be - // created after reboot due to no window bounds. So if the ARC instance - // connection is lost, don't remove the window info, but wait for the task - // destroyed to keep the window bounds info. Remove the window info only - // when the ARC instance is connected. + // Wait for the task to be destroyed to remove the full restore data for + // the task. Don't remove the window info, because it might affect the ghost + // window creating due to no window bounds. Send the window to background. if (is_connection_ready_) { - FullRestoreSaveHandler::GetInstance()->RemoveWindowInfo( + FullRestoreSaveHandler::GetInstance()->SendWindowToBackground( profile_path_, task_it->second, task_id); } return;
diff --git a/components/app_restore/full_restore_save_handler.cc b/components/app_restore/full_restore_save_handler.cc index d18657c..71a6522 100644 --- a/components/app_restore/full_restore_save_handler.cc +++ b/components/app_restore/full_restore_save_handler.cc
@@ -418,7 +418,7 @@ MaybeStartSaveTimer(profile_path); } -void FullRestoreSaveHandler::RemoveWindowInfo( +void FullRestoreSaveHandler::SendWindowToBackground( const base::FilePath& profile_path, const std::string& app_id, int window_id) { @@ -426,7 +426,7 @@ if (it == profile_path_to_restore_data_.end()) return; - it->second.RemoveWindowInfo(app_id, window_id); + it->second.SendWindowToBackground(app_id, window_id); pending_save_profile_paths_.insert(profile_path);
diff --git a/components/app_restore/full_restore_save_handler.h b/components/app_restore/full_restore_save_handler.h index 61bd3ab..5b3e1db1 100644 --- a/components/app_restore/full_restore_save_handler.h +++ b/components/app_restore/full_restore_save_handler.h
@@ -150,10 +150,10 @@ const std::string& app_id, int window_id); - // Removes WindowInfo from |profile_path| for |app_id| and |window_id|. - void RemoveWindowInfo(const base::FilePath& profile_path, - const std::string& app_id, - int window_id); + // Sends the window for `profile_path` `app_id and `window_id` to background. + void SendWindowToBackground(const base::FilePath& profile_path, + const std::string& app_id, + int window_id); // Starts the timer, and when timeout, clears restore data for |profile_path|. void ClearRestoreData(const base::FilePath& profile_path);
diff --git a/components/app_restore/restore_data.cc b/components/app_restore/restore_data.cc index 34d95709..d5477ba5 100644 --- a/components/app_restore/restore_data.cc +++ b/components/app_restore/restore_data.cc
@@ -173,7 +173,7 @@ // When a chrome app has multiple windows, all windows will be sent to the // background. for (auto& data_it : it->second) - data_it.second->activation_index = INT32_MIN; + data_it.second->activation_index = INT32_MAX; } void RestoreData::RemoveAppRestoreData(const std::string& app_id, @@ -186,10 +186,11 @@ app_id_to_launch_list_.erase(app_id); } -void RestoreData::RemoveWindowInfo(const std::string& app_id, int window_id) { +void RestoreData::SendWindowToBackground(const std::string& app_id, + int window_id) { auto* app_restore_data = GetAppRestoreDataMutable(app_id, window_id); if (app_restore_data) - app_restore_data->ClearWindowInfo(); + app_restore_data->activation_index = INT32_MAX; } void RestoreData::RemoveApp(const std::string& app_id) {
diff --git a/components/app_restore/restore_data.h b/components/app_restore/restore_data.h index 409c8b6..1623fd3 100644 --- a/components/app_restore/restore_data.h +++ b/components/app_restore/restore_data.h
@@ -126,8 +126,8 @@ // Removes a AppRestoreData with |window_id| for |app_id|. void RemoveAppRestoreData(const std::string& app_id, int window_id); - // Clears the window info for |app_id| and |window_id|. - void RemoveWindowInfo(const std::string& app_id, int window_id); + // Sends the window for |app_id| and |window_id| to background. + void SendWindowToBackground(const std::string& app_id, int window_id); // Removes the launch list for |app_id|. void RemoveApp(const std::string& app_id);
diff --git a/components/app_restore/restore_data_unittest.cc b/components/app_restore/restore_data_unittest.cc index 04a4f398..f904dd43 100644 --- a/components/app_restore/restore_data_unittest.cc +++ b/components/app_restore/restore_data_unittest.cc
@@ -481,22 +481,22 @@ EXPECT_EQ(0u, app_id_to_launch_list().size()); } -TEST_F(RestoreDataTest, RemoveWindowInfo) { +TEST_F(RestoreDataTest, SendWindowToBackground) { AddAppLaunchInfos(); ModifyWindowInfos(); ModifyThemeColors(); VerifyRestoreData(restore_data()); - // Remove kAppId1. - restore_data().RemoveWindowInfo(kAppId1, kWindowId1); + restore_data().SendWindowToBackground(kAppId1, kWindowId1); auto window_info = restore_data().GetWindowInfo(kAppId1, kWindowId1); EXPECT_TRUE(window_info); - EXPECT_FALSE(window_info->activation_index.has_value()); - EXPECT_FALSE(window_info->desk_id.has_value()); - EXPECT_FALSE(window_info->current_bounds.has_value()); - EXPECT_FALSE(window_info->window_state_type.has_value()); - EXPECT_FALSE(window_info->arc_extra_info.has_value()); + EXPECT_TRUE(window_info->activation_index.has_value()); + EXPECT_EQ(INT32_MAX, window_info->activation_index.value()); + EXPECT_TRUE(window_info->desk_id.has_value()); + EXPECT_TRUE(window_info->current_bounds.has_value()); + EXPECT_TRUE(window_info->window_state_type.has_value()); + EXPECT_TRUE(window_info->arc_extra_info.has_value()); } TEST_F(RestoreDataTest, RemoveApp) { @@ -674,19 +674,19 @@ restore_data().SetNextRestoreWindowIdForChromeApp(kAppId1); - // Verify that the activation index is modified as INT32_MIN. + // Verify that the activation index is modified as INT32_MAX. EXPECT_EQ(kWindowId1, restore_data().FetchRestoreWindowId(kAppId1)); window_info = restore_data().GetWindowInfo(kAppId1, kWindowId1); EXPECT_TRUE(window_info); EXPECT_TRUE(window_info->activation_index.has_value()); - EXPECT_EQ(INT32_MIN, window_info->activation_index.value()); + EXPECT_EQ(INT32_MAX, window_info->activation_index.value()); - // Verify that the activation index is modified as INT32_MIN. + // Verify that the activation index is modified as INT32_MAX. EXPECT_EQ(kWindowId2, restore_data().FetchRestoreWindowId(kAppId1)); window_info = restore_data().GetWindowInfo(kAppId1, kWindowId2); EXPECT_TRUE(window_info); EXPECT_TRUE(window_info->activation_index.has_value()); - EXPECT_EQ(INT32_MIN, window_info->activation_index.value()); + EXPECT_EQ(INT32_MAX, window_info->activation_index.value()); EXPECT_EQ(0, restore_data().FetchRestoreWindowId(kAppId1)); }
diff --git a/components/arc/arc_features.cc b/components/arc/arc_features.cc index 894a4a1..1ea8593 100644 --- a/components/arc/arc_features.cc +++ b/components/arc/arc_features.cc
@@ -106,7 +106,7 @@ // Controls ARCVM real time vcpu feature on a device with 2 logical cores // online. const base::Feature kRtVcpuDualCore{"ArcRtVcpuDualCore", - base::FEATURE_ENABLED_BY_DEFAULT}; + base::FEATURE_DISABLED_BY_DEFAULT}; // Controls ARCVM real time vcpu feature on a device with 3+ logical cores // online.
diff --git a/components/arc/compat_mode/arc_resize_lock_manager.cc b/components/arc/compat_mode/arc_resize_lock_manager.cc index 724977f..15964996 100644 --- a/components/arc/compat_mode/arc_resize_lock_manager.cc +++ b/components/arc/compat_mode/arc_resize_lock_manager.cc
@@ -161,7 +161,8 @@ }; bool ShouldEnableResizeLock(ash::ArcResizeLockType type) { - return type != ash::ArcResizeLockType::RESIZABLE; + return type != ash::ArcResizeLockType::NONE && + type != ash::ArcResizeLockType::RESIZE_ENABLED_TOGGLABLE; } } // namespace @@ -217,7 +218,7 @@ // We need to always trigger UpdateCompatModeButton regardless of value // change because it need to be called even when the property is set to - // ArcResizeLockType::RESIZABLE, which is the the default value of + // ArcResizeLockType::NONE, which is the the default value of // kArcResizeLockTypeKey, and the new value is the same as |old| in that case. AppIdObserver::RunOnReady( window, base::BindOnce(&CompatModeButtonController::Update, @@ -230,24 +231,20 @@ if (new_value == old_value) return; - if (ShouldEnableResizeLock(new_value)) { - // Both the resize lock value and app id are needed to enable resize lock. - AppIdObserver::RunOnReady( - window, base::BindOnce( - [](base::WeakPtr<ArcResizeLockManager> manager, - aura::Window* window) { - if (!manager) - return; - if (!ShouldEnableResizeLock(window->GetProperty( - ash::kArcResizeLockTypeKey))) { - return; - } + AppIdObserver::RunOnReady( + window, base::BindOnce( + [](base::WeakPtr<ArcResizeLockManager> manager, + aura::Window* window) { + if (!manager) + return; + if (ShouldEnableResizeLock( + window->GetProperty(ash::kArcResizeLockTypeKey))) { manager->EnableResizeLock(window); - }, - weak_ptr_factory_.GetWeakPtr())); - } else { - DisableResizeLock(window); - } + } else { + manager->DisableResizeLock(window); + } + }, + weak_ptr_factory_.GetWeakPtr())); } void ArcResizeLockManager::OnWindowBoundsChanged( @@ -278,15 +275,16 @@ const ash::ArcResizeLockType resize_lock_value = window->GetProperty(ash::kArcResizeLockTypeKey); switch (resize_lock_value) { - case ash::ArcResizeLockType::RESIZE_LIMITED: + case ash::ArcResizeLockType::RESIZE_DISABLED_TOGGLABLE: pref_delegate_->SetResizeLockState(*app_id, mojom::ArcResizeLockState::ON); break; - case ash::ArcResizeLockType::FULLY_LOCKED: + case ash::ArcResizeLockType::RESIZE_DISABLED_NONTOGGLABLE: pref_delegate_->SetResizeLockState( *app_id, mojom::ArcResizeLockState::FULLY_LOCKED); break; - case ash::ArcResizeLockType::RESIZABLE: + case ash::ArcResizeLockType::NONE: + case ash::ArcResizeLockType::RESIZE_ENABLED_TOGGLABLE: NOTREACHED(); } // As we updated the resize lock state above, we need to update compat mode @@ -296,7 +294,7 @@ if (ShouldShowSplashScreenDialog(pref_delegate_)) { const bool is_for_unresizable = window->GetProperty(ash::kArcResizeLockTypeKey) == - ash::ArcResizeLockType::FULLY_LOCKED; + ash::ArcResizeLockType::RESIZE_DISABLED_NONTOGGLABLE; WindowActivationObserver::RunOnActivated( window, base::BindOnce(&ArcSplashScreenDialogView::Show, window, is_for_unresizable)); @@ -313,7 +311,12 @@ const bool erased = resize_lock_enabled_windows_.erase(window); if (!erased) return; - + const auto app_id = GetAppId(window); + DCHECK(app_id); + if (window->GetProperty(ash::kArcResizeLockTypeKey) == + ash::ArcResizeLockType::RESIZE_ENABLED_TOGGLABLE) { + pref_delegate_->SetResizeLockState(*app_id, mojom::ArcResizeLockState::OFF); + } window->SetProperty(ash::kResizeShadowTypeKey, ash::ResizeShadowType::kUnlock); // Hide shadow effect on window. ash::Shell may not exist in tests.
diff --git a/components/arc/compat_mode/arc_resize_lock_manager_unittest.cc b/components/arc/compat_mode/arc_resize_lock_manager_unittest.cc index 5eacb9cf..e750850 100644 --- a/components/arc/compat_mode/arc_resize_lock_manager_unittest.cc +++ b/components/arc/compat_mode/arc_resize_lock_manager_unittest.cc
@@ -74,9 +74,11 @@ DEFINE_UI_CLASS_PROPERTY_KEY(bool, kNonInterestedPropKey, false) -constexpr std::array<ash::ArcResizeLockType, 3> kArcResizeLockTypes{ - ash::ArcResizeLockType::RESIZABLE, ash::ArcResizeLockType::RESIZE_LIMITED, - ash::ArcResizeLockType::FULLY_LOCKED}; +constexpr std::array<ash::ArcResizeLockType, 4> kArcResizeLockTypes{ + ash::ArcResizeLockType::NONE, + ash::ArcResizeLockType::RESIZE_ENABLED_TOGGLABLE, + ash::ArcResizeLockType::RESIZE_DISABLED_TOGGLABLE, + ash::ArcResizeLockType::RESIZE_DISABLED_NONTOGGLABLE}; } // namespace @@ -139,31 +141,31 @@ // Test EnableResizeLock will be called by the property change. arc_window->SetProperty(ash::kArcResizeLockTypeKey, - ash::ArcResizeLockType::RESIZE_LIMITED); + ash::ArcResizeLockType::RESIZE_DISABLED_TOGGLABLE); EXPECT_TRUE(IsResizeLockEnabled(arc_window.get())); // Test nothing will be called by the property overwrite with the same value. arc_window->SetProperty(ash::kArcResizeLockTypeKey, - ash::ArcResizeLockType::RESIZE_LIMITED); + ash::ArcResizeLockType::RESIZE_DISABLED_TOGGLABLE); EXPECT_TRUE(IsResizeLockEnabled(arc_window.get())); // Test DisableResizeLock will be called by the property change. arc_window->SetProperty(ash::kArcResizeLockTypeKey, - ash::ArcResizeLockType::RESIZABLE); + ash::ArcResizeLockType::NONE); EXPECT_FALSE(IsResizeLockEnabled(arc_window.get())); - // Test if enabling/disabling |FULLY_LOCKED| toggles the resize lock state - // properly. + // Test if enabling/disabling |RESIZE_DISABLED_NONTOGGLABLE| toggles the + // resize lock state properly. arc_window->SetProperty(ash::kArcResizeLockTypeKey, - ash::ArcResizeLockType::FULLY_LOCKED); + ash::ArcResizeLockType::RESIZE_DISABLED_NONTOGGLABLE); EXPECT_TRUE(IsResizeLockEnabled(arc_window.get())); arc_window->SetProperty(ash::kArcResizeLockTypeKey, - ash::ArcResizeLockType::RESIZABLE); + ash::ArcResizeLockType::NONE); EXPECT_FALSE(IsResizeLockEnabled(arc_window.get())); // Test nothing will be called by the property overwrite with the same value. arc_window->SetProperty(ash::kArcResizeLockTypeKey, - ash::ArcResizeLockType::RESIZABLE); + ash::ArcResizeLockType::NONE); EXPECT_FALSE(IsResizeLockEnabled(arc_window.get())); // Test nothing will be called by the NON-interested property change. @@ -178,7 +180,7 @@ EXPECT_FALSE(IsResizeLockEnabled(arc_window.get())); arc_window->SetProperty(ash::kArcResizeLockTypeKey, - ash::ArcResizeLockType::RESIZE_LIMITED); + ash::ArcResizeLockType::RESIZE_DISABLED_TOGGLABLE); EXPECT_FALSE(IsResizeLockEnabled(arc_window.get())); // Should ignore null. arc_window->ClearProperty(ash::kAppIDKey); @@ -200,11 +202,11 @@ EXPECT_FALSE(IsResizeLockEnabled(arc_window.get())); arc_window->SetProperty(ash::kArcResizeLockTypeKey, - ash::ArcResizeLockType::RESIZE_LIMITED); + ash::ArcResizeLockType::RESIZE_DISABLED_TOGGLABLE); EXPECT_FALSE(IsResizeLockEnabled(arc_window.get())); arc_window->SetProperty(ash::kArcResizeLockTypeKey, - ash::ArcResizeLockType::RESIZABLE); + ash::ArcResizeLockType::NONE); EXPECT_FALSE(IsResizeLockEnabled(arc_window.get())); arc_window->SetProperty(ash::kAppIDKey, app_id); @@ -215,11 +217,12 @@ TEST_F(ArcResizeLockManagerTest, TestNonArcWindow) { auto non_arc_window = CreateFakeWindow(false); EXPECT_FALSE(IsResizeLockEnabled(non_arc_window.get())); - non_arc_window->SetProperty(ash::kArcResizeLockTypeKey, - ash::ArcResizeLockType::RESIZE_LIMITED); + non_arc_window->SetProperty( + ash::kArcResizeLockTypeKey, + ash::ArcResizeLockType::RESIZE_DISABLED_TOGGLABLE); EXPECT_FALSE(IsResizeLockEnabled(non_arc_window.get())); non_arc_window->SetProperty(ash::kArcResizeLockTypeKey, - ash::ArcResizeLockType::RESIZABLE); + ash::ArcResizeLockType::NONE); EXPECT_FALSE(IsResizeLockEnabled(non_arc_window.get())); } @@ -231,24 +234,24 @@ arc_window->SetProperty(ash::kAppIDKey, app_id); EXPECT_FALSE(IsResizeLockEnabled(arc_window.get())); - // Test for RESIZE_LIMITED. + // Test for RESIZE_DISABLED_TOGGLABLE. pref_delegate()->SetResizeLockState(app_id, mojom::ArcResizeLockState::READY); arc_window->SetProperty(ash::kArcResizeLockTypeKey, - ash::ArcResizeLockType::RESIZE_LIMITED); + ash::ArcResizeLockType::RESIZE_DISABLED_TOGGLABLE); EXPECT_EQ(pref_delegate()->GetResizeLockState(app_id), mojom::ArcResizeLockState::ON); // Test for RESIZABLE. pref_delegate()->SetResizeLockState(app_id, mojom::ArcResizeLockState::READY); arc_window->SetProperty(ash::kArcResizeLockTypeKey, - ash::ArcResizeLockType::RESIZABLE); + ash::ArcResizeLockType::NONE); EXPECT_EQ(pref_delegate()->GetResizeLockState(app_id), mojom::ArcResizeLockState::READY); - // Test for FULLY_LOCKED. + // Test for RESIZE_DISABLED_NONTOGGLABLE. pref_delegate()->SetResizeLockState(app_id, mojom::ArcResizeLockState::READY); arc_window->SetProperty(ash::kArcResizeLockTypeKey, - ash::ArcResizeLockType::FULLY_LOCKED); + ash::ArcResizeLockType::RESIZE_DISABLED_NONTOGGLABLE); EXPECT_EQ(pref_delegate()->GetResizeLockState(app_id), mojom::ArcResizeLockState::FULLY_LOCKED); } @@ -312,31 +315,31 @@ // Locked for resize locked windows. resize_shadow_updated = false; arc_window->SetProperty(ash::kArcResizeLockTypeKey, - ash::ArcResizeLockType::RESIZE_LIMITED); + ash::ArcResizeLockType::RESIZE_DISABLED_TOGGLABLE); EXPECT_EQ(arc_window->GetProperty(ash::kResizeShadowTypeKey), ash::ResizeShadowType::kLock); EXPECT_TRUE(resize_shadow_updated); // No redundant property update. resize_shadow_updated = false; arc_window->SetProperty(ash::kArcResizeLockTypeKey, - ash::ArcResizeLockType::RESIZE_LIMITED); + ash::ArcResizeLockType::RESIZE_DISABLED_TOGGLABLE); EXPECT_FALSE(resize_shadow_updated); resize_shadow_updated = false; arc_window->SetProperty(ash::kArcResizeLockTypeKey, - ash::ArcResizeLockType::FULLY_LOCKED); + ash::ArcResizeLockType::RESIZE_DISABLED_NONTOGGLABLE); EXPECT_FALSE(resize_shadow_updated); // Unlocked for non-resize locked windows. resize_shadow_updated = false; arc_window->SetProperty(ash::kArcResizeLockTypeKey, - ash::ArcResizeLockType::RESIZABLE); + ash::ArcResizeLockType::NONE); EXPECT_EQ(arc_window->GetProperty(ash::kResizeShadowTypeKey), ash::ResizeShadowType::kUnlock); EXPECT_TRUE(resize_shadow_updated); // No redundant property update. resize_shadow_updated = false; arc_window->SetProperty(ash::kArcResizeLockTypeKey, - ash::ArcResizeLockType::RESIZABLE); + ash::ArcResizeLockType::NONE); EXPECT_FALSE(resize_shadow_updated); } @@ -354,7 +357,7 @@ auto arc_window = CreateFakeWindow(true); EXPECT_FALSE(IsResizeLockEnabled(arc_window.get())); arc_window->SetProperty(ash::kArcResizeLockTypeKey, - ash::ArcResizeLockType::RESIZE_LIMITED); + ash::ArcResizeLockType::RESIZE_DISABLED_TOGGLABLE); EXPECT_FALSE(IsResizeLockEnabled(arc_window.get())); } @@ -363,7 +366,7 @@ auto arc_window = CreateFakeWindow(true); EXPECT_FALSE(IsResizeLockEnabled(arc_window.get())); arc_window->SetProperty(ash::kArcResizeLockTypeKey, - ash::ArcResizeLockType::RESIZE_LIMITED); + ash::ArcResizeLockType::RESIZE_DISABLED_TOGGLABLE); arc_window->SetProperty(ash::kAppIDKey, std::string("app-id")); EXPECT_TRUE(IsResizeLockEnabled(arc_window.get()));
diff --git a/components/arc/compat_mode/compat_mode_button_controller.cc b/components/arc/compat_mode/compat_mode_button_controller.cc index 6beccf2e..b2f6ac25d 100644 --- a/components/arc/compat_mode/compat_mode_button_controller.cc +++ b/components/arc/compat_mode/compat_mode_button_controller.cc
@@ -66,10 +66,10 @@ if (!app_id) return; auto* const frame_header = GetFrameHeader(window); + // TODO(b/200230343): Replace it with resize lock type. const auto resize_lock_state = pref_delegate->GetResizeLockState(*app_id); if (resize_lock_state == mojom::ArcResizeLockState::UNDEFINED || resize_lock_state == mojom::ArcResizeLockState::READY) { - frame_header->SetCenterButton(nullptr); return; } auto* compat_mode_button = frame_header->GetCenterButton(); @@ -101,15 +101,17 @@ const auto resize_lock_type = window->GetProperty(ash::kArcResizeLockTypeKey); switch (resize_lock_type) { - case ash::ArcResizeLockType::RESIZE_LIMITED: - case ash::ArcResizeLockType::RESIZABLE: + case ash::ArcResizeLockType::RESIZE_DISABLED_TOGGLABLE: + case ash::ArcResizeLockType::RESIZE_ENABLED_TOGGLABLE: compat_mode_button->SetEnabled(true); break; - case ash::ArcResizeLockType::FULLY_LOCKED: + case ash::ArcResizeLockType::RESIZE_DISABLED_NONTOGGLABLE: compat_mode_button->SetEnabled(false); compat_mode_button->SetTooltipText(l10n_util::GetStringUTF16( IDS_ASH_ARC_APP_COMPAT_DISABLED_COMPAT_MODE_BUTTON_TOOLTIP_PHONE)); break; + case ash::ArcResizeLockType::NONE: + NOTREACHED(); } UpdateAshAccelerator(pref_delegate, window); @@ -136,13 +138,16 @@ const auto resize_lock_type = window->GetProperty(ash::kArcResizeLockTypeKey); switch (resize_lock_type) { - case ash::ArcResizeLockType::RESIZE_LIMITED: - case ash::ArcResizeLockType::RESIZABLE: + case ash::ArcResizeLockType::RESIZE_DISABLED_TOGGLABLE: + // TODO(b/200230343): Call NOTREACHED() once the client has shifted to + // the new protocol. + case ash::ArcResizeLockType::NONE: + case ash::ArcResizeLockType::RESIZE_ENABLED_TOGGLABLE: frame_view->SetToggleResizeLockMenuCallback(base::BindRepeating( &CompatModeButtonController::ToggleResizeToggleMenu, GetWeakPtr(), window, pref_delegate)); break; - case ash::ArcResizeLockType::FULLY_LOCKED: + case ash::ArcResizeLockType::RESIZE_DISABLED_NONTOGGLABLE: frame_view->ClearToggleResizeLockMenuCallback(); break; }
diff --git a/components/arc/compat_mode/resize_util.cc b/components/arc/compat_mode/resize_util.cc index 6094eeb..c9c187f 100644 --- a/components/arc/compat_mode/resize_util.cc +++ b/components/arc/compat_mode/resize_util.cc
@@ -180,8 +180,9 @@ } ResizeCompatMode PredictCurrentMode(const aura::Window* window) { - if (window->GetProperty(ash::kArcResizeLockTypeKey) == - ash::ArcResizeLockType::RESIZABLE) { + const auto resize_lock_type = window->GetProperty(ash::kArcResizeLockTypeKey); + if (resize_lock_type == ash::ArcResizeLockType::NONE || + resize_lock_type == ash::ArcResizeLockType::RESIZE_ENABLED_TOGGLABLE) { return ResizeCompatMode::kResizable; }
diff --git a/components/arc/compat_mode/test/compat_mode_test_base.cc b/components/arc/compat_mode/test/compat_mode_test_base.cc index 36e51a0..aad6178b 100644 --- a/components/arc/compat_mode/test/compat_mode_test_base.cc +++ b/components/arc/compat_mode/test/compat_mode_test_base.cc
@@ -121,19 +121,23 @@ const auto app_id = GetAppId(window); switch (pref_delegate()->GetResizeLockState(*app_id)) { case mojom::ArcResizeLockState::UNDEFINED: + window->SetProperty(ash::kArcResizeLockTypeKey, + ash::ArcResizeLockType::NONE); + break; case mojom::ArcResizeLockState::OFF: window->SetProperty(ash::kArcResizeLockTypeKey, - ash::ArcResizeLockType::RESIZABLE); + ash::ArcResizeLockType::RESIZE_ENABLED_TOGGLABLE); break; case mojom::ArcResizeLockState::ON: case mojom::ArcResizeLockState::READY: case mojom::ArcResizeLockState::FULLY_LOCKED: if (widget->widget_delegate()->CanResize()) { window->SetProperty(ash::kArcResizeLockTypeKey, - ash::ArcResizeLockType::RESIZE_LIMITED); + ash::ArcResizeLockType::RESIZE_DISABLED_TOGGLABLE); } else { - window->SetProperty(ash::kArcResizeLockTypeKey, - ash::ArcResizeLockType::FULLY_LOCKED); + window->SetProperty( + ash::kArcResizeLockTypeKey, + ash::ArcResizeLockType::RESIZE_DISABLED_NONTOGGLABLE); } break; }
diff --git a/components/arc/metrics/arc_metrics_service.cc b/components/arc/metrics/arc_metrics_service.cc index e33e933..01896b4 100644 --- a/components/arc/metrics/arc_metrics_service.cc +++ b/components/arc/metrics/arc_metrics_service.cc
@@ -374,6 +374,12 @@ base::UmaHistogramBoolean(metric_name, success); } +void ArcMetricsService::ReportImageCopyPasteCompatAction( + mojom::ArcImageCopyPasteCompatAction action_type) { + base::UmaHistogramEnumeration("Arc.ImageCopyPasteCompatOperationType", + action_type); +} + void ArcMetricsService::NotifyLowMemoryKill() { for (auto& obs : app_kill_observers_) obs.OnArcLowMemoryKill();
diff --git a/components/arc/metrics/arc_metrics_service.h b/components/arc/metrics/arc_metrics_service.h index e3f3020..13f2bba 100644 --- a/components/arc/metrics/arc_metrics_service.h +++ b/components/arc/metrics/arc_metrics_service.h
@@ -130,6 +130,8 @@ uint32_t number_of_directories) override; void ReportMainAccountHashMigrationMetrics( mojom::MainAccountHashMigrationStatus status) override; + void ReportImageCopyPasteCompatAction( + mojom::ArcImageCopyPasteCompatAction action_type) override; // wm::ActivationChangeObserver overrides. // Records to UMA when a user has interacted with an ARC app window.
diff --git a/components/arc/mojom/metrics.mojom b/components/arc/mojom/metrics.mojom index 51b49f4c..d4b46fc 100644 --- a/components/arc/mojom/metrics.mojom +++ b/components/arc/mojom/metrics.mojom
@@ -1,7 +1,7 @@ // Copyright 2016 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. -// Next MinVersion: 15 +// Next MinVersion: 16 module arc.mojom; @@ -205,6 +205,14 @@ kImageDragDropFromArc = 7, }; +[Extensible] +enum ArcImageCopyPasteCompatAction { + kPasteFromFiles = 0, + kDragFromFiles = 1, + kPasteFromBrowser = 2, + kDragFromBrowser = 3, +}; + // Enumerates variations of Low Latency Stylus Library. [Extensible] enum LowLatencyStylusLibraryType { @@ -266,7 +274,7 @@ // tools/metrics/histograms/enums.xml. }; -// Next method ID: 18 +// Next method ID: 19 interface MetricsHost { // Reports boot progress events from ARC instance. ReportBootProgress@0(array<BootProgressEvent> events, @@ -336,6 +344,15 @@ // Reports main account hash migration status. [MinVersion=14] ReportMainAccountHashMigrationMetrics@17( MainAccountHashMigrationStatus status); + + // Reports the operation type (copy & paste or drag & drop) and the source of + // the image (from browser or Files app) when image copy-paste app compat is + // triggered. + // Image copy-paste app compat is a feature that allows insertion of images to + // Android apps through commitContent IME API or Android intent, when the app + // don't support images in the clipboard. + [MinVersion=15] ReportImageCopyPasteCompatAction@18( + ArcImageCopyPasteCompatAction action_type); }; // Next method ID: 3
diff --git a/components/autofill/content/browser/content_autofill_driver_factory_unittest.cc b/components/autofill/content/browser/content_autofill_driver_factory_unittest.cc index 7676792..c70807a 100644 --- a/components/autofill/content/browser/content_autofill_driver_factory_unittest.cc +++ b/components/autofill/content/browser/content_autofill_driver_factory_unittest.cc
@@ -171,8 +171,13 @@ public ::testing::WithParamInterface<bool> { public: ContentAutofillDriverFactoryTest_WithOrWithoutBfCache() { - scoped_feature_list_.InitWithFeatureState(::features::kBackForwardCache, - use_bfcache()); + std::vector<base::Feature> enabled; + // Allow BackForwardCache for all devices regardless of their memory. + std::vector<base::Feature> disabled{ + ::features::kBackForwardCacheMemoryControls}; + (use_bfcache() ? enabled : disabled) + .push_back(::features::kBackForwardCache); + scoped_feature_list_.InitWithFeatures(enabled, disabled); } bool use_bfcache() { return GetParam(); } @@ -260,9 +265,13 @@ ASSERT_NE(orig_rfh_id, main_rfh()->GetGlobalId()); // A new driver for main_rfh() has been created and the |orig_rfh| has now - // been removed in ContentAutofillDriverFactory::RenderFrameDeleted(). - EXPECT_EQ(factory_test_api().GetDriver(orig_rfh), - use_bfcache() ? orig_driver : nullptr); + // been removed in ContentAutofillDriverFactory::RenderFrameDeleted(), unless + // BFcache is enabled (or main_rfh() happens to have the same address as + // |orig_rfh|). + if (use_bfcache()) + EXPECT_EQ(factory_test_api().GetDriver(orig_rfh), orig_driver); + else if (main_rfh() != orig_rfh) + EXPECT_EQ(factory_test_api().GetDriver(orig_rfh), nullptr); EXPECT_NE(factory_test_api().GetDriver(main_rfh()), nullptr); EXPECT_EQ(factory_test_api().num_drivers(), use_bfcache() ? 2u : 1u); }
diff --git a/components/exo/client_controlled_shell_surface.cc b/components/exo/client_controlled_shell_surface.cc index c211adc..7109984e3 100644 --- a/components/exo/client_controlled_shell_surface.cc +++ b/components/exo/client_controlled_shell_surface.cc
@@ -736,29 +736,41 @@ return 1.f / scale_; } -void ClientControlledShellSurface::SetResizeLock(bool resize_lock) { - TRACE_EVENT1("exo", "ClientControlledShellSurface::SetResizeLock", - "resize_lock", resize_lock); - pending_resize_lock_ = resize_lock; +void ClientControlledShellSurface::SetResizeLockType( + ash::ArcResizeLockType resize_lock_type) { + TRACE_EVENT1("exo", "ClientControlledShellSurface::SetResizeLockType", + "resize_lock_type", resize_lock_type); + pending_resize_lock_type_ = resize_lock_type; } void ClientControlledShellSurface::UpdateResizability() { TRACE_EVENT0("exo", "ClientControlledShellSurface::updateCanResize"); - ash::ArcResizeLockType resizeLockType = ash::ArcResizeLockType::RESIZABLE; - if (pending_resize_lock_) { - // CalculateCanResize() returns the "raw" resizability of the window, - // in which the influence of the resize lock state is excluded. - if (CalculateCanResize()) { - resizeLockType = ash::ArcResizeLockType::RESIZE_LIMITED; - } else { - resizeLockType = ash::ArcResizeLockType::FULLY_LOCKED; + ash::ArcResizeLockType resize_lock_type = pending_resize_lock_type_; + // TODO(b/200230343): Remove this once the client's switched to the + // new protocol. + if (resize_lock_type == ash::ArcResizeLockType::RESIZE_DISABLED_TOGGLABLE && + !CalculateCanResize()) { + resize_lock_type = ash::ArcResizeLockType::RESIZE_DISABLED_NONTOGGLABLE; + } else if (resize_lock_type == ash::ArcResizeLockType::NONE) { + const auto current_resize_lock_type = + widget_->GetNativeWindow()->GetProperty(ash::kArcResizeLockTypeKey); + if (current_resize_lock_type == + ash::ArcResizeLockType::RESIZE_DISABLED_TOGGLABLE) { + resize_lock_type = ash::ArcResizeLockType::RESIZE_ENABLED_TOGGLABLE; + } else if (current_resize_lock_type == + ash::ArcResizeLockType::RESIZE_ENABLED_TOGGLABLE) { + resize_lock_type = ash::ArcResizeLockType::RESIZE_ENABLED_TOGGLABLE; } } widget_->GetNativeWindow()->SetProperty(ash::kArcResizeLockTypeKey, - resizeLockType); + resize_lock_type); // If resize lock is enabled, the window is explicitly marded as unresizable. // Otherwise, the decision is deferred to the parent class. - if (ash::features::IsArcResizeLockEnabled() && pending_resize_lock_) { + if (ash::features::IsArcResizeLockEnabled() && + (pending_resize_lock_type_ == + ash::ArcResizeLockType::RESIZE_DISABLED_TOGGLABLE || + pending_resize_lock_type_ == + ash::ArcResizeLockType::RESIZE_DISABLED_NONTOGGLABLE)) { SetCanResize(false); return; }
diff --git a/components/exo/client_controlled_shell_surface.h b/components/exo/client_controlled_shell_surface.h index b1ae5ce..0aa43f4 100644 --- a/components/exo/client_controlled_shell_surface.h +++ b/components/exo/client_controlled_shell_surface.h
@@ -9,6 +9,7 @@ #include <string> #include "ash/display/screen_orientation_controller.h" +#include "ash/public/cpp/arc_resize_lock_type.h" #include "ash/wm/client_controlled_state.h" #include "base/callback.h" #include "base/gtest_prod_util.h" @@ -241,10 +242,10 @@ // Used to scale incoming coordinates from the client to DP. float GetClientToDpScale() const; - // Sets the resize lock state to the surface. - void SetResizeLock(bool resize_lock); + // Sets the resize lock type to the surface. + void SetResizeLockType(ash::ArcResizeLockType resize_lock_type); - // Update the resizability based on the resize lock state. + // Update the resizability based on the resize lock type. void UpdateResizability() override; protected: @@ -374,7 +375,8 @@ // Accessibility ID provided by client. absl::optional<int32_t> client_accessibility_id_; - bool pending_resize_lock_ = false; + ash::ArcResizeLockType pending_resize_lock_type_ = + ash::ArcResizeLockType::NONE; }; } // namespace exo
diff --git a/components/exo/client_controlled_shell_surface_unittest.cc b/components/exo/client_controlled_shell_surface_unittest.cc index c56e33d8..68962298 100644 --- a/components/exo/client_controlled_shell_surface_unittest.cc +++ b/components/exo/client_controlled_shell_surface_unittest.cc
@@ -2749,7 +2749,8 @@ scoped_feature_list.InitAndEnableFeature(ash::features::kArcResizeLock); EXPECT_TRUE(shell_surface->CanResize()); - shell_surface->SetResizeLock(true); + shell_surface->SetResizeLockType( + ash::ArcResizeLockType::RESIZE_DISABLED_TOGGLABLE); surface->Commit(); EXPECT_FALSE(shell_surface->CanResize()); @@ -2757,16 +2758,16 @@ // of the window. aura::Window* window = shell_surface->GetWidget()->GetNativeWindow(); EXPECT_EQ(window->GetProperty(ash::kArcResizeLockTypeKey), - ash::ArcResizeLockType::RESIZE_LIMITED); + ash::ArcResizeLockType::RESIZE_DISABLED_TOGGLABLE); shell_surface->SetMinimumSize(gfx::Size(1, 1)); shell_surface->SetMaximumSize(gfx::Size(1, 1)); surface->Commit(); EXPECT_EQ(window->GetProperty(ash::kArcResizeLockTypeKey), - ash::ArcResizeLockType::FULLY_LOCKED); + ash::ArcResizeLockType::RESIZE_DISABLED_NONTOGGLABLE); shell_surface->SetMinimumSize(gfx::Size(0, 0)); shell_surface->SetMaximumSize(gfx::Size(0, 0)); - shell_surface->SetResizeLock(false); + shell_surface->SetResizeLockType(ash::ArcResizeLockType::NONE); surface->Commit(); EXPECT_TRUE(shell_surface->CanResize()); } @@ -2779,7 +2780,8 @@ scoped_feature_list.InitAndDisableFeature(ash::features::kArcResizeLock); EXPECT_TRUE(shell_surface->CanResize()); - shell_surface->SetResizeLock(true); + shell_surface->SetResizeLockType( + ash::ArcResizeLockType::RESIZE_DISABLED_TOGGLABLE); surface->Commit(); EXPECT_TRUE(shell_surface->CanResize()); }
diff --git a/components/exo/shell_surface_base.cc b/components/exo/shell_surface_base.cc index b3ebf8c..07f004d 100644 --- a/components/exo/shell_surface_base.cc +++ b/components/exo/shell_surface_base.cc
@@ -1392,8 +1392,15 @@ gfx::Rect ShellSurfaceBase::GetVisibleBounds() const { // Use |geometry_| if set, otherwise use the visual bounds of the surface. if (geometry_.IsEmpty()) { - return root_surface() ? gfx::Rect(root_surface()->content_size()) - : gfx::Rect(); + gfx::Size size; + if (root_surface()) { + size = root_surface()->content_size(); + if (client_submits_surfaces_in_pixel_coordinates()) { + int dsf = std::ceil(host_window()->layer()->device_scale_factor()); + size = gfx::ScaleToRoundedSize(size, 1.0f / dsf); + } + } + return gfx::Rect(size); } const auto* screen = display::Screen::GetScreen();
diff --git a/components/exo/sub_surface.h b/components/exo/sub_surface.h index 492c7aa6..963a9d5 100644 --- a/components/exo/sub_surface.h +++ b/components/exo/sub_surface.h
@@ -83,6 +83,7 @@ void SetInitialWorkspace(const char* initial_workspace) override {} void Pin(bool trusted) override {} void Unpin() override {} + void SetClientSubmitsSurfacesInPixelCoordinates(bool enabled) override {} // Overridden from SurfaceObserver: void OnSurfaceDestroying(Surface* surface) override;
diff --git a/components/exo/surface.cc b/components/exo/surface.cc index 59df8c7..1eb4951 100644 --- a/components/exo/surface.cc +++ b/components/exo/surface.cc
@@ -1528,4 +1528,9 @@ delegate_->Unpin(); } +void Surface::SetClientSubmitsSurfacesInPixelCoordinates(bool enabled) { + if (delegate_) + delegate_->SetClientSubmitsSurfacesInPixelCoordinates(enabled); +} + } // namespace exo
diff --git a/components/exo/surface.h b/components/exo/surface.h index e4db588..96b97aa 100644 --- a/components/exo/surface.h +++ b/components/exo/surface.h
@@ -392,6 +392,8 @@ // Release the pinned mode and allows the user to do other things again. void Unpin(); + void SetClientSubmitsSurfacesInPixelCoordinates(bool enabled); + private: struct State { State();
diff --git a/components/exo/surface_delegate.h b/components/exo/surface_delegate.h index 51a9010..ea1f2eb 100644 --- a/components/exo/surface_delegate.h +++ b/components/exo/surface_delegate.h
@@ -101,6 +101,8 @@ // Releases the pinned mode and allows the user to do other things again. virtual void Unpin() = 0; + virtual void SetClientSubmitsSurfacesInPixelCoordinates(bool enabled) = 0; + protected: virtual ~SurfaceDelegate() {} };
diff --git a/components/exo/surface_tree_host.cc b/components/exo/surface_tree_host.cc index 2c6ae1a..430b7d9 100644 --- a/components/exo/surface_tree_host.cc +++ b/components/exo/surface_tree_host.cc
@@ -213,6 +213,10 @@ UpdateDisplayOnTree(); } +void SurfaceTreeHost::SetClientSubmitsSurfacesInPixelCoordinates(bool enabled) { + client_submits_surfaces_in_pixel_coordinates_ = enabled; +} + //////////////////////////////////////////////////////////////////////////////// // display::DisplayObserver: void SurfaceTreeHost::OnDisplayMetricsChanged(const display::Display& display, @@ -319,6 +323,15 @@ gfx::Rect bounds = root_surface_->surface_hierarchy_content_bounds(); host_window_->SetBounds( gfx::Rect(host_window_->bounds().origin(), bounds.size())); + // TODO(yjliu): a) consolidate with ClientControlledShellSurface. b) use the + // scale factor the buffer is created for to set the transform for + // synchronization. + if (client_submits_surfaces_in_pixel_coordinates_) { + gfx::Transform tr; + float s = ceil(host_window_->layer()->device_scale_factor()); + tr.Scale(1.0f / s, 1.0f / s); + host_window_->SetTransform(tr); + } const bool fills_bounds_opaquely = bounds.size() == root_surface_->content_size() && root_surface_->FillsBoundsOpaquely();
diff --git a/components/exo/surface_tree_host.h b/components/exo/surface_tree_host.h index 65082066..e07e799 100644 --- a/components/exo/surface_tree_host.h +++ b/components/exo/surface_tree_host.h
@@ -115,6 +115,7 @@ void SetInitialWorkspace(const char* initial_workspace) override {} void Pin(bool trusted) override {} void Unpin() override {} + void SetClientSubmitsSurfacesInPixelCoordinates(bool enabled) override; // display::DisplayObserver: void OnDisplayMetricsChanged(const display::Display& display, @@ -138,6 +139,10 @@ // not clipped. virtual void UpdateHostWindowBounds(); + bool client_submits_surfaces_in_pixel_coordinates() const { + return client_submits_surfaces_in_pixel_coordinates_; + } + private: viz::CompositorFrame PrepareToSubmitCompositorFrame(); @@ -172,6 +177,8 @@ int64_t display_id_ = display::kInvalidDisplayId; + bool client_submits_surfaces_in_pixel_coordinates_ = false; + base::WeakPtrFactory<SurfaceTreeHost> weak_ptr_factory_{this}; };
diff --git a/components/exo/wayland/protocol/aura-shell.xml b/components/exo/wayland/protocol/aura-shell.xml index 5118f0c2..3cbf2b2 100644 --- a/components/exo/wayland/protocol/aura-shell.xml +++ b/components/exo/wayland/protocol/aura-shell.xml
@@ -24,7 +24,7 @@ DEALINGS IN THE SOFTWARE. </copyright> - <interface name="zaura_shell" version="25"> + <interface name="zaura_shell" version="26"> <description summary="aura_shell"> The global interface exposing aura shell capabilities is used to instantiate an interface extension for a wl_surface object. @@ -108,6 +108,7 @@ </description> <arg name="active_desk_index" type="int" summary="index of the active desk"/> </event> + <!-- Version 24 additions --> <event name="activated" since="24"> <description summary="activated surface changed"> @@ -116,6 +117,16 @@ <arg name="gained_active" type="object" interface="wl_surface" allow-null="true"/> <arg name="lost_active" type="object" interface="wl_surface" allow-null="true"/> </event> + + <!-- Version 26 additions --> + <request name="surface_submission_in_pixel_coordinates" since="26"> + <description summary="surfaces will be submitted in pixel coordinates"> + Informs the server that when submitting surfaces, this client will not + use wl_surface_set_buffer_scale to report the scales, nor will it apply + scale via vp_viewporter. Instead the server should apply an appropriate + scale transform to have the submitted buffers composited correctly. + </description> + </request> </interface> <interface name="zaura_surface" version="25">
diff --git a/components/exo/wayland/zaura_shell.cc b/components/exo/wayland/zaura_shell.cc index 0f3a0c4..8aed4ea 100644 --- a/components/exo/wayland/zaura_shell.cc +++ b/components/exo/wayland/zaura_shell.cc
@@ -766,6 +766,12 @@ const std::u16string& new_name) override { OnDesksChanged(); } + void set_client_submits_surfaces_in_pixel_coordinates(bool enabled) { + client_submits_surfaces_in_pixel_coordinates_ = enabled; + } + bool client_submits_surfaces_in_pixel_coordinates() const { + return client_submits_surfaces_in_pixel_coordinates_; + } private: void OnDesksChanged() { @@ -826,6 +832,8 @@ // The aura shell resource associated with observer. wl_resource* const aura_shell_resource_; + bool client_submits_surfaces_in_pixel_coordinates_ = false; + base::WeakPtrFactory<WaylandAuraShell> weak_ptr_factory_{this}; }; #endif // BUILDFLAG(IS_CHROMEOS_ASH)) @@ -842,6 +850,14 @@ return; } +#if BUILDFLAG(IS_CHROMEOS_ASH) + if (WaylandAuraShell* aura_shell = + GetUserDataAs<WaylandAuraShell>(resource)) { + surface->SetClientSubmitsSurfacesInPixelCoordinates( + aura_shell->client_submits_surfaces_in_pixel_coordinates()); + } +#endif // BUILDFLAG(IS_CHROMEOS_ASH)) + wl_resource* aura_surface_resource = wl_resource_create( client, &zaura_surface_interface, wl_resource_get_version(resource), id); @@ -866,11 +882,17 @@ SetImplementation(aura_output_resource, nullptr, std::move(aura_output)); } -const struct zaura_shell_interface aura_shell_implementation = { - aura_shell_get_aura_surface, - aura_shell_get_aura_output, -}; +void aura_shell_surface_submission_in_pixel_coordinates(wl_client* client, + wl_resource* resource) { +#if BUILDFLAG(IS_CHROMEOS_ASH) + if (WaylandAuraShell* aura_shell = GetUserDataAs<WaylandAuraShell>(resource)) + aura_shell->set_client_submits_surfaces_in_pixel_coordinates(true); +#endif // BUILDFLAG(IS_CHROMEOS_ASH)) +} +const struct zaura_shell_interface aura_shell_implementation = { + aura_shell_get_aura_surface, aura_shell_get_aura_output, + aura_shell_surface_submission_in_pixel_coordinates}; } // namespace void bind_aura_shell(wl_client* client,
diff --git a/components/exo/wayland/zaura_shell.h b/components/exo/wayland/zaura_shell.h index 9c2a72e..f51497f 100644 --- a/components/exo/wayland/zaura_shell.h +++ b/components/exo/wayland/zaura_shell.h
@@ -18,7 +18,7 @@ namespace exo { namespace wayland { -constexpr uint32_t kZAuraShellVersion = 25; +constexpr uint32_t kZAuraShellVersion = 26; // Adds bindings to the Aura Shell. Normally this implies Ash on ChromeOS // builds. On non-ChromeOS builds the protocol provides access to Aura windowing
diff --git a/components/exo/wayland/zaura_shell_unittest.cc b/components/exo/wayland/zaura_shell_unittest.cc index 24e16cac..ceb0fcd 100644 --- a/components/exo/wayland/zaura_shell_unittest.cc +++ b/components/exo/wayland/zaura_shell_unittest.cc
@@ -117,6 +117,10 @@ (override)); MOCK_METHOD(void, Pin, (bool trusted), (override)); MOCK_METHOD(void, Unpin, (), (override)); + MOCK_METHOD(void, + SetClientSubmitsSurfacesInPixelCoordinates, + (bool), + (override)); }; } // namespace
diff --git a/components/exo/wayland/zcr_remote_shell_impl.cc b/components/exo/wayland/zcr_remote_shell_impl.cc index c36259f..66a491c 100644 --- a/components/exo/wayland/zcr_remote_shell_impl.cc +++ b/components/exo/wayland/zcr_remote_shell_impl.cc
@@ -4,6 +4,7 @@ #include "components/exo/wayland/zcr_remote_shell_impl.h" +#include "ash/public/cpp/arc_resize_lock_type.h" #include "ash/shelf/shelf_layout_manager.h" #include "ash/shell.h" #include "ash/wm/window_resizer.h" @@ -1400,12 +1401,14 @@ } void remote_surface_set_resize_lock(wl_client* client, wl_resource* resource) { - GetUserDataAs<ClientControlledShellSurface>(resource)->SetResizeLock(true); + GetUserDataAs<ClientControlledShellSurface>(resource)->SetResizeLockType( + ash::ArcResizeLockType::RESIZE_DISABLED_TOGGLABLE); } void remote_surface_unset_resize_lock(wl_client* client, wl_resource* resource) { - GetUserDataAs<ClientControlledShellSurface>(resource)->SetResizeLock(false); + GetUserDataAs<ClientControlledShellSurface>(resource)->SetResizeLockType( + ash::ArcResizeLockType::NONE); } void remote_surface_set_bounds_in_output(wl_client* client, @@ -1422,6 +1425,13 @@ display_handler->id(), gfx::Rect(x, y, width, height)); } +void remote_surface_set_resize_lock_type(wl_client* client, + wl_resource* resource, + uint32_t type) { + GetUserDataAs<ClientControlledShellSurface>(resource)->SetResizeLockType( + static_cast<ash::ArcResizeLockType>(type)); +} + //////////////////////////////////////////////////////////////////////////////// // notification_surface_interface:
diff --git a/components/exo/wayland/zcr_remote_shell_impl.h b/components/exo/wayland/zcr_remote_shell_impl.h index d532f21..75382de 100644 --- a/components/exo/wayland/zcr_remote_shell_impl.h +++ b/components/exo/wayland/zcr_remote_shell_impl.h
@@ -334,6 +334,10 @@ int32_t width, int32_t height); +void remote_surface_set_resize_lock_type(wl_client* client, + wl_resource* resource, + uint32_t mode); + void remote_surface_block_ime(wl_client* client, wl_resource* resource); void remote_surface_unblock_ime(wl_client* client, wl_resource* resource);
diff --git a/components/exo/wayland/zcr_remote_shell_v2.cc b/components/exo/wayland/zcr_remote_shell_v2.cc index 7edfaa0..8d7196f 100644 --- a/components/exo/wayland/zcr_remote_shell_v2.cc +++ b/components/exo/wayland/zcr_remote_shell_v2.cc
@@ -105,6 +105,7 @@ zcr_remote_shell::remote_surface_set_resize_lock, zcr_remote_shell::remote_surface_unset_resize_lock, zcr_remote_shell::remote_surface_set_bounds_in_output, + zcr_remote_shell::remote_surface_set_resize_lock_type, }; const struct zcr_notification_surface_v2_interface
diff --git a/components/keep_alive_registry/keep_alive_registry.cc b/components/keep_alive_registry/keep_alive_registry.cc index 913402e..0f77ce7 100644 --- a/components/keep_alive_registry/keep_alive_registry.cc +++ b/components/keep_alive_registry/keep_alive_registry.cc
@@ -23,7 +23,7 @@ } bool KeepAliveRegistry::IsKeepingAlive() const { - return registered_count_ > 0; + return registered_count_ > 0 && !(IsRestartAllowed() && is_restarting_); } bool KeepAliveRegistry::IsKeepingAliveOnlyByBrowserOrigin() const { @@ -88,6 +88,21 @@ is_shutting_down_ = value; } +bool KeepAliveRegistry::IsRestarting() const { + return is_restarting_; +} + +void KeepAliveRegistry::SetRestarting() { + bool old_keeping_alive = IsKeepingAlive(); + is_restarting_ = true; + bool new_keeping_alive = IsKeepingAlive(); + + // keep alive state can be updated by |is_restarting_| change. + // If that happens, notify observers. + if (old_keeping_alive != new_keeping_alive) + OnKeepAliveStateChanged(new_keeping_alive); +} + //////////////////////////////////////////////////////////////////////////////// // Private methods
diff --git a/components/keep_alive_registry/keep_alive_registry.h b/components/keep_alive_registry/keep_alive_registry.h index e75d1ea..f80e223 100644 --- a/components/keep_alive_registry/keep_alive_registry.h +++ b/components/keep_alive_registry/keep_alive_registry.h
@@ -51,6 +51,12 @@ // Call when shutting down to ensure registering a new KeepAlive CHECKs. void SetIsShuttingDown(bool value = true); + // True if restarting is in progress. + bool IsRestarting() const; + + // Called when restarting is triggered. + void SetRestarting(); + private: friend struct base::DefaultSingletonTraits<KeepAliveRegistry>; // Friend to be able to use Register/Unregister @@ -100,6 +106,9 @@ // Used to guard against registering during shutdown. bool is_shutting_down_ = false; + // Used to handle KeepAliveRestartOption::ENABLED. + bool is_restarting_ = false; + base::ObserverList<KeepAliveStateObserver>::Unchecked observers_; };
diff --git a/components/keep_alive_registry/keep_alive_registry_unittest.cc b/components/keep_alive_registry/keep_alive_registry_unittest.cc index cc4cba7..05bfbc3 100644 --- a/components/keep_alive_registry/keep_alive_registry_unittest.cc +++ b/components/keep_alive_registry/keep_alive_registry_unittest.cc
@@ -137,6 +137,70 @@ EXPECT_EQ(0, on_restart_forbidden_call_count_); } +// Check that KeepAliveState is changed on attempting restarting, +// if the remaining keepalive is only RestartOption::ENABLED. +TEST_F(KeepAliveRegistryTest, AttemptRestarting) { + std::unique_ptr<ScopedKeepAlive> keep_alive, keep_alive_restart; + + EXPECT_EQ(0, on_restart_allowed_call_count_); + EXPECT_EQ(0, on_restart_forbidden_call_count_); + + // With a normal keep alive, restart should not be allowed + keep_alive = std::make_unique<ScopedKeepAlive>( + KeepAliveOrigin::CHROME_APP_DELEGATE, KeepAliveRestartOption::DISABLED); + ASSERT_EQ(1, start_keep_alive_call_count_--); // decrement to ack + ASSERT_EQ(1, on_restart_forbidden_call_count_--); + + // Restart should not be allowed if all KA don't allow it. + keep_alive_restart = std::make_unique<ScopedKeepAlive>( + KeepAliveOrigin::CHROME_APP_DELEGATE, KeepAliveRestartOption::ENABLED); + // No state change. + EXPECT_EQ(0, start_keep_alive_call_count_); + EXPECT_EQ(0, on_restart_allowed_call_count_); + + // Now restart should be allowed, the only one left allows it. + keep_alive.reset(); + EXPECT_EQ(0, start_keep_alive_call_count_); + ASSERT_EQ(1, on_restart_allowed_call_count_--); + EXPECT_TRUE(registry_->IsRestartAllowed()); + + // Trigger the restarting procedure. + registry_->SetRestarting(); + ASSERT_EQ(1, stop_keep_alive_call_count_); +} + +TEST_F(KeepAliveRegistryTest, + AttemptRestartingBeforeDestroyingDisabledKeepAlive) { + std::unique_ptr<ScopedKeepAlive> keep_alive, keep_alive_restart; + + EXPECT_EQ(0, on_restart_allowed_call_count_); + EXPECT_EQ(0, on_restart_forbidden_call_count_); + + // With a normal keep alive, restart should not be allowed + keep_alive = std::make_unique<ScopedKeepAlive>( + KeepAliveOrigin::CHROME_APP_DELEGATE, KeepAliveRestartOption::DISABLED); + ASSERT_EQ(1, start_keep_alive_call_count_--); // decrement to ack + ASSERT_EQ(1, on_restart_forbidden_call_count_--); + + // Restart should not be allowed if all KA don't allow it. + keep_alive_restart = std::make_unique<ScopedKeepAlive>( + KeepAliveOrigin::CHROME_APP_DELEGATE, KeepAliveRestartOption::ENABLED); + // No state change. + EXPECT_EQ(0, start_keep_alive_call_count_); + EXPECT_EQ(0, on_restart_allowed_call_count_); + + // Trigger the restarting procedure, during normal keep alive is still + // active. + registry_->SetRestarting(); + EXPECT_EQ(0, stop_keep_alive_call_count_); + + // Now restart should be allowed, the only one left allows it. + // This also updates KeepAliveState. + keep_alive.reset(); + ASSERT_EQ(1, stop_keep_alive_call_count_--); + ASSERT_EQ(1, on_restart_allowed_call_count_--); +} + TEST_F(KeepAliveRegistryTest, WouldRestartWithoutTest) { // WouldRestartWithout() should have the same results as IsRestartAllowed() // when called with an empty vector.
diff --git a/components/services/app_service/public/cpp/BUILD.gn b/components/services/app_service/public/cpp/BUILD.gn index 06a432c..9eaf622 100644 --- a/components/services/app_service/public/cpp/BUILD.gn +++ b/components/services/app_service/public/cpp/BUILD.gn
@@ -215,6 +215,14 @@ deps = [ "//components/services/app_service/public/mojom" ] } +source_set("permission_utils") { + sources = [ + "permission_utils.cc", + "permission_utils.h", + ] + deps = [ "//components/services/app_service/public/mojom" ] +} + source_set("unit_tests") { testonly = true
diff --git a/components/services/app_service/public/cpp/app_update.cc b/components/services/app_service/public/cpp/app_update.cc index 102867f..341843e 100644 --- a/components/services/app_service/public/cpp/app_update.cc +++ b/components/services/app_service/public/cpp/app_update.cc
@@ -629,7 +629,13 @@ out << "Permissions:" << std::endl; for (const auto& permission : app.Permissions()) { out << " ID: " << permission->permission_type; - out << " value: " << permission->value; + out << " value: " << std::endl; + if (permission->value->is_bool_value()) { + out << " bool_value: " << permission->value->get_bool_value(); + } + if (permission->value->is_tristate_value()) { + out << " tristate_value: " << permission->value->get_tristate_value(); + } out << " is_managed: " << permission->is_managed << std::endl; }
diff --git a/components/services/app_service/public/cpp/app_update_unittest.cc b/components/services/app_service/public/cpp/app_update_unittest.cc index 1a0fd60..c432eda9 100644 --- a/components/services/app_service/public/cpp/app_update_unittest.cc +++ b/components/services/app_service/public/cpp/app_update_unittest.cc
@@ -101,8 +101,8 @@ apps::mojom::TriState value) { apps::mojom::PermissionPtr permission = apps::mojom::Permission::New(); permission->permission_type = permission_type; - permission->value_type = apps::mojom::PermissionValueType::kTriState; - permission->value = static_cast<uint32_t>(value); + permission->value = apps::mojom::PermissionValue::New(); + permission->value->set_tristate_value(value); return permission; }
diff --git a/components/services/app_service/public/cpp/permission_utils.cc b/components/services/app_service/public/cpp/permission_utils.cc new file mode 100644 index 0000000..fd6dd61 --- /dev/null +++ b/components/services/app_service/public/cpp/permission_utils.cc
@@ -0,0 +1,20 @@ +// 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 "components/services/app_service/public/cpp/permission_utils.h" + +namespace apps_util { + +bool IsPermissionEnabled( + const apps::mojom::PermissionValuePtr& permission_value) { + if (permission_value->is_tristate_value()) { + return permission_value->get_tristate_value() == + apps::mojom::TriState::kAllow; + } else if (permission_value->is_bool_value()) { + return permission_value->get_bool_value(); + } + return false; +} + +} // namespace apps_util
diff --git a/components/services/app_service/public/cpp/permission_utils.h b/components/services/app_service/public/cpp/permission_utils.h new file mode 100644 index 0000000..cde4f45 --- /dev/null +++ b/components/services/app_service/public/cpp/permission_utils.h
@@ -0,0 +1,20 @@ +// 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 COMPONENTS_SERVICES_APP_SERVICE_PUBLIC_CPP_PERMISSION_UTILS_H_ +#define COMPONENTS_SERVICES_APP_SERVICE_PUBLIC_CPP_PERMISSION_UTILS_H_ + +#include "components/services/app_service/public/mojom/types.mojom.h" + +namespace apps_util { + +// Check whether the |permission_value| equavalent to permission enabled. +// The permission value could be a TriState or a bool. If it is TriState, +// only Allow represent permission enabled. +bool IsPermissionEnabled( + const apps::mojom::PermissionValuePtr& permission_value); + +} // namespace apps_util + +#endif // COMPONENTS_SERVICES_APP_SERVICE_PUBLIC_CPP_PERMISSION_UTILS_H_
diff --git a/components/services/app_service/public/mojom/types.mojom b/components/services/app_service/public/mojom/types.mojom index 82a47a1..d73af3a 100644 --- a/components/services/app_service/public/mojom/types.mojom +++ b/components/services/app_service/public/mojom/types.mojom
@@ -89,9 +89,7 @@ struct Permission { PermissionType permission_type; - PermissionValueType value_type; - // The semantics of value depends on the value_type. - uint32 value; + PermissionValue value; // If the permission is managed by an enterprise policy. bool is_managed; }; @@ -282,9 +280,9 @@ kAsk, }; -enum PermissionValueType { - kBool, // Permission.value is a Bool (either 0 or 1). - kTriState, // Permission.value is a TriState. +union PermissionValue { + bool bool_value; + TriState tristate_value; }; // MenuItems are used to populate context menus, e.g. in the app list or shelf.
diff --git a/components/test/data/web_package/24_responses.har b/components/test/data/web_package/24_responses.har new file mode 100644 index 0000000..a997299 --- /dev/null +++ b/components/test/data/web_package/24_responses.har
@@ -0,0 +1,439 @@ +{ + "log": { + "version": "1.2", + "entries": [ + { + "request": { + "method": "GET", + "url": "https://test.example.org/0" + }, + "response": { + "status": 200, + "headers": [ + { + "name": "Content-Type", + "value": "text/html;" + } + ], + "content": { + "text": "<p>Hello Web Bundles!</p>" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://test.example.org/1" + }, + "response": { + "status": 200, + "headers": [ + { + "name": "Content-Type", + "value": "text/html;" + } + ], + "content": { + "text": "<p>Hello Web Bundles!</p>" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://test.example.org/2" + }, + "response": { + "status": 200, + "headers": [ + { + "name": "Content-Type", + "value": "text/html;" + } + ], + "content": { + "text": "<p>Hello Web Bundles!</p>" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://test.example.org/3" + }, + "response": { + "status": 200, + "headers": [ + { + "name": "Content-Type", + "value": "text/html;" + } + ], + "content": { + "text": "<p>Hello Web Bundles!</p>" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://test.example.org/4" + }, + "response": { + "status": 200, + "headers": [ + { + "name": "Content-Type", + "value": "text/html;" + } + ], + "content": { + "text": "<p>Hello Web Bundles!</p>" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://test.example.org/5" + }, + "response": { + "status": 200, + "headers": [ + { + "name": "Content-Type", + "value": "text/html;" + } + ], + "content": { + "text": "<p>Hello Web Bundles!</p>" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://test.example.org/6" + }, + "response": { + "status": 200, + "headers": [ + { + "name": "Content-Type", + "value": "text/html;" + } + ], + "content": { + "text": "<p>Hello Web Bundles!</p>" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://test.example.org/7" + }, + "response": { + "status": 200, + "headers": [ + { + "name": "Content-Type", + "value": "text/html;" + } + ], + "content": { + "text": "<p>Hello Web Bundles!</p>" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://test.example.org/8" + }, + "response": { + "status": 200, + "headers": [ + { + "name": "Content-Type", + "value": "text/html;" + } + ], + "content": { + "text": "<p>Hello Web Bundles!</p>" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://test.example.org/9" + }, + "response": { + "status": 200, + "headers": [ + { + "name": "Content-Type", + "value": "text/html;" + } + ], + "content": { + "text": "<p>Hello Web Bundles!</p>" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://test.example.org/10" + }, + "response": { + "status": 200, + "headers": [ + { + "name": "Content-Type", + "value": "text/html;" + } + ], + "content": { + "text": "<p>Hello Web Bundles!</p>" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://test.example.org/11" + }, + "response": { + "status": 200, + "headers": [ + { + "name": "Content-Type", + "value": "text/html;" + } + ], + "content": { + "text": "<p>Hello Web Bundles!</p>" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://test.example.org/12" + }, + "response": { + "status": 200, + "headers": [ + { + "name": "Content-Type", + "value": "text/html;" + } + ], + "content": { + "text": "<p>Hello Web Bundles!</p>" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://test.example.org/13" + }, + "response": { + "status": 200, + "headers": [ + { + "name": "Content-Type", + "value": "text/html;" + } + ], + "content": { + "text": "<p>Hello Web Bundles!</p>" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://test.example.org/14" + }, + "response": { + "status": 200, + "headers": [ + { + "name": "Content-Type", + "value": "text/html;" + } + ], + "content": { + "text": "<p>Hello Web Bundles!</p>" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://test.example.org/15" + }, + "response": { + "status": 200, + "headers": [ + { + "name": "Content-Type", + "value": "text/html;" + } + ], + "content": { + "text": "<p>Hello Web Bundles!</p>" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://test.example.org/16" + }, + "response": { + "status": 200, + "headers": [ + { + "name": "Content-Type", + "value": "text/html;" + } + ], + "content": { + "text": "<p>Hello Web Bundles!</p>" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://test.example.org/17" + }, + "response": { + "status": 200, + "headers": [ + { + "name": "Content-Type", + "value": "text/html;" + } + ], + "content": { + "text": "<p>Hello Web Bundles!</p>" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://test.example.org/18" + }, + "response": { + "status": 200, + "headers": [ + { + "name": "Content-Type", + "value": "text/html;" + } + ], + "content": { + "text": "<p>Hello Web Bundles!</p>" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://test.example.org/19" + }, + "response": { + "status": 200, + "headers": [ + { + "name": "Content-Type", + "value": "text/html;" + } + ], + "content": { + "text": "<p>Hello Web Bundles!</p>" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://test.example.org/20" + }, + "response": { + "status": 200, + "headers": [ + { + "name": "Content-Type", + "value": "text/html;" + } + ], + "content": { + "text": "<p>Hello Web Bundles!</p>" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://test.example.org/21" + }, + "response": { + "status": 200, + "headers": [ + { + "name": "Content-Type", + "value": "text/html;" + } + ], + "content": { + "text": "<p>Hello Web Bundles!</p>" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://test.example.org/22" + }, + "response": { + "status": 200, + "headers": [ + { + "name": "Content-Type", + "value": "text/html;" + } + ], + "content": { + "text": "<p>Hello Web Bundles!</p>" + } + } + }, + { + "request": { + "method": "GET", + "url": "https://test.example.org/23" + }, + "response": { + "status": 200, + "headers": [ + { + "name": "Content-Type", + "value": "text/html;" + } + ], + "content": { + "text": "<p>Hello Web Bundles!</p>" + } + } + } + ] + } +}
diff --git a/components/test/data/web_package/24_responses.wbn b/components/test/data/web_package/24_responses.wbn new file mode 100644 index 0000000..7767b17 --- /dev/null +++ b/components/test/data/web_package/24_responses.wbn Binary files differ
diff --git a/components/test/data/web_package/generate-test-wbns.sh b/components/test/data/web_package/generate-test-wbns.sh index ff98865..42504b5 100755 --- a/components/test/data/web_package/generate-test-wbns.sh +++ b/components/test/data/web_package/generate-test-wbns.sh
@@ -39,6 +39,11 @@ -o simple.wbn \ -primaryURL https://test.example.org/ \ +gen-bundle \ + -version b2 \ + -har 24_responses.har + -o 24_responses.wbn + sign-bundle \ -i hello.wbn \ -certificate $sxg_test_data_dir/test.example.org.public.pem.cbor \
diff --git a/components/web_package/BUILD.gn b/components/web_package/BUILD.gn index 709d321..e868b36 100644 --- a/components/web_package/BUILD.gn +++ b/components/web_package/BUILD.gn
@@ -6,6 +6,8 @@ static_library("web_package") { sources = [ + "web_bundle_builder.cc", + "web_bundle_builder.h", "web_bundle_parser.cc", "web_bundle_parser.h", "web_bundle_parser_factory.cc", @@ -25,28 +27,15 @@ public_deps = [ "//components/web_package/mojom" ] } -static_library("test_support") { - testonly = true - sources = [ - "test_support/web_bundle_builder.cc", - "test_support/web_bundle_builder.h", - ] - - deps = [ - "//base", - "//components/cbor", - ] -} - source_set("unit_tests") { testonly = true sources = [ + "web_bundle_builder_unittest.cc", "web_bundle_parser_factory_unittest.cc", "web_bundle_parser_unittest.cc", "web_bundle_utils_unittest.cc", ] deps = [ - ":test_support", ":web_package", "//base/test:test_support", "//components/cbor",
diff --git a/components/web_package/test_support/web_bundle_builder.cc b/components/web_package/web_bundle_builder.cc similarity index 63% rename from components/web_package/test_support/web_bundle_builder.cc rename to components/web_package/web_bundle_builder.cc index 3f9b9a44..d538c70 100644 --- a/components/web_package/test_support/web_bundle_builder.cc +++ b/components/web_package/web_bundle_builder.cc
@@ -2,12 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/web_package/test_support/web_bundle_builder.h" +#include "components/web_package/web_bundle_builder.h" #include <ostream> +#include "base/big_endian.h" + namespace web_package { -namespace test { namespace { @@ -22,24 +23,45 @@ return cbor::Value(std::move(map)); } +// TODO(myrzakereyms): replace this method with cbor::writer::GetNumUintBytes. +uint64_t GetNumUintBytes(uint64_t value) { + if (value < 24) { + return 0; + } else if (value <= 0xFF) { + return 1; + } else if (value <= 0xFFFF) { + return 2; + } else if (value <= 0xFFFFFFFF) { + return 4; + } + return 8; +} + } // namespace WebBundleBuilder::WebBundleBuilder(const std::string& fallback_url, const std::string& manifest_url, - BundleVersion version) + BundleVersion version, + bool allow_invalid_utf8_strings_for_testing) : fallback_url_(fallback_url), version_(version) { - writer_config_.allow_invalid_utf8_for_testing = true; + writer_config_.allow_invalid_utf8_for_testing = + allow_invalid_utf8_strings_for_testing; if (!manifest_url.empty()) { - AddSection("manifest", - cbor::Value::InvalidUTF8StringValueForTesting(manifest_url)); + AddSection("manifest", GetCborValueOfURL(manifest_url)); } if (version == BundleVersion::kB2 && !fallback_url_.empty()) { - AddSection("primary", - cbor::Value::InvalidUTF8StringValueForTesting(fallback_url_)); + AddSection("primary", GetCborValueOfURL(fallback_url_)); } } WebBundleBuilder::~WebBundleBuilder() = default; +cbor::Value WebBundleBuilder::GetCborValueOfURL(base::StringPiece url) { + if (writer_config_.allow_invalid_utf8_for_testing) { + return cbor::Value::InvalidUTF8StringValueForTesting(url); + } + return cbor::Value(url); +} + void WebBundleBuilder::AddExchange(base::StringPiece url, const Headers& response_headers, base::StringPiece payload) { @@ -49,11 +71,6 @@ WebBundleBuilder::ResponseLocation WebBundleBuilder::AddResponse( const Headers& headers, base::StringPiece payload) { - // We assume that the size of the CBOR header of the responses array is 1, - // which is true only if the responses array has no more than 23 elements. - DCHECK_LT(responses_.size(), 23u) - << "WebBundleBuilder cannot create bundles with more than 23 responses"; - cbor::Value::ArrayValue response_array; response_array.emplace_back(Encode(CreateHeaderMap(headers))); response_array.emplace_back(CreateByteString(payload)); @@ -69,19 +86,13 @@ base::StringPiece url, base::StringPiece variants_value, std::vector<ResponseLocation> response_locations) { - cbor::Value::ArrayValue index_value_array; // 'b2' version does not include |variants_value| in the response array. - if (version_ == BundleVersion::kB1) { - index_value_array.emplace_back(CreateByteString(variants_value)); - } else { + if (version_ != BundleVersion::kB1) { DCHECK_EQ(response_locations.size(), 1u); } - for (const auto& location : response_locations) { - index_value_array.emplace_back(location.offset); - index_value_array.emplace_back(location.length); - } - index_.insert({cbor::Value::InvalidUTF8StringValueForTesting(url), - cbor::Value(index_value_array)}); + delayed_index_.insert( + {std::string(url), std::make_pair(std::string(variants_value), + std::move(response_locations))}); } void WebBundleBuilder::AddSection(base::StringPiece name, cbor::Value section) { @@ -99,7 +110,26 @@ } std::vector<uint8_t> WebBundleBuilder::CreateBundle() { - AddSection("index", cbor::Value(index_)); + // Now that we know how many responses will be in the bundle, + // we want to shift all the offsets by the bytes required + // for the CBOR Array header and actually construct the index + // section. + int64_t initial_offset = 1 + GetNumUintBytes(responses_.size()); + cbor::Value::MapValue index; + for (auto& entry : delayed_index_) { + auto& index_entry = entry.second; + cbor::Value::ArrayValue index_value_array; + if (version_ == BundleVersion::kB1) { + index_value_array.emplace_back(CreateByteString(index_entry.first)); + } + for (auto& location : index_entry.second) { + index_value_array.emplace_back(location.offset + initial_offset); + index_value_array.emplace_back(location.length); + } + index.insert( + {GetCborValueOfURL(entry.first), cbor::Value(index_value_array)}); + } + AddSection("index", cbor::Value(index)); if (!authorities_.empty() || !vouched_subsets_.empty()) { cbor::Value::ArrayValue signatures_section; signatures_section.emplace_back(std::move(authorities_)); @@ -107,7 +137,7 @@ AddSection("signatures", cbor::Value(std::move(signatures_section))); } AddSection("responses", cbor::Value(responses_)); - return Encode(CreateTopLevel()); + return CreateTopLevel(); } cbor::Value WebBundleBuilder::CreateEncodedSigned( @@ -124,7 +154,7 @@ subset_hash_value.emplace_back(payload_integrity_header); cbor::Value::MapValue subset_hashes; - subset_hashes.emplace(url, std::move(subset_hash_value)); + subset_hashes.emplace(GetCborValueOfURL(url), std::move(subset_hash_value)); cbor::Value::MapValue signed_subset; signed_subset.emplace("validity-url", validity_url); @@ -135,23 +165,29 @@ return cbor::Value(Encode(cbor::Value(signed_subset))); } -cbor::Value WebBundleBuilder::CreateTopLevel() { +std::vector<uint8_t> WebBundleBuilder::CreateTopLevel() { cbor::Value::ArrayValue toplevel_array; toplevel_array.emplace_back( CreateByteString(u8"\U0001F310\U0001F4E6")); // "🌐📦" if (version_ == BundleVersion::kB1) { toplevel_array.emplace_back( CreateByteString(base::StringPiece("b1\0\0", 4))); - toplevel_array.emplace_back( - cbor::Value::InvalidUTF8StringValueForTesting(fallback_url_)); + toplevel_array.emplace_back(GetCborValueOfURL(fallback_url_)); } else { toplevel_array.emplace_back( CreateByteString(base::StringPiece("b2\0\0", 4))); } toplevel_array.emplace_back(Encode(cbor::Value(section_lengths_))); toplevel_array.emplace_back(sections_); - toplevel_array.emplace_back(CreateByteString("")); // length (ignored) - return cbor::Value(toplevel_array); + // Put a dummy 8-byte bytestring. + toplevel_array.emplace_back(cbor::Value::BinaryValue(8, 0)); + + std::vector<uint8_t> bundle = Encode(cbor::Value(toplevel_array)); + char encoded[8]; + base::WriteBigEndian(encoded, static_cast<uint64_t>(bundle.size())); + // Overwrite the dummy bytestring with the actual size. + memcpy(bundle.data() + bundle.size() - 8, encoded, 8); + return bundle; } std::vector<uint8_t> WebBundleBuilder::Encode(const cbor::Value& value) { @@ -162,5 +198,4 @@ return Encode(value).size(); } -} // namespace test } // namespace web_package
diff --git a/components/web_package/test_support/web_bundle_builder.h b/components/web_package/web_bundle_builder.h similarity index 79% rename from components/web_package/test_support/web_bundle_builder.h rename to components/web_package/web_bundle_builder.h index 898301c..e7a649a 100644 --- a/components/web_package/test_support/web_bundle_builder.h +++ b/components/web_package/web_bundle_builder.h
@@ -2,9 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_WEB_PACKAGE_TEST_SUPPORT_WEB_BUNDLE_BUILDER_H_ -#define COMPONENTS_WEB_PACKAGE_TEST_SUPPORT_WEB_BUNDLE_BUILDER_H_ +#ifndef COMPONENTS_WEB_PACKAGE_WEB_BUNDLE_BUILDER_H_ +#define COMPONENTS_WEB_PACKAGE_WEB_BUNDLE_BUILDER_H_ +#include <map> #include <string> #include <utility> #include <vector> @@ -19,9 +20,7 @@ kB2, }; -namespace test { - -// This class can be used to create a Web Bundle binary in tests. +// This class can be used to create a Web Bundle. class WebBundleBuilder { public: using Headers = std::vector<std::pair<std::string, std::string>>; @@ -33,7 +32,8 @@ WebBundleBuilder(const std::string& fallback_url, const std::string& manifest_url, - BundleVersion version = BundleVersion::kB1); + BundleVersion version = BundleVersion::kB1, + bool allow_invalid_utf8_strings_for_testing = false); ~WebBundleBuilder(); @@ -64,8 +64,9 @@ base::StringPiece payload_integrity_header); private: - cbor::Value CreateTopLevel(); + std::vector<uint8_t> CreateTopLevel(); std::vector<uint8_t> Encode(const cbor::Value& value); + cbor::Value GetCborValueOfURL(base::StringPiece url); int64_t EncodedLength(const cbor::Value& value); @@ -73,17 +74,15 @@ std::string fallback_url_; cbor::Value::ArrayValue section_lengths_; cbor::Value::ArrayValue sections_; - cbor::Value::MapValue index_; + std::map<std::string, std::pair<std::string, std::vector<ResponseLocation>>> + delayed_index_; cbor::Value::ArrayValue responses_; cbor::Value::ArrayValue authorities_; cbor::Value::ArrayValue vouched_subsets_; BundleVersion version_; - - // 1 for the CBOR header byte. See the comment at the top of AddResponse(). - int64_t current_responses_offset_ = 1; + int64_t current_responses_offset_ = 0; }; -} // namespace test } // namespace web_package -#endif // COMPONENTS_WEB_PACKAGE_TEST_SUPPORT_WEB_BUNDLE_BUILDER_H_ +#endif // COMPONENTS_WEB_PACKAGE_WEB_BUNDLE_BUILDER_H_
diff --git a/components/web_package/web_bundle_builder_unittest.cc b/components/web_package/web_bundle_builder_unittest.cc new file mode 100644 index 0000000..4f6eeb186 --- /dev/null +++ b/components/web_package/web_bundle_builder_unittest.cc
@@ -0,0 +1,86 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/web_package/web_bundle_builder.h" + +#include "base/big_endian.h" +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/path_service.h" +#include "base/strings/string_number_conversions.h" +#include "base/test/task_environment.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace web_package { + +namespace { + +std::string kFallbackUrl = "https://test.example.org/"; + +std::string GetTestFileContents(const base::FilePath& path) { + base::FilePath test_data_dir; + base::PathService::Get(base::DIR_SOURCE_ROOT, &test_data_dir); + test_data_dir = test_data_dir.Append( + base::FilePath(FILE_PATH_LITERAL("components/test/data/web_package"))); + + std::string contents; + EXPECT_TRUE(base::ReadFileToString(test_data_dir.Append(path), &contents)); + return contents; +} + +std::vector<uint8_t> GetStringAsBytes(base::StringPiece contents) { + auto bytes = base::as_bytes(base::make_span(contents)); + return std::vector<uint8_t>(bytes.begin(), bytes.end()); +} + +} // namespace + +class WebBundleBuilderTest : public testing::Test { + private: + base::test::TaskEnvironment task_environment_; +}; + +TEST_F(WebBundleBuilderTest, CorrectWebBundleSizeIsWritten) { + WebBundleBuilder builder(kFallbackUrl, ""); + builder.AddExchange("https://test.example.com/", + {{":status", "200"}, {"content-type", "text/plain"}}, + "payload"); + std::vector<uint8_t> bundle = builder.CreateBundle(); + char written_size[8]; + memcpy(written_size, bundle.data() + bundle.size() - 8, 8); + uint64_t written_size_int; + base::ReadBigEndian(written_size, &written_size_int); + EXPECT_EQ(bundle.size(), written_size_int); +} + +TEST_F(WebBundleBuilderTest, ByteByByteComparison) { + WebBundleBuilder builder(kFallbackUrl, ""); + builder.AddExchange( + "https://test.example.org/", + {{":status", "200"}, {"content-type", "text/html; charset=UTF-8"}}, + "<a href='index.html'>click for web bundles</a>"); + builder.AddExchange( + "https://test.example.org/index.html", + {{":status", "200"}, {"content-type", "text/html; charset=UTF-8"}}, + "<p>Hello Web Bundles!</p>"); + std::vector<uint8_t> bundle = builder.CreateBundle(); + std::vector<uint8_t> expected_bundle = GetStringAsBytes( + GetTestFileContents(base::FilePath(FILE_PATH_LITERAL("simple.wbn")))); + EXPECT_EQ(bundle, expected_bundle); +} + +TEST_F(WebBundleBuilderTest, MoreThan23ResponsesInABundle) { + WebBundleBuilder builder("", "", BundleVersion::kB2); + for (int i = 0; i < 24; ++i) { + builder.AddExchange("https://test.example.org/" + base::NumberToString(i), + {{":status", "200"}, {"content-type", "text/html;"}}, + "<p>Hello Web Bundles!</p>"); + } + std::vector<uint8_t> bundle = builder.CreateBundle(); + std::vector<uint8_t> expected_bundle = GetStringAsBytes(GetTestFileContents( + base::FilePath(FILE_PATH_LITERAL("24_responses.wbn")))); + EXPECT_EQ(bundle, expected_bundle); +} + +} // namespace web_package
diff --git a/components/web_package/web_bundle_parser_unittest.cc b/components/web_package/web_bundle_parser_unittest.cc index fa2ebd4..35ebbc5 100644 --- a/components/web_package/web_bundle_parser_unittest.cc +++ b/components/web_package/web_bundle_parser_unittest.cc
@@ -10,7 +10,7 @@ #include "base/test/bind.h" #include "base/test/task_environment.h" #include "components/cbor/writer.h" -#include "components/web_package/test_support/web_bundle_builder.h" +#include "components/web_package/web_bundle_builder.h" #include "mojo/public/cpp/bindings/receiver_set.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -162,7 +162,7 @@ }; TEST_F(WebBundleParserTest, WrongMagic) { - test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl); + WebBundleBuilder builder(kFallbackUrl, kManifestUrl); std::vector<uint8_t> bundle = builder.CreateBundle(); bundle[3] ^= 1; TestDataSource data_source(bundle); @@ -174,7 +174,7 @@ } TEST_F(WebBundleParserTest, UnknownVersion) { - test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl); + WebBundleBuilder builder(kFallbackUrl, kManifestUrl); std::vector<uint8_t> bundle = builder.CreateBundle(); // Modify the version string from "b1\0\0" to "q1\0\0". ASSERT_EQ(bundle[11], 'b'); @@ -187,7 +187,8 @@ } TEST_F(WebBundleParserTest, FallbackURLIsNotUTF8) { - test::WebBundleBuilder builder("https://test.example.com/\xcc", kManifestUrl); + WebBundleBuilder builder("https://test.example.com/\xcc", kManifestUrl, + BundleVersion::kB1, true); std::vector<uint8_t> bundle = builder.CreateBundle(); TestDataSource data_source(bundle); @@ -198,8 +199,7 @@ } TEST_F(WebBundleParserTest, FallbackURLHasFragment) { - test::WebBundleBuilder builder("https://test.example.com/#fragment", - kManifestUrl); + WebBundleBuilder builder("https://test.example.com/#fragment", kManifestUrl); std::vector<uint8_t> bundle = builder.CreateBundle(); TestDataSource data_source(bundle); @@ -210,7 +210,7 @@ } TEST_F(WebBundleParserTest, SectionLengthsTooLarge) { - test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl); + WebBundleBuilder builder(kFallbackUrl, kManifestUrl); std::string too_long_section_name(8192, 'x'); builder.AddSection(too_long_section_name, cbor::Value(0)); TestDataSource data_source(builder.CreateBundle()); @@ -219,7 +219,7 @@ } TEST_F(WebBundleParserTest, DuplicateSectionName) { - test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl); + WebBundleBuilder builder(kFallbackUrl, kManifestUrl); builder.AddSection("foo", cbor::Value(0)); builder.AddSection("foo", cbor::Value(0)); TestDataSource data_source(builder.CreateBundle()); @@ -228,7 +228,7 @@ } TEST_F(WebBundleParserTest, SingleEntry) { - test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl); + WebBundleBuilder builder(kFallbackUrl, kManifestUrl); builder.AddExchange("https://test.example.com/", {{":status", "200"}, {"content-type", "text/plain"}}, "payload"); @@ -248,7 +248,7 @@ } TEST_F(WebBundleParserTest, InvalidRequestURL) { - test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl); + WebBundleBuilder builder(kFallbackUrl, kManifestUrl); builder.AddExchange("", {{":status", "200"}, {"content-type", "text/plain"}}, "payload"); TestDataSource data_source(builder.CreateBundle()); @@ -257,7 +257,8 @@ } TEST_F(WebBundleParserTest, RequestURLIsNotUTF8) { - test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl); + WebBundleBuilder builder(kFallbackUrl, kManifestUrl, BundleVersion::kB1, + true); builder.AddExchange("https://test.example.com/\xcc", {{":status", "200"}, {"content-type", "text/plain"}}, "payload"); @@ -267,7 +268,7 @@ } TEST_F(WebBundleParserTest, RequestURLHasBadScheme) { - test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl); + WebBundleBuilder builder(kFallbackUrl, kManifestUrl); builder.AddExchange("file:///tmp/foo", {{":status", "200"}, {"content-type", "text/plain"}}, "payload"); @@ -277,7 +278,7 @@ } TEST_F(WebBundleParserTest, RequestURLHasCredentials) { - test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl); + WebBundleBuilder builder(kFallbackUrl, kManifestUrl); builder.AddExchange("https://user:passwd@test.example.com/", {{":status", "200"}, {"content-type", "text/plain"}}, "payload"); @@ -287,7 +288,7 @@ } TEST_F(WebBundleParserTest, RequestURLHasFragment) { - test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl); + WebBundleBuilder builder(kFallbackUrl, kManifestUrl); builder.AddExchange("https://test.example.com/#fragment", {{":status", "200"}, {"content-type", "text/plain"}}, "payload"); @@ -298,7 +299,7 @@ TEST_F(WebBundleParserTest, RequestURLIsValidUrnUuid) { const char urn_uuid[] = "urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6"; - test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl); + WebBundleBuilder builder(kFallbackUrl, kManifestUrl); builder.AddExchange(urn_uuid, {{":status", "200"}, {"content-type", "text/plain"}}, "payload"); @@ -313,7 +314,7 @@ TEST_F(WebBundleParserTest, RequestURLIsInvalidUrnUuid) { const char urn_uuid[] = "urn:uuid:invalid"; - test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl); + WebBundleBuilder builder(kFallbackUrl, kManifestUrl); builder.AddExchange(urn_uuid, {{":status", "200"}, {"content-type", "text/plain"}}, "payload"); @@ -323,7 +324,7 @@ } TEST_F(WebBundleParserTest, NoStatusInResponseHeaders) { - test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl); + WebBundleBuilder builder(kFallbackUrl, kManifestUrl); builder.AddExchange("https://test.example.com/", {{"content-type", "text/plain"}}, "payload"); // ":status" is missing. @@ -337,7 +338,7 @@ } TEST_F(WebBundleParserTest, InvalidResponseStatus) { - test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl); + WebBundleBuilder builder(kFallbackUrl, kManifestUrl); builder.AddExchange("https://test.example.com/", {{":status", "0200"}, {"content-type", "text/plain"}}, "payload"); @@ -351,7 +352,7 @@ } TEST_F(WebBundleParserTest, ExtraPseudoInResponseHeaders) { - test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl); + WebBundleBuilder builder(kFallbackUrl, kManifestUrl); builder.AddExchange( "https://test.example.com/", {{":status", "200"}, {":foo", ""}, {"content-type", "text/plain"}}, @@ -366,7 +367,7 @@ } TEST_F(WebBundleParserTest, UpperCaseCharacterInHeaderName) { - test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl); + WebBundleBuilder builder(kFallbackUrl, kManifestUrl); builder.AddExchange("https://test.example.com/", {{":status", "200"}, {"Content-Type", "text/plain"}}, "payload"); @@ -380,7 +381,7 @@ } TEST_F(WebBundleParserTest, InvalidHeaderValue) { - test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl); + WebBundleBuilder builder(kFallbackUrl, kManifestUrl); builder.AddExchange("https://test.example.com/", {{":status", "200"}, {"content-type", "\n"}}, "payload"); TestDataSource data_source(builder.CreateBundle()); @@ -393,7 +394,7 @@ } TEST_F(WebBundleParserTest, NoContentTypeWithNonEmptyContent) { - test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl); + WebBundleBuilder builder(kFallbackUrl, kManifestUrl); builder.AddExchange("https://test.example.com/", {{":status", "200"}}, "payload"); TestDataSource data_source(builder.CreateBundle()); @@ -406,7 +407,7 @@ } TEST_F(WebBundleParserTest, NoContentTypeWithEmptyContent) { - test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl); + WebBundleBuilder builder(kFallbackUrl, kManifestUrl); builder.AddExchange("https://test.example.com/", {{":status", "301"}}, ""); TestDataSource data_source(builder.CreateBundle()); @@ -418,7 +419,7 @@ } TEST_F(WebBundleParserTest, Variants) { - test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl); + WebBundleBuilder builder(kFallbackUrl, kManifestUrl); auto location1 = builder.AddResponse( {{":status", "200"}, {"content-type", "text/html"}}, "payload1"); auto location2 = builder.AddResponse( @@ -447,7 +448,7 @@ } TEST_F(WebBundleParserTest, EmptyIndexEntry) { - test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl); + WebBundleBuilder builder(kFallbackUrl, kManifestUrl); builder.AddIndexEntry("https://test.example.com/", "", {}); TestDataSource data_source(builder.CreateBundle()); @@ -455,7 +456,7 @@ } TEST_F(WebBundleParserTest, EmptyIndexEntryWithVariants) { - test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl); + WebBundleBuilder builder(kFallbackUrl, kManifestUrl); builder.AddIndexEntry("https://test.example.com/", "Accept;text/html;text/plain", {}); TestDataSource data_source(builder.CreateBundle()); @@ -464,7 +465,7 @@ } TEST_F(WebBundleParserTest, MultipleResponsesWithoutVariantsValue) { - test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl); + WebBundleBuilder builder(kFallbackUrl, kManifestUrl); auto location1 = builder.AddResponse( {{":status", "200"}, {"content-type", "text/html"}}, "payload1"); auto location2 = builder.AddResponse( @@ -477,7 +478,7 @@ } TEST_F(WebBundleParserTest, AllKnownSectionInCritical) { - test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl); + WebBundleBuilder builder(kFallbackUrl, kManifestUrl); builder.AddExchange("https://test.example.com/", {{":status", "200"}, {"content-type", "text/plain"}}, "payload"); @@ -494,7 +495,7 @@ } TEST_F(WebBundleParserTest, UnknownSectionInCritical) { - test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl); + WebBundleBuilder builder(kFallbackUrl, kManifestUrl); builder.AddExchange("https://test.example.com/", {{":status", "200"}, {"content-type", "text/plain"}}, "payload"); @@ -507,7 +508,7 @@ } TEST_F(WebBundleParserTest, NoManifest) { - test::WebBundleBuilder builder(kFallbackUrl, std::string()); + WebBundleBuilder builder(kFallbackUrl, std::string()); builder.AddExchange("https://test.example.com/", {{":status", "200"}, {"content-type", "text/plain"}}, "payload"); @@ -518,7 +519,7 @@ } TEST_F(WebBundleParserTest, InvalidManifestURL) { - test::WebBundleBuilder builder(kFallbackUrl, "not-an-absolute-url"); + WebBundleBuilder builder(kFallbackUrl, "not-an-absolute-url"); builder.AddExchange("https://test.example.com/", {{":status", "200"}, {"content-type", "text/plain"}}, "payload"); @@ -528,11 +529,11 @@ } TEST_F(WebBundleParserTest, EmptySignaturesSection) { - test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl); + WebBundleBuilder builder(kFallbackUrl, kManifestUrl); builder.AddExchange("https://test.example.com/", {{":status", "200"}, {"content-type", "text/plain"}}, "payload"); - // test::WebBundleBuilder omits signatures section if empty, so create it + // WebBundleBuilder omits signatures section if empty, so create it // ourselves. cbor::Value::ArrayValue signatures_section; signatures_section.emplace_back(cbor::Value::ArrayValue()); // authorities @@ -548,7 +549,7 @@ } TEST_F(WebBundleParserTest, SignaturesSection) { - test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl); + WebBundleBuilder builder(kFallbackUrl, kManifestUrl); builder.AddExchange("https://test.example.com/", {{":status", "200"}, {"content-type", "text/plain"}}, "payload"); @@ -607,7 +608,7 @@ } TEST_F(WebBundleParserTest, MultipleSignatures) { - test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl); + WebBundleBuilder builder(kFallbackUrl, kManifestUrl); builder.AddExchange("https://test.example.com/", {{":status", "200"}, {"content-type", "text/plain"}}, "payload"); @@ -757,8 +758,7 @@ } TEST_F(WebBundleParserTest, B2BundleSingleEntry) { - test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl, - BundleVersion::kB2); + WebBundleBuilder builder(kFallbackUrl, kManifestUrl, BundleVersion::kB2); builder.AddExchange("https://test.example.com/", {{":status", "200"}, {"content-type", "text/plain"}}, "payload"); @@ -779,7 +779,7 @@ } TEST_F(WebBundleParserTest, B2BundleNoPrimaryUrlSingleEntry) { - test::WebBundleBuilder builder("", kManifestUrl, BundleVersion::kB2); + WebBundleBuilder builder("", kManifestUrl, BundleVersion::kB2); builder.AddExchange("https://test.example.com/", {{":status", "200"}, {"content-type", "text/plain"}}, "payload"); @@ -803,8 +803,8 @@ constexpr BundleVersion kVersions[] = {BundleVersion::kB1, BundleVersion::kB2}; for (const auto& version : kVersions) { - test::WebBundleBuilder builder("path/to/primary_url", "path/to/manifest", - version); + WebBundleBuilder builder("path/to/primary_url", "path/to/manifest", + version); builder.AddExchange("path/to/file.txt", {{":status", "200"}, {"content-type", "text/plain"}}, "payload");
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index efea3b7c..656f9ee 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -1737,7 +1737,6 @@ "screenlock_monitor/screenlock_monitor_source.cc", "screenlock_monitor/screenlock_monitor_source.h", "service_process_host_impl.cc", - "service_sandbox_type.h", "service_worker/embedded_worker_instance.cc", "service_worker/embedded_worker_instance.h", "service_worker/embedded_worker_status.h",
diff --git a/content/browser/OWNERS b/content/browser/OWNERS index 2dcab7c8..a273dc6 100644 --- a/content/browser/OWNERS +++ b/content/browser/OWNERS
@@ -33,9 +33,6 @@ per-file sandbox_ipc_linux.*=file://sandbox/linux/OWNERS per-file utility_process_sandbox_browsertest.cc=file://sandbox/linux/OWNERS -# Service sandbox mappings require security review -per-file service_sandbox_type.h=file://ipc/SECURITY_OWNERS - # Utility sandbox delegate requires security review. per-file utility_sandbox_delegate.*=set noparent per-file utility_sandbox_delegate.*=file://ipc/SECURITY_OWNERS
diff --git a/content/browser/audio/audio_service.cc b/content/browser/audio/audio_service.cc index cc211f8..6d263c0 100644 --- a/content/browser/audio/audio_service.cc +++ b/content/browser/audio/audio_service.cc
@@ -12,7 +12,6 @@ #include "base/time/time.h" #include "build/build_config.h" #include "content/browser/browser_main_loop.h" -#include "content/browser/service_sandbox_type.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/content_browser_client.h" @@ -24,6 +23,7 @@ #include "media/base/media_switches.h" #include "mojo/public/cpp/bindings/remote.h" #include "services/audio/public/cpp/audio_system_to_service_adapter.h" +#include "services/audio/public/mojom/audio_service.mojom.h" #include "services/audio/service.h" #include "services/audio/service_factory.h" #include "third_party/abseil-cpp/absl/types/optional.h"
diff --git a/content/browser/network_service_instance_impl.cc b/content/browser/network_service_instance_impl.cc index 48d85fd..1923ddf 100644 --- a/content/browser/network_service_instance_impl.cc +++ b/content/browser/network_service_instance_impl.cc
@@ -31,7 +31,6 @@ #include "build/chromeos_buildflags.h" #include "content/browser/browser_main_loop.h" #include "content/browser/network_service_client.h" -#include "content/browser/service_sandbox_type.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/content_browser_client.h"
diff --git a/content/browser/renderer_host/navigation_controller_impl_browsertest.cc b/content/browser/renderer_host/navigation_controller_impl_browsertest.cc index ccf6ba9..5f60eb9 100644 --- a/content/browser/renderer_host/navigation_controller_impl_browsertest.cc +++ b/content/browser/renderer_host/navigation_controller_impl_browsertest.cc
@@ -2176,13 +2176,10 @@ FrameTreeNode* root = contents()->GetFrameTree()->root(); EXPECT_EQ(url1, root->current_frame_host()->GetLastCommittedURL()); EXPECT_EQ(url1, root->current_frame_host()->last_document_url_in_renderer()); - EXPECT_EQ(url1, root->current_frame_host()->GetLastLoadingURLInRenderer()); FrameTreeNode* iframe = root->child_at(0); EXPECT_EQ(iframe_url, iframe->current_frame_host()->GetLastCommittedURL()); EXPECT_EQ(iframe_url, iframe->current_frame_host()->last_document_url_in_renderer()); - EXPECT_EQ(iframe_url, - iframe->current_frame_host()->GetLastLoadingURLInRenderer()); // 2) Do a document.open() on the iframe from the main frame. EXPECT_TRUE(ExecJs( @@ -2195,7 +2192,6 @@ EXPECT_EQ(iframe_url, iframe->current_frame_host()->GetLastCommittedURL()); EXPECT_EQ(url1, iframe->current_frame_host()->last_document_url_in_renderer()); - EXPECT_EQ(url1, iframe->current_frame_host()->GetLastLoadingURLInRenderer()); // 3) Do a same-document navigation to `url_1_fragment` on the iframe (Note // that this is a same-document navigation because the iframe's document URL @@ -2214,8 +2210,6 @@ iframe->current_frame_host()->GetLastCommittedURL()); EXPECT_EQ(url_1_fragment, iframe->current_frame_host()->last_document_url_in_renderer()); - EXPECT_EQ(url_1_fragment, - iframe->current_frame_host()->GetLastLoadingURLInRenderer()); // 4) Do a navigation to `url404`, which wil result in an error page. // The document URL will be set to the kUnreachableWebDataURL. @@ -2224,7 +2218,6 @@ EXPECT_EQ(url404, root->current_frame_host()->GetLastCommittedURL()); EXPECT_EQ(GURL(kUnreachableWebDataURL), root->current_frame_host()->last_document_url_in_renderer()); - EXPECT_EQ(url404, root->current_frame_host()->GetLastLoadingURLInRenderer()); // 5) Do a same-document pushState on an error page without changing the URL // (otherwise it will result in an origin mismatch error). The URLs will stay @@ -2239,7 +2232,6 @@ EXPECT_EQ(url404, root->current_frame_host()->GetLastCommittedURL()); EXPECT_EQ(GURL(kUnreachableWebDataURL), root->current_frame_host()->last_document_url_in_renderer()); - EXPECT_EQ(url404, root->current_frame_host()->GetLastLoadingURLInRenderer()); } // Tests various cases of replacements caused by error pages.
diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc index db136fe..40ff686f 100644 --- a/content/browser/renderer_host/navigation_request.cc +++ b/content/browser/renderer_host/navigation_request.cc
@@ -891,6 +891,32 @@ return parent_anonymous || frame->anonymous(); } +// Returns the "loading" URL in the renderer. This tries to replicate +// RenderFrameImpl::GetLoadingUrl(). This might return a different URL from +// what we get when calling GetLastCommittedURL() on `rfh`, in case the +// document had changed its URL through document.open() before, or +// when calling last_document_url_in_renderer(), in case of error pages and +// loadDataWithBaseURL documents. +// This function should only be used to preserve calculations that were +// previously done in the renderer but got moved to the browser (e.g. URL +// comparisons to determine if a navigation should do a replacement or not). +const GURL& GetLastLoadingURLInRendererForNavigationReplacement( + RenderFrameHostImpl* rfh) { + // Handle some special cases: + // - The "loading URL" for an error page commit is the URL that it failed to + // load. This will be retained as long as the document stays the same. + // - For loadDataWithBaseURL() navigations the "loading URL" will be the + // last committed URL (the data: URL). This will also be retained as long as + // the document stays the same. + if (rfh->IsErrorDocument() || + rfh->was_loaded_from_load_data_with_base_url()) { + return rfh->GetLastCommittedURL(); + } + + // Otherwise, return the last document URL. + return rfh->last_document_url_in_renderer(); +} + } // namespace NavigationRequest::PrerenderActivationNavigationState:: @@ -3729,7 +3755,29 @@ // soon be restarted as a normal history navigation. return; } - CHECK(rfh_restored_from_back_forward_cache_); + if (!rfh_restored_from_back_forward_cache_ || + rfh_restored_from_back_forward_cache_ + ->is_evicted_from_back_forward_cache()) { + // We might also get here when the navigation is not marked as being + // restarted yet, but the RFH being restored is gone or is already marked + // as evicted. Do not continue the navigation, and trigger uploading of + // debug information to understand what led to this case, since it's still + // unknown. + // See https://crbug.com/1258523. + SCOPED_CRASH_KEY_BOOL("NoRestoredRFH", "rfh_exists", + !!rfh_restored_from_back_forward_cache_); + SCOPED_CRASH_KEY_BOOL("NoRestoredRFH", "is_main_frame", + frame_tree_node_->IsMainFrame()); + SCOPED_CRASH_KEY_BOOL("NoRestoredRFH", "is_ftn_nav_req", + (frame_tree_node_->navigation_request() == this)); + BackForwardCacheImpl& back_forward_cache = + frame_tree_node_->frame_tree()->controller().GetBackForwardCache(); + SCOPED_CRASH_KEY_NUMBER("NoRestoredRFH", "bfcache_entries_size", + back_forward_cache.GetEntries().size()); + CaptureTraceForNavigationDebugScenario( + DebugScenario::kDebugNoRestoredRFHOnNonRestartedNavigation); + return; + } loader_type = NavigationURLLoader::LoaderType::kNoopForBackForwardCache; cached_response_head = rfh_restored_from_back_forward_cache_->last_response_head()->Clone(); @@ -6845,15 +6893,15 @@ // https://html.spec.whatwg.org/multipage/browsing-the-web.html#navigating-across-documents:hh-replace bool NavigationRequest::ShouldReplaceCurrentEntryForSameUrlNavigation() const { DCHECK_LE(state_, WILL_START_NAVIGATION); - // Not a same-url navigation. Note that this is comparing against the last - // history URL since this is what was used in the renderer check that was + // Not a same-url navigation. Note that this is comparing against the "last + // loading URL" since this is what was used in the renderer check that was // moved here. This means for error pages we should compare against the URL // that failed to load (the last committed URL), while for other navigations // we should compare against the last document URL, which might be different - // from the last committed URL due to document.open() changing the URL. To - // handle that, we compare against the "loading URL". + // from the last committed URL due to document.open() changing the URL. if (common_params_->url != - frame_tree_node_->current_frame_host()->GetLastLoadingURLInRenderer()) { + GetLastLoadingURLInRendererForNavigationReplacement( + frame_tree_node_->current_frame_host())) { return false; } @@ -6966,8 +7014,9 @@ // TODO(https://crbug.com/1188956): Reconsider whether these two cases should // do replacement or not, since we're just preserving old behavior here. return is_reload_or_history || - (common_params_->url == frame_tree_node_->current_frame_host() - ->GetLastLoadingURLInRenderer()); + (common_params_->url == + GetLastLoadingURLInRendererForNavigationReplacement( + frame_tree_node_->current_frame_host())); } void NavigationRequest::RenderFallbackContentForObjectTag() {
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc index 199b2b1..754d634 100644 --- a/content/browser/renderer_host/render_frame_host_impl.cc +++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -968,7 +968,7 @@ // failed (which is already accounted for in the error page case above). return request->common_params().base_url_for_data_url; } - if (renderer_url_info.is_loaded_from_load_data_with_base_url && + if (renderer_url_info.was_loaded_from_load_data_with_base_url && request->IsSameDocument()) { // If this is a same-document navigation on a document loaded from // loadDataWithBaseURL(), it is not currently possible to figure out the @@ -2070,21 +2070,6 @@ return last_committed_origin_; } -const GURL& RenderFrameHostImpl::GetLastLoadingURLInRenderer() const { - // Handle some special cases: - // - The "loading URL" for an error page commit is the URL that it failed to - // load. This will be retained as long as the document stays the same. - // - For loadDataWithBaseURL() navigations the "loading URL" will be the - // last committed URL (the data: URL). This will also be retained as long as - // the document stays the same. - if (is_error_page_ || - renderer_url_info_.is_loaded_from_load_data_with_base_url) { - return last_committed_url_; - } - // Otherwise, return the last document URL. - return renderer_url_info_.last_document_url; -} - const net::NetworkIsolationKey& RenderFrameHostImpl::GetNetworkIsolationKey() { DCHECK(!isolation_info_.IsEmpty()); return isolation_info_.network_isolation_key(); @@ -10006,13 +9991,13 @@ // checks. We should also allow same-document navigations within pages loaded // with loadDataWithBaseURL. Since renderer-initiated same-document // navigations won't have a NavigationRequest at this point, we need to check - // |renderer_url_info_.is_loaded_from_load_data_with_base_url|. + // |renderer_url_info_.was_loaded_from_load_data_with_base_url|. DCHECK(navigation_request || is_same_document_navigation || !frame_tree_node_->has_committed_real_load()); bool bypass_checks_for_webview = false; if ((navigation_request && navigation_request->IsLoadDataWithBaseURL()) || (is_same_document_navigation && - renderer_url_info_.is_loaded_from_load_data_with_base_url)) { + renderer_url_info_.was_loaded_from_load_data_with_base_url)) { // Allow bypass if the process isn't locked. Otherwise run normal checks. bypass_checks_for_webview = !ChildProcessSecurityPolicyImpl::GetInstance() ->GetProcessLock(process->GetID()) @@ -10568,10 +10553,10 @@ navigation_request->is_overriding_user_agent() && is_main_frame(); // Mark whether then navigation was intended as a loadDataWithBaseURL or not. - // If |renderer_url_info_.is_loaded_from_load_data_with_base_url| is true, we + // If |renderer_url_info_.was_loaded_from_load_data_with_base_url| is true, we // will bypass checks in VerifyDidCommitParams for same-document navigations // in the loaded document. - renderer_url_info_.is_loaded_from_load_data_with_base_url = + renderer_url_info_.was_loaded_from_load_data_with_base_url = navigation_request->IsLoadDataWithBaseURL(); // If we still have a PeakGpuMemoryTracker, then the loading it was observing @@ -11421,9 +11406,7 @@ // Calculates the "loading" URL for a given navigation. This tries to replicate // RenderFrameImpl::GetLoadingUrl() and is used to predict the value of "url" in -// DidCommitProvisionalLoadParams. Note that this is a bit different from -// GetLastDocumentLoadingURL(), which predicts the loading URL of an -// already-committed document for URL comparison purposes. +// DidCommitProvisionalLoadParams. GURL CalculateLoadingURL( NavigationRequest* request, const mojom::DidCommitProvisionalLoadParams& params, @@ -11449,7 +11432,7 @@ if (request->IsSameDocument() && (last_document_is_error_page || - last_renderer_url_info.is_loaded_from_load_data_with_base_url)) { + last_renderer_url_info.was_loaded_from_load_data_with_base_url)) { // Documents that have an "override" URL (loadDataWithBaseURL navigations, // error pages) will continue using that URL even after same-document // navigations. @@ -11625,7 +11608,7 @@ SCOPED_CRASH_KEY_BOOL( "VerifyDidCommit", "prev_ldwb", - renderer_url_info_.is_loaded_from_load_data_with_base_url); + renderer_url_info_.was_loaded_from_load_data_with_base_url); SCOPED_CRASH_KEY_STRING32( "VerifyDidCommit", "base_url_fdu_type", GetURLTypeForCrashKey(request->common_params().base_url_for_data_url));
diff --git a/content/browser/renderer_host/render_frame_host_impl.h b/content/browser/renderer_host/render_frame_host_impl.h index a1a391e..4f3b88b 100644 --- a/content/browser/renderer_host/render_frame_host_impl.h +++ b/content/browser/renderer_host/render_frame_host_impl.h
@@ -639,16 +639,11 @@ return renderer_url_info_.last_document_url; } - // Returns the "loading" URL in the renderer. This tries to replicate - // RenderFrameImpl::GetLoadingUrl(). This might return a different URL from - // GetLastCommittedURL() in case the document had changed its URL through - // document.open() before, and last_document_url_in_renderer() in case of - // error pages and loadDataWithBaseURL documents. See comments in the - // implementation for details. - // This function should only be used to preserve calculations that were - // previously done in the renderer but got moved to the browser (e.g. URL - // comparisons to determine if a navigation should do a replacement or not). - const GURL& GetLastLoadingURLInRenderer() const; + // Whether the last committed document was loaded from loadDataWithBaseURL or + // not. + bool was_loaded_from_load_data_with_base_url() const { + return renderer_url_info_.was_loaded_from_load_data_with_base_url; + } // Saves the URLs and other URL-related information used in the renderer. // These values can be used to know the current state of URLs in the renderer. @@ -676,7 +671,7 @@ // Whether the currently committed document is a result of webview's // loadDataWithBaseURL API or not. - bool is_loaded_from_load_data_with_base_url = false; + bool was_loaded_from_load_data_with_base_url = false; }; // Returns the storage key for the last committed document in this
diff --git a/content/browser/service_process_host_impl.cc b/content/browser/service_process_host_impl.cc index 946af5b..65749a5 100644 --- a/content/browser/service_process_host_impl.cc +++ b/content/browser/service_process_host_impl.cc
@@ -16,7 +16,9 @@ #include "content/common/child_process.mojom.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/content_browser_client.h" #include "content/public/browser/service_process_host.h" +#include "content/public/common/content_client.h" #include "mojo/public/cpp/bindings/generic_pending_receiver.h" #include "mojo/public/cpp/bindings/remote.h" @@ -24,6 +26,15 @@ namespace { +// Changes to this function should be reviewed by a security person. +bool ShouldEnableSandbox(sandbox::mojom::Sandbox sandbox) { + if (sandbox == sandbox::mojom::Sandbox::kAudio) + return GetContentClient()->browser()->ShouldSandboxAudioService(); + if (sandbox == sandbox::mojom::Sandbox::kNetwork) + return GetContentClient()->browser()->ShouldSandboxNetworkService(); + return true; +} + // Internal helper to track running service processes. class ServiceProcessTracker { public: @@ -162,14 +173,17 @@ // TODO(crbug.com/977637): Once UtilityProcessHost is used only by service // processes, its logic can be inlined here. void LaunchServiceProcess(mojo::GenericPendingReceiver receiver, - ServiceProcessHost::Options options) { + ServiceProcessHost::Options options, + sandbox::mojom::Sandbox sandbox) { UtilityProcessHost* host = new UtilityProcessHost( std::make_unique<UtilityProcessClient>(*receiver.interface_name())); host->SetName(!options.display_name.empty() ? options.display_name : base::UTF8ToUTF16(*receiver.interface_name())); host->SetMetricsName(*receiver.interface_name()); - host->SetSandboxType(options.sandbox_type); + if (!ShouldEnableSandbox(sandbox)) + sandbox = sandbox::mojom::Sandbox::kNoSandbox; + host->SetSandboxType(sandbox::policy::MapToSandboxType(sandbox)); host->SetExtraCommandLineSwitches(std::move(options.extra_switches)); if (options.child_flags) host->set_child_flags(*options.child_flags); @@ -196,14 +210,15 @@ // static void ServiceProcessHost::Launch(mojo::GenericPendingReceiver receiver, - Options options) { + Options options, + sandbox::mojom::Sandbox sandbox) { DCHECK(receiver.interface_name().has_value()); if (GetUIThreadTaskRunner({})->BelongsToCurrentThread()) { - LaunchServiceProcess(std::move(receiver), std::move(options)); + LaunchServiceProcess(std::move(receiver), std::move(options), sandbox); } else { GetUIThreadTaskRunner({})->PostTask( FROM_HERE, base::BindOnce(&LaunchServiceProcess, std::move(receiver), - std::move(options))); + std::move(options), sandbox)); } }
diff --git a/content/browser/service_sandbox_type.h b/content/browser/service_sandbox_type.h deleted file mode 100644 index 4498948..0000000 --- a/content/browser/service_sandbox_type.h +++ /dev/null
@@ -1,45 +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 CONTENT_BROWSER_SERVICE_SANDBOX_TYPE_H_ -#define CONTENT_BROWSER_SERVICE_SANDBOX_TYPE_H_ - -#include "content/browser/network_service_instance_impl.h" -#include "content/public/browser/content_browser_client.h" -#include "content/public/browser/service_process_host.h" -#include "content/public/common/content_client.h" -#include "sandbox/policy/sandbox_type.h" - -// This file maps service classes to sandbox types. See -// ServiceProcessHost::Launch() for how these templates are consumed. - -// audio::mojom::AudioService -namespace audio { -namespace mojom { -class AudioService; -} -} // namespace audio -template <> -inline sandbox::policy::SandboxType -content::GetServiceSandboxType<audio::mojom::AudioService>() { - return GetContentClient()->browser()->ShouldSandboxAudioService() - ? sandbox::policy::SandboxType::kAudio - : sandbox::policy::SandboxType::kNoSandbox; -} - -// network::mojom::NetworkService -namespace network { -namespace mojom { -class NetworkService; -} -} // namespace network -template <> -inline sandbox::policy::SandboxType -content::GetServiceSandboxType<network::mojom::NetworkService>() { - return GetContentClient()->browser()->ShouldSandboxNetworkService() - ? sandbox::policy::SandboxType::kNetwork - : sandbox::policy::SandboxType::kNoSandbox; -} - -#endif // CONTENT_BROWSER_SERVICE_SANDBOX_TYPE_H_
diff --git a/content/browser/web_package/link_web_bundle_browsertest.cc b/content/browser/web_package/link_web_bundle_browsertest.cc index e039da03..8fc0e61 100644 --- a/content/browser/web_package/link_web_bundle_browsertest.cc +++ b/content/browser/web_package/link_web_bundle_browsertest.cc
@@ -10,7 +10,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/test/scoped_feature_list.h" #include "base/threading/thread_restrictions.h" -#include "components/web_package/test_support/web_bundle_builder.h" +#include "components/web_package/web_bundle_builder.h" #include "components/web_package/web_bundle_utils.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/public/browser/content_browser_client.h" @@ -176,8 +176,8 @@ request.relative_url == "/web_bundle/huge2.wbn")) return nullptr; GURL primary_url(https_server_.GetURL("/web_bundle/huge.txt")); - web_package::test::WebBundleBuilder builder(primary_url.spec(), - "" /* manifest_url */); + web_package::WebBundleBuilder builder(primary_url.spec(), + "" /* manifest_url */); builder.AddExchange( primary_url.spec(), {{":status", "200"}, {"content-type", "text/plain"}},
diff --git a/content/browser/web_package/signed_exchange_request_handler_browsertest.cc b/content/browser/web_package/signed_exchange_request_handler_browsertest.cc index a4f3984f..9668e98 100644 --- a/content/browser/web_package/signed_exchange_request_handler_browsertest.cc +++ b/content/browser/web_package/signed_exchange_request_handler_browsertest.cc
@@ -585,8 +585,9 @@ UsePrefetch() ? 2 : 1); } -// https://crbug.com/966820. Fails pretty often on Android. Fails flakily -// on all platforms with Synchronous HTML Parsing enabled. +// TODO(crbug.com/966820): Fails pretty often on Android. +// TODO(crbug.com/1258886): Fails flakily on all platforms with Synchronous HTML +// Parsing enabled. IN_PROC_BROWSER_TEST_P(SignedExchangeRequestHandlerBrowserTest, DISABLED_BadMICE) { InstallMockCertChainInterceptor();
diff --git a/content/browser/web_package/signed_exchange_subresource_prefetch_browsertest.cc b/content/browser/web_package/signed_exchange_subresource_prefetch_browsertest.cc index 0451ccbac..a8da74e 100644 --- a/content/browser/web_package/signed_exchange_subresource_prefetch_browsertest.cc +++ b/content/browser/web_package/signed_exchange_subresource_prefetch_browsertest.cc
@@ -1343,6 +1343,8 @@ 1 /* expected_script_fetch_count */); } +// TODO(crbug.com/1258886): Fails flakily on all platforms with Synchronous HTML +// Parsing enabled. IN_PROC_BROWSER_TEST_F(SignedExchangeSubresourcePrefetchBrowserTest, DISABLED_ImageSrcsetAndSizes) { const char* prefetch_path = "/prefetch.html";
diff --git a/content/browser/web_package/web_bundle_browsertest_base.cc b/content/browser/web_package/web_bundle_browsertest_base.cc index 2a8318e0..a25f3d1 100644 --- a/content/browser/web_package/web_bundle_browsertest_base.cc +++ b/content/browser/web_package/web_bundle_browsertest_base.cc
@@ -362,7 +362,7 @@ } std::string CreateSimpleWebBundle(const GURL& primary_url) { - web_package::test::WebBundleBuilder builder(primary_url.spec(), ""); + web_package::WebBundleBuilder builder(primary_url.spec(), ""); builder.AddExchange(primary_url.spec(), {{":status", "200"}, {"content-type", "text/html"}}, "<title>Ready</title>"); @@ -370,7 +370,7 @@ return std::string(bundle.begin(), bundle.end()); } -void AddHtmlFile(web_package::test::WebBundleBuilder* builder, +void AddHtmlFile(web_package::WebBundleBuilder* builder, const GURL& base_url, const std::string& path, const std::string& content) { @@ -379,7 +379,7 @@ content); } -void AddScriptFile(web_package::test::WebBundleBuilder* builder, +void AddScriptFile(web_package::WebBundleBuilder* builder, const GURL& base_url, const std::string& path, const std::string& content) { @@ -391,7 +391,7 @@ std::string CreatePathTestWebBundle(const GURL& base_url) { const std::string primary_url_path = "/web_bundle/path_test/in_scope/"; - web_package::test::WebBundleBuilder builder( + web_package::WebBundleBuilder builder( base_url.Resolve(primary_url_path).spec(), ""); AddHtmlFile(&builder, base_url, primary_url_path, "<title>Ready</title>"); AddHtmlFile( @@ -470,7 +470,7 @@ *primary_url_origin = primary_server->GetURL("/"); *third_party_origin = third_party_server->GetURL("/"); - web_package::test::WebBundleBuilder builder( + web_package::WebBundleBuilder builder( primary_url_origin->Resolve("/top").spec(), ""); AddHtmlFile(&builder, *primary_url_origin, "/top", R"( <script> @@ -588,11 +588,10 @@ script_info.c_str()); } -void AddHtmlAndScriptForNavigationTest( - web_package::test::WebBundleBuilder* builder, - const GURL& base_url, - const std::string& path, - const std::string& additional_html) { +void AddHtmlAndScriptForNavigationTest(web_package::WebBundleBuilder* builder, + const GURL& base_url, + const std::string& path, + const std::string& additional_html) { AddHtmlFile(builder, base_url, path, CreateHtmlForNavigationTest(path + " from wbn", additional_html)); AddScriptFile(builder, base_url, path + "script", @@ -684,7 +683,7 @@ GURL* url_origin, std::string* web_bundle_content) { SetUpNavigationTestServer(server, url_origin); - web_package::test::WebBundleBuilder builder( + web_package::WebBundleBuilder builder( url_origin->Resolve("/top-page/").spec(), ""); for (const auto& path : pathes) AddHtmlAndScriptForNavigationTest(&builder, *url_origin, path, ""); @@ -1052,7 +1051,7 @@ GURL* url_origin, std::string* web_bundle_content) { SetUpNavigationTestServer(server, url_origin); - web_package::test::WebBundleBuilder builder( + web_package::WebBundleBuilder builder( url_origin->Resolve("/top-page/").spec(), ""); const std::vector<std::string> pathes = {"/top-page/", "/1-page/", "/2-page/"};
diff --git a/content/browser/web_package/web_bundle_browsertest_base.h b/content/browser/web_package/web_bundle_browsertest_base.h index d6b09ee4..77692897 100644 --- a/content/browser/web_package/web_bundle_browsertest_base.h +++ b/content/browser/web_package/web_bundle_browsertest_base.h
@@ -9,7 +9,7 @@ #include "base/run_loop.h" #include "base/strings/string_piece.h" #include "build/build_config.h" -#include "components/web_package/test_support/web_bundle_builder.h" +#include "components/web_package/web_bundle_builder.h" #include "content/browser/renderer_host/frame_tree_node.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/public/browser/browser_context.h" @@ -242,12 +242,12 @@ std::string CreateSimpleWebBundle(const GURL& primary_url); -void AddHtmlFile(web_package::test::WebBundleBuilder* builder, +void AddHtmlFile(web_package::WebBundleBuilder* builder, const GURL& base_url, const std::string& path, const std::string& content); -void AddScriptFile(web_package::test::WebBundleBuilder* builder, +void AddScriptFile(web_package::WebBundleBuilder* builder, const GURL& base_url, const std::string& path, const std::string& content); @@ -313,11 +313,10 @@ std::string CreateScriptForNavigationTest(const std::string& script_info); -void AddHtmlAndScriptForNavigationTest( - web_package::test::WebBundleBuilder* builder, - const GURL& base_url, - const std::string& path, - const std::string& additional_html); +void AddHtmlAndScriptForNavigationTest(web_package::WebBundleBuilder* builder, + const GURL& base_url, + const std::string& path, + const std::string& additional_html); std::string GetLoadResultForNavigationTest(const ToRenderFrameHost& adapter);
diff --git a/content/browser/web_package/web_bundle_network_browsertest.cc b/content/browser/web_package/web_bundle_network_browsertest.cc index 0aaf218d..2336fa4 100644 --- a/content/browser/web_package/web_bundle_network_browsertest.cc +++ b/content/browser/web_package/web_bundle_network_browsertest.cc
@@ -134,7 +134,7 @@ const GURL script_url = embedded_test_server()->GetURL("/web_bundle/script.js"); - web_package::test::WebBundleBuilder builder(primary_url.spec(), ""); + web_package::WebBundleBuilder builder(primary_url.spec(), ""); builder.AddExchange(primary_url.spec(), {{":status", "200"}, {"content-type", "text/html"}}, "<script src=\"script.js\"></script>"); @@ -228,7 +228,7 @@ const GURL primary_url = embedded_test_server()->GetURL(primary_url_path); const GURL inner_url = embedded_test_server()->GetURL("/web_bundle/inner.html"); - web_package::test::WebBundleBuilder builder(primary_url.spec(), ""); + web_package::WebBundleBuilder builder(primary_url.spec(), ""); builder.AddExchange(inner_url.spec(), {{":status", "200"}, {"content-type", "text/html"}}, "<title>Ready</title>"); @@ -695,8 +695,8 @@ embedded_test_server(), ""); ASSERT_TRUE(embedded_test_server()->Start()); const GURL origin = embedded_test_server()->GetURL("/"); - web_package::test::WebBundleBuilder builder( - origin.Resolve(primary_url_path).spec(), ""); + web_package::WebBundleBuilder builder(origin.Resolve(primary_url_path).spec(), + ""); web_bundle_browsertest_utils::AddHtmlFile(&builder, origin, primary_url_path, R"( <script>
diff --git a/content/common/debug_utils.h b/content/common/debug_utils.h index 13d02428..1f724fd 100644 --- a/content/common/debug_utils.h +++ b/content/common/debug_utils.h
@@ -55,9 +55,14 @@ // RenderFrameProxyHost::SetFocusedFrame(). kDebugNoRenderFrameProxyHostOnSetFocusedFrame = 9, + // The RenderFrameHost to be restored from the back/forward cache no longer + // exists for a navigation that is not marked as being restarted. + // See https://crbug.com/1258523. + kDebugNoRestoredRFHOnNonRestartedNavigation = 10, + // After making changes, you MUST update the histograms xml by running: // "python tools/metrics/histograms/update_debug_scenarios.py" - kMaxValue = kDebugNoRenderFrameProxyHostOnSetFocusedFrame, + kMaxValue = kDebugNoRestoredRFHOnNonRestartedNavigation, }; // The tracing categories enabled for debugging navigation scenarios can be
diff --git a/content/public/browser/service_process_host.h b/content/public/browser/service_process_host.h index 11c2c6f..d4cab88 100644 --- a/content/public/browser/service_process_host.h +++ b/content/public/browser/service_process_host.h
@@ -30,17 +30,16 @@ // Sandbox type for ServiceProcessHost::Launch<remote>() is found by // template matching on |remote|. Consult security-dev@chromium.org and -// add a [ServiceSandbox=type] mojom attribute, or an appropriate -// |service_sandbox_type.h|. +// add a [ServiceSandbox=type] mojom attribute. template <typename Interface> -inline sandbox::policy::SandboxType GetServiceSandboxType() { +inline sandbox::mojom::Sandbox GetServiceSandboxType() { using ProvidedSandboxType = decltype(Interface::kServiceSandbox); static_assert( std::is_same<ProvidedSandboxType, const sandbox::mojom::Sandbox>::value, "This interface does not declare a proper ServiceSandbox attribute. See " "//docs/mojo_and_services.md (Specifying a sandbox)."); - return sandbox::policy::MapToSandboxType(Interface::kServiceSandbox); + return Interface::kServiceSandbox; } // ServiceProcessHost is used to launch new service processes given basic @@ -87,8 +86,6 @@ // to |Launch()|. Options Pass(); - sandbox::policy::SandboxType sandbox_type = - sandbox::policy::SandboxType::kUtility; std::u16string display_name; absl::optional<int> child_flags; std::vector<std::string> extra_switches; @@ -130,9 +127,8 @@ template <typename Interface> static void Launch(mojo::PendingReceiver<Interface> receiver, Options options = {}) { - options.sandbox_type = content::GetServiceSandboxType<Interface>(); Launch(mojo::GenericPendingReceiver(std::move(receiver)), - std::move(options)); + std::move(options), content::GetServiceSandboxType<Interface>()); } // Same as above but creates a new |Interface| pipe on the caller's behalf and @@ -141,9 +137,9 @@ // May be called from any thread. template <typename Interface> static mojo::Remote<Interface> Launch(Options options = {}) { - options.sandbox_type = content::GetServiceSandboxType<Interface>(); mojo::Remote<Interface> remote; - Launch(remote.BindNewPipeAndPassReceiver(), std::move(options)); + Launch(remote.BindNewPipeAndPassReceiver(), std::move(options), + content::GetServiceSandboxType<Interface>()); return remote; } @@ -163,7 +159,9 @@ // Launches a new service process and asks it to bind a receiver for the // service interface endpoint carried by |receiver|, which should be connected // to a Remote of the same interface type. - static void Launch(mojo::GenericPendingReceiver receiver, Options options); + static void Launch(mojo::GenericPendingReceiver receiver, + Options options, + sandbox::mojom::Sandbox sandbox); }; // DEPRECATED. DO NOT USE THIS. This is a helper for any remaining service
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 5ca2f21..fac3e7446 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -1400,7 +1400,6 @@ "//components/viz/host", "//components/viz/test:test_support", "//components/web_package", - "//components/web_package:test_support", "//content/app:for_content_tests", "//content/browser:for_content_tests", "//content/browser/background_sync:background_sync_proto",
diff --git a/device/fido/cros/authenticator.cc b/device/fido/cros/authenticator.cc index fdf86d49..21c4c52 100644 --- a/device/fido/cros/authenticator.cc +++ b/device/fido/cros/authenticator.cc
@@ -24,8 +24,10 @@ namespace device { ChromeOSAuthenticator::ChromeOSAuthenticator( - base::RepeatingCallback<uint32_t()> generate_request_id_callback) + base::RepeatingCallback<uint32_t()> generate_request_id_callback, + ChromeOSAuthenticator::Config config) : generate_request_id_callback_(std::move(generate_request_id_callback)), + config_(config), weak_factory_(this) {} ChromeOSAuthenticator::~ChromeOSAuthenticator() {} @@ -73,10 +75,11 @@ MakeCredentialOptions request_options, MakeCredentialCallback callback) { u2f::MakeCredentialRequest req; - // Requests with UserPresence get upgraded to UserVerification unless - // verification is explicitly discouraged. + // Requests will be UserPresence if uv is not available or discouraged, + // and be UserVerification otherwise. req.set_verification_type( - (request.user_verification == UserVerificationRequirement::kDiscouraged) + (request.user_verification == UserVerificationRequirement::kDiscouraged && + config_.power_button_enabled) ? u2f::VERIFICATION_USER_PRESENCE : u2f::VERIFICATION_USER_VERIFICATION); req.set_rp_id(request.rp.id); @@ -185,10 +188,11 @@ CtapGetAssertionOptions options, GetAssertionCallback callback) { u2f::GetAssertionRequest req; - // Requests with UserPresence get upgraded to UserVerification unless - // verification is explicitly discouraged. + // Requests will be UserPresence if uv is not available or discouraged, + // and be UserVerification otherwise. req.set_verification_type( - (request.user_verification == UserVerificationRequirement::kDiscouraged) + (request.user_verification == UserVerificationRequirement::kDiscouraged && + config_.power_button_enabled) ? u2f::VERIFICATION_USER_PRESENCE : u2f::VERIFICATION_USER_VERIFICATION); req.set_rp_id(request.rp_id);
diff --git a/device/fido/cros/authenticator.h b/device/fido/cros/authenticator.h index ecc0743..2798583b 100644 --- a/device/fido/cros/authenticator.h +++ b/device/fido/cros/authenticator.h
@@ -25,8 +25,17 @@ class COMPONENT_EXPORT(DEVICE_FIDO) ChromeOSAuthenticator : public FidoAuthenticator { public: - explicit ChromeOSAuthenticator( - base::RepeatingCallback<uint32_t()> generate_request_id_callback); + struct COMPONENT_EXPORT(DEVICE_FIDO) Config { + // Whether uv platform authenticator is available (PIN or fingerprint + // enrolled). + bool uv_available; + // Whether using the power button for user presence checking is enabled. + bool power_button_enabled; + }; + + ChromeOSAuthenticator( + base::RepeatingCallback<uint32_t()> generate_request_id_callback, + Config config); ~ChromeOSAuthenticator() override; static void HasCredentialForGetAssertionRequest( @@ -37,7 +46,7 @@ const CtapGetAssertionRequest& request, base::OnceCallback<void(bool has_credential)> callback); - // Invokes |callback| with a bool indicating whether the platform + // Invokes |callback| with a bool indicating whether the platform // authenticator is available, which is true if the current user has a PIN set // up or biometrics enrolled. static void IsUVPlatformAuthenticatorAvailable( @@ -94,6 +103,7 @@ // Callback to set request_id in the window property. base::RepeatingCallback<uint32_t()> generate_request_id_callback_; + const Config config_; base::WeakPtrFactory<ChromeOSAuthenticator> weak_factory_; };
diff --git a/device/fido/cros/discovery.cc b/device/fido/cros/discovery.cc index c56704e..435388a2 100644 --- a/device/fido/cros/discovery.cc +++ b/device/fido/cros/discovery.cc
@@ -43,13 +43,6 @@ return; } - if (require_power_button_mode_) { - ChromeOSAuthenticator::IsPowerButtonModeEnabled( - base::BindOnce(&FidoChromeOSDiscovery::MaybeAddAuthenticator, - weak_factory_.GetWeakPtr())); - return; - } - if (get_assertion_request_) { ChromeOSAuthenticator::HasLegacyU2fCredentialForGetAssertionRequest( *get_assertion_request_, @@ -58,31 +51,45 @@ return; } - ChromeOSAuthenticator::IsUVPlatformAuthenticatorAvailable( - base::BindOnce(&FidoChromeOSDiscovery::MaybeAddAuthenticator, - weak_factory_.GetWeakPtr())); + CheckAuthenticators(); } -void FidoChromeOSDiscovery::MaybeAddAuthenticator(bool is_available) { - if (!is_available) { +void FidoChromeOSDiscovery::CheckAuthenticators() { + ChromeOSAuthenticator::IsPowerButtonModeEnabled(base::BindOnce( + &FidoChromeOSDiscovery::CheckUVPlatformAuthenticatorAvailable, + weak_factory_.GetWeakPtr())); +} + +void FidoChromeOSDiscovery::CheckUVPlatformAuthenticatorAvailable( + bool is_enabled) { + ChromeOSAuthenticator::IsUVPlatformAuthenticatorAvailable(base::BindOnce( + &FidoChromeOSDiscovery::MaybeAddAuthenticator, weak_factory_.GetWeakPtr(), + /*power_button_enabled=*/is_enabled)); +} + +void FidoChromeOSDiscovery::MaybeAddAuthenticator(bool power_button_enabled, + bool uv_available) { + if (require_power_button_mode_) { + uv_available = false; + } + + if (!uv_available && !power_button_enabled) { observer()->DiscoveryStarted(this, /*success=*/false); return; } - authenticator_ = - std::make_unique<ChromeOSAuthenticator>(generate_request_id_callback_); + authenticator_ = std::make_unique<ChromeOSAuthenticator>( + generate_request_id_callback_, + ChromeOSAuthenticator::Config{ + .uv_available = uv_available, + .power_button_enabled = power_button_enabled}); observer()->DiscoveryStarted(this, /*success=*/true, {authenticator_.get()}); } void FidoChromeOSDiscovery::OnHasLegacyU2fCredential(bool has_credential) { DCHECK(!authenticator_); - if (!has_credential) { - ChromeOSAuthenticator::IsUVPlatformAuthenticatorAvailable( - base::BindOnce(&FidoChromeOSDiscovery::MaybeAddAuthenticator, - weak_factory_.GetWeakPtr())); - return; - } - - MaybeAddAuthenticator(/*is_available=*/true); + ChromeOSAuthenticator::IsUVPlatformAuthenticatorAvailable(base::BindOnce( + &FidoChromeOSDiscovery::MaybeAddAuthenticator, weak_factory_.GetWeakPtr(), + /*power_button_enabled=*/has_credential)); } } // namespace device
diff --git a/device/fido/cros/discovery.h b/device/fido/cros/discovery.h index a8cf869..54d4a19 100644 --- a/device/fido/cros/discovery.h +++ b/device/fido/cros/discovery.h
@@ -33,7 +33,9 @@ private: void OnU2FServiceAvailable(bool u2f_service_available); - void MaybeAddAuthenticator(bool is_available); + void CheckAuthenticators(); + void CheckUVPlatformAuthenticatorAvailable(bool is_enabled); + void MaybeAddAuthenticator(bool power_button_enabled, bool uv_available); void OnHasLegacyU2fCredential(bool has_credential); base::RepeatingCallback<uint32_t()> generate_request_id_callback_;
diff --git a/docs/mojo_and_services.md b/docs/mojo_and_services.md index 65a1571..45234f6 100644 --- a/docs/mojo_and_services.md +++ b/docs/mojo_and_services.md
@@ -444,14 +444,9 @@ that the sandbox is only applied if the interface is launched out-of-process using `content::ServiceProcessHost::Launch()`. -Dynamic or feature based mapping to an underlying platform sandbox can be -achieved using `sandbox::policy::MapToSandboxType()`. As a last resort, specify -a service's sandbox by specialization of `GetServiceSandboxType()` in an -appropriate `service_sandbox_type.h` such as -[`//chrome/browser/service_sandbox_type.h`](https://cs.chromium.org/chromium/src/chrome/browser/service_sandbox_type.h) -or -[`//content/browser/service_sandbox_type.h`](https://cs.chromium.org/chromium/src/content/browser/service_sandbox_type.h). -This must be included where `ServiceProcessHost::Launch()` is called. +As a last resort, dynamic or feature based mapping to an underlying platform +sandbox can be achieved but requires plumbing through ContentBrowserClient +(e.g. `ShouldEnableNetworkServiceSandbox()`). ## Content-Layer Services Overview
diff --git a/docs/testing/web_tests.md b/docs/testing/web_tests.md index 7fcc071..2968f47 100644 --- a/docs/testing/web_tests.md +++ b/docs/testing/web_tests.md
@@ -286,6 +286,13 @@ under `web_tests/compositing` and `web_tests/fast/repaint`, respectively, and pass `--blocking-repaint` to `content_shell` when they are run. +Note that you can run the tests with the following command line: + +```bash +third_party/blink/tools/run_web_tests.py virtual/blocking_repaint/compositing \ + virtual/blocking_repaint/fast/repaint +``` + These virtual tests exist in addition to the original `compositing/...` and `fast/repaint/...` tests. They can have their own expectations in `web_tests/TestExpectations`, and their own baselines. The test harness will
diff --git a/extensions/browser/extension_prefs.cc b/extensions/browser/extension_prefs.cc index 5f66af8..83efb76 100644 --- a/extensions/browser/extension_prefs.cc +++ b/extensions/browser/extension_prefs.cc
@@ -174,10 +174,6 @@ // Chrome Web Store. constexpr const char kPrefFromWebStore[] = "from_webstore"; -// A preference that indicates whether the extension was installed from a -// mock App created from a bookmark. -constexpr const char kPrefFromBookmark[] = "from_bookmark"; - // A preference that indicates whether the extension was installed as a // default app. constexpr const char kPrefWasInstalledByDefault[] = "was_installed_by_default"; @@ -1686,21 +1682,11 @@ return false; } -bool ExtensionPrefs::IsFromBookmark( - const std::string& extension_id) const { - const base::DictionaryValue* dictionary = GetExtensionPref(extension_id); - if (dictionary) - return dictionary->FindBoolKey(kPrefFromBookmark).value_or(false); - return false; -} - int ExtensionPrefs::GetCreationFlags(const std::string& extension_id) const { int creation_flags = Extension::NO_FLAGS; if (!ReadPrefAsInteger(extension_id, kPrefCreationFlags, &creation_flags)) { // Since kPrefCreationFlags was added later, it will be missing for // previously installed extensions. - if (IsFromBookmark(extension_id)) - creation_flags |= Extension::FROM_BOOKMARK; if (IsFromWebStore(extension_id)) creation_flags |= Extension::FROM_WEBSTORE; if (WasInstalledByDefault(extension_id)) @@ -2331,7 +2317,6 @@ static_cast<int>(extension->location())); extension_dict->SetInteger(kPrefCreationFlags, extension->creation_flags()); extension_dict->SetBoolean(kPrefFromWebStore, extension->from_webstore()); - extension_dict->SetBoolean(kPrefFromBookmark, extension->from_bookmark()); extension_dict->SetBoolean(kPrefWasInstalledByDefault, extension->was_installed_by_default()); extension_dict->SetBoolean(kPrefWasInstalledByOem,
diff --git a/extensions/browser/extension_prefs.h b/extensions/browser/extension_prefs.h index c9905767..e240db89 100644 --- a/extensions/browser/extension_prefs.h +++ b/extensions/browser/extension_prefs.h
@@ -586,10 +586,6 @@ // Returns true if the extension was installed from the Chrome Web Store. bool IsFromWebStore(const std::string& extension_id) const; - // Returns true if the extension was installed from an App generated from a - // bookmark. - bool IsFromBookmark(const std::string& extension_id) const; - // Returns true if the extension was installed as a default app. bool WasInstalledByDefault(const std::string& extension_id) const;
diff --git a/ios/chrome/browser/ui/recent_tabs/BUILD.gn b/ios/chrome/browser/ui/recent_tabs/BUILD.gn index 125934d..d180051 100644 --- a/ios/chrome/browser/ui/recent_tabs/BUILD.gn +++ b/ios/chrome/browser/ui/recent_tabs/BUILD.gn
@@ -92,6 +92,7 @@ "//ios/chrome/browser/ui/authentication", "//ios/chrome/browser/ui/authentication:signin_presenter", "//ios/chrome/browser/ui/authentication/cells", + "//ios/chrome/browser/ui/authentication/enterprise:enterprise_utils", "//ios/chrome/browser/ui/authentication/signin:signin_headers", "//ios/chrome/browser/ui/commands", "//ios/chrome/browser/ui/settings/sync/utils",
diff --git a/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm b/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm index 7c0fe7a..8c47f86 100644 --- a/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm +++ b/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm
@@ -34,6 +34,7 @@ #import "ios/chrome/browser/ui/authentication/cells/signin_promo_view_configurator.h" #import "ios/chrome/browser/ui/authentication/cells/signin_promo_view_consumer.h" #import "ios/chrome/browser/ui/authentication/cells/table_view_signin_promo_item.h" +#import "ios/chrome/browser/ui/authentication/enterprise/enterprise_utils.h" #import "ios/chrome/browser/ui/authentication/signin/signin_utils.h" #import "ios/chrome/browser/ui/authentication/signin_presenter.h" #import "ios/chrome/browser/ui/authentication/signin_promo_view_mediator.h" @@ -250,8 +251,11 @@ // Returns YES if the user cannot turn on sync for enterprise policy reasons. - (BOOL)isSyncDisabledByAdministrator { DCHECK(self.syncService); - return self.syncService->GetDisableReasons().Has( + bool syncDisabledPolicy = self.syncService->GetDisableReasons().Has( syncer::SyncService::DISABLE_REASON_ENTERPRISE_POLICY); + bool syncTypesDisabledPolicy = + IsManagedSyncDataType(self.browserState, SyncSetupService::kSyncOpenTabs); + return syncDisabledPolicy || syncTypesDisabledPolicy; } #pragma mark - SyncObserverModelBridge
diff --git a/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.cc b/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.cc index a5c93d0..6df0bcf 100644 --- a/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.cc +++ b/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.cc
@@ -1160,11 +1160,19 @@ DCHECK_EQ(state_, kIdle); DCHECK(decoder_display_queue_.empty()); + +#if DCHECK_IS_ON() // All output buffers should've been returned from decoder and device by now. // The only remaining owner of surfaces may be display (client), and we will // dismiss them when destroying output buffers below. + const size_t num_imported_buffers = + std::count_if(output_buffer_map_.begin(), output_buffer_map_.end(), + [](const OutputRecord& output_record) { + return output_record.output_frame != nullptr; + }); DCHECK_EQ(output_queue_->FreeBuffersCount() + surfaces_at_display_.size(), - output_buffer_map_.size()); + num_imported_buffers); +#endif // DCHECK_IS_ON() if (!StopDevicePoll()) { LOG(ERROR) << "Failed StopDevicePoll()";
diff --git a/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc b/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc index f43cd32..6eb64869 100644 --- a/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc +++ b/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc
@@ -1353,22 +1353,68 @@ "Invalid bitrate mode", ); framerate = base::clamp(framerate, 1u, uint32_t{kMaxFrameRateNumerator}); + if (frame_rate_ != framerate) { HRESULT hr = MFSetAttributeRatio(imf_output_media_type_.Get(), MF_MT_FRAME_RATE, framerate, 1); RETURN_ON_HR_FAILURE(hr, "Couldn't set frame rate for output type", ); + imf_output_media_type_->SetUINT32(MF_MT_AVG_BITRATE, bitrate.target()); + RETURN_ON_HR_FAILURE(hr, "Couldn't set average bitrate for output type", ); + hr = MFSetAttributeRatio(imf_input_media_type_.Get(), MF_MT_FRAME_RATE, framerate, 1); RETURN_ON_HR_FAILURE(hr, "Couldn't set frame rate for input type", ); - hr = encoder_->SetOutputType(output_stream_id_, - imf_output_media_type_.Get(), 0); - RETURN_ON_HR_FAILURE(hr, "Couldn't set output media type", ); + if (is_async_mft_) { + // Some HMFTs will reject output type change with MF_E_INVALIDTYPE due + // to temporary mismatch between output/input media types, so we always + // clear the input/output media types before reconfiguring them + // dynamically. + hr = encoder_->ProcessMessage(MFT_MESSAGE_COMMAND_DRAIN, 0); + RETURN_ON_HR_FAILURE( + hr, "Couldn't process message MFT_MESSAGE_COMMAND_DRAIN", ); - hr = encoder_->SetInputType(input_stream_id_, imf_input_media_type_.Get(), - 0); - RETURN_ON_HR_FAILURE(hr, "Couldn't set input media type", ); + DrainPendingOutputs(); + + hr = encoder_->ProcessMessage(MFT_MESSAGE_NOTIFY_END_OF_STREAM, 0); + RETURN_ON_HR_FAILURE( + hr, "Couldn't process message MFT_MESSAGE_NOTIFY_END_OF_STREAM", ); + + hr = encoder_->ProcessMessage(MFT_MESSAGE_NOTIFY_END_STREAMING, 0); + RETURN_ON_HR_FAILURE( + hr, "Couldn't process message MFT_MESSAGE_NOTIFY_END_STREAMING", ); + + hr = encoder_->SetInputType(input_stream_id_, nullptr, 0); + RETURN_ON_HR_FAILURE(hr, "Couldn't clear input media type.", ); + + hr = encoder_->SetOutputType(output_stream_id_, nullptr, 0); + RETURN_ON_HR_FAILURE(hr, "Couldn't clear ouput media type.", ); + + hr = encoder_->SetOutputType(output_stream_id_, + imf_output_media_type_.Get(), 0); + RETURN_ON_HR_FAILURE(hr, "Couldn't set output media type", ); + + hr = encoder_->SetInputType(input_stream_id_, imf_input_media_type_.Get(), + 0); + RETURN_ON_HR_FAILURE(hr, "Couldn't set input media type", ); + + hr = encoder_->ProcessMessage(MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, 0); + RETURN_ON_HR_FAILURE( + hr, "Couldn't process message MFT_MESSAGE_NOTIFY_BEGIN_STREAMING", ); + + hr = encoder_->ProcessMessage(MFT_MESSAGE_NOTIFY_START_OF_STREAM, 0); + RETURN_ON_HR_FAILURE( + hr, "Couldn't process message MFT_MESSAGE_NOTIFY_START_OF_STREAM", ); + } else { + hr = encoder_->SetOutputType(output_stream_id_, + imf_output_media_type_.Get(), 0); + RETURN_ON_HR_FAILURE(hr, "Couldn't set output media type", ); + + hr = encoder_->SetInputType(input_stream_id_, imf_input_media_type_.Get(), + 0); + RETURN_ON_HR_FAILURE(hr, "Couldn't set input media type", ); + } frame_rate_ = framerate; } @@ -1583,4 +1629,22 @@ return hr; } +void MediaFoundationVideoEncodeAccelerator::DrainPendingOutputs() { + Microsoft::WRL::ComPtr<IMFMediaEvent> media_event; + + while ((SUCCEEDED( + event_generator_->GetEvent(MF_EVENT_FLAG_NO_WAIT, &media_event)))) { + MediaEventType event_type; + HRESULT hr = media_event->GetType(&event_type); + if (FAILED(hr)) { + DLOG(ERROR) << "Failed to get the type of media event."; + continue; + } + + if (event_type == METransformHaveOutput) { + ProcessOutputAsync(); + } + } +} + } // namespace media
diff --git a/media/gpu/windows/media_foundation_video_encode_accelerator_win.h b/media/gpu/windows/media_foundation_video_encode_accelerator_win.h index c6a5f49..be6473b1 100644 --- a/media/gpu/windows/media_foundation_video_encode_accelerator_win.h +++ b/media/gpu/windows/media_foundation_video_encode_accelerator_win.h
@@ -101,6 +101,9 @@ void ProcessOutputAsync(); void ProcessOutputSync(); + // Drains pending output samples on |encoder_thread_|. + void DrainPendingOutputs(); + // Tries to deliver the input frame to the encoder. bool TryToDeliverInputFrame(scoped_refptr<VideoFrame> frame, bool force_keyframe);
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/module-forward.h.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/module-forward.h.tmpl index 06647c6..5042367 100644 --- a/mojo/public/tools/bindings/generators/cpp_templates/module-forward.h.tmpl +++ b/mojo/public/tools/bindings/generators/cpp_templates/module-forward.h.tmpl
@@ -43,7 +43,7 @@ #include <stdint.h> {%- endif %} -{% if structs|length -%} +{% if structs|length or unions|length -%} #include "mojo/public/cpp/bindings/struct_forward.h" {%- endif %} @@ -167,9 +167,9 @@ {% for union in unions %} class {{union.name}}; {% if union|should_inline_union %} -typedef mojo::InlinedStructPtr<{{union.name}}> {{union.name}}Ptr; +using {{union.name}}Ptr = mojo::InlinedStructPtr<{{union.name}}>; {% else %} -typedef mojo::StructPtr<{{union.name}}> {{union.name}}Ptr; +using {{union.name}}Ptr = mojo::StructPtr<{{union.name}}>; {% endif %} {%- endfor %}
diff --git a/net/log/net_log_event_type_list.h b/net/log/net_log_event_type_list.h index 5dafb61..960ac79 100644 --- a/net/log/net_log_event_type_list.h +++ b/net/log/net_log_event_type_list.h
@@ -4023,3 +4023,14 @@ // from preflight cache. // The parameters are the same as for CORS_PREFLIGHT_RESULT. EVENT_TYPE(CORS_PREFLIGHT_CACHED_RESULT) + +// ------------------------------------------------------------------------ +// Initiator +// ------------------------------------------------------------------------ + +// This event is logged to indicate the initiator of the network event. +// The event contains the following parameters: +// { +// "source_dependency": <Source identifier for the attached event> +// } +EVENT_TYPE(CREATED_BY)
diff --git a/net/log/net_log_source.cc b/net/log/net_log_source.cc index 549f6d07..db42730 100644 --- a/net/log/net_log_source.cc +++ b/net/log/net_log_source.cc
@@ -41,6 +41,10 @@ base::TimeTicks start_time) : type(type), id(id), start_time(start_time) {} +bool NetLogSource::operator==(const NetLogSource& rhs) const { + return type == rhs.type && id == rhs.id && start_time == rhs.start_time; +} + bool NetLogSource::IsValid() const { return id != kInvalidId; }
diff --git a/net/log/net_log_source.h b/net/log/net_log_source.h index 32aaf51..fd0b737 100644 --- a/net/log/net_log_source.h +++ b/net/log/net_log_source.h
@@ -26,6 +26,9 @@ NetLogSource(); NetLogSource(NetLogSourceType type, uint32_t id); NetLogSource(NetLogSourceType type, uint32_t id, base::TimeTicks start_time); + + bool operator==(const NetLogSource& rhs) const; + bool IsValid() const; // Adds the source to a dictionary containing event parameters,
diff --git a/net/log/net_log_source_type.h b/net/log/net_log_source_type.h index 8fe57e541..72ea14d 100644 --- a/net/log/net_log_source_type.h +++ b/net/log/net_log_source_type.h
@@ -5,10 +5,12 @@ #ifndef NET_LOG_NET_LOG_SOURCE_TYPE_H_ #define NET_LOG_NET_LOG_SOURCE_TYPE_H_ +#include <stdint.h> + namespace net { // The "source" identifies the entity that generated the log message. -enum class NetLogSourceType { +enum class NetLogSourceType : uint32_t { #define SOURCE_TYPE(label) label, #include "net/log/net_log_source_type_list.h" #undef SOURCE_TYPE
diff --git a/net/log/net_log_source_type_list.h b/net/log/net_log_source_type_list.h index 3967235b..e9432bd 100644 --- a/net/log/net_log_source_type_list.h +++ b/net/log/net_log_source_type_list.h
@@ -46,4 +46,3 @@ SOURCE_TYPE(HTTP3_SESSION) SOURCE_TYPE(WEB_TRANSPORT_CLIENT) SOURCE_TYPE(NETWORK_SERVICE_HOST_RESOLVER) -SOURCE_TYPE(CORS_URL_LOADER)
diff --git a/net/url_request/url_request.cc b/net/url_request/url_request.cc index 942504c..aecb553 100644 --- a/net/url_request/url_request.cc +++ b/net/url_request/url_request.cc
@@ -133,11 +133,9 @@ NetLogWithSource CreateNetLogWithSource( NetLog* net_log, - absl::optional<uint32_t> net_log_source_id) { - if (net_log_source_id) { - return NetLogWithSource::Make( - net_log, - NetLogSource(NetLogSourceType::URL_REQUEST, net_log_source_id.value())); + absl::optional<net::NetLogSource> net_log_source) { + if (net_log_source) { + return NetLogWithSource::Make(net_log, net_log_source.value()); } return NetLogWithSource::Make(net_log, NetLogSourceType::URL_REQUEST); } @@ -559,9 +557,9 @@ const URLRequestContext* context, NetworkTrafficAnnotationTag traffic_annotation, bool is_for_websockets, - absl::optional<uint32_t> net_log_source_id) + absl::optional<net::NetLogSource> net_log_source) : context_(context), - net_log_(CreateNetLogWithSource(context->net_log(), net_log_source_id)), + net_log_(CreateNetLogWithSource(context->net_log(), net_log_source)), url_chain_(1, url), force_ignore_site_for_cookies_(false), force_ignore_top_frame_party_for_cookies_(false),
diff --git a/net/url_request/url_request.h b/net/url_request/url_request.h index 308ec99f..8cca710 100644 --- a/net/url_request/url_request.h +++ b/net/url_request/url_request.h
@@ -41,6 +41,7 @@ #include "net/http/http_response_headers.h" #include "net/http/http_response_info.h" #include "net/log/net_log_event_type.h" +#include "net/log/net_log_source.h" #include "net/log/net_log_with_source.h" #include "net/net_buildflags.h" #include "net/socket/connection_attempts.h" @@ -824,7 +825,7 @@ const URLRequestContext* context, NetworkTrafficAnnotationTag traffic_annotation, bool is_for_websockets, - absl::optional<uint32_t> net_log_source_id); + absl::optional<net::NetLogSource> net_log_source); // Resumes or blocks a request paused by the NetworkDelegate::OnBeforeRequest // handler. If |blocked| is true, the request is blocked and an error page is
diff --git a/net/url_request/url_request_context.cc b/net/url_request/url_request_context.cc index 382b195..045a1dc1 100644 --- a/net/url_request/url_request_context.cc +++ b/net/url_request/url_request_context.cc
@@ -22,6 +22,7 @@ #include "net/http/http_cache.h" #include "net/http/http_network_session.h" #include "net/http/http_transaction_factory.h" +#include "net/log/net_log_source.h" #include "net/socket/ssl_client_socket_impl.h" #include "net/url_request/url_request.h" @@ -102,10 +103,10 @@ URLRequest::Delegate* delegate, NetworkTrafficAnnotationTag traffic_annotation, bool is_for_websockets, - const absl::optional<uint32_t> net_log_source_id) const { + const absl::optional<net::NetLogSource> net_log_source) const { return base::WrapUnique(new URLRequest(url, priority, delegate, this, traffic_annotation, is_for_websockets, - net_log_source_id)); + net_log_source)); } void URLRequestContext::set_cookie_store(CookieStore* cookie_store) {
diff --git a/net/url_request/url_request_context.h b/net/url_request/url_request_context.h index 472ab4d..bd1a35c 100644 --- a/net/url_request/url_request_context.h +++ b/net/url_request/url_request_context.h
@@ -21,6 +21,7 @@ #include "build/chromeos_buildflags.h" #include "net/base/net_export.h" #include "net/base/request_priority.h" +#include "net/log/net_log_source.h" #include "net/net_buildflags.h" #include "net/traffic_annotation/network_traffic_annotation.h" #include "net/url_request/url_request.h" @@ -115,7 +116,8 @@ URLRequest::Delegate* delegate, NetworkTrafficAnnotationTag traffic_annotation, bool is_for_websockets = false, - const absl::optional<uint32_t> net_log_source_id = absl::nullopt) const; + const absl::optional<net::NetLogSource> net_log_source = + absl::nullopt) const; NetLog* net_log() const { return net_log_; }
diff --git a/remoting/protocol/BUILD.gn b/remoting/protocol/BUILD.gn index 4d9adbc..4c8a9a7 100644 --- a/remoting/protocol/BUILD.gn +++ b/remoting/protocol/BUILD.gn
@@ -273,11 +273,11 @@ "webrtc_audio_stream.h", "webrtc_connection_to_client.cc", "webrtc_connection_to_client.h", - "webrtc_dummy_video_encoder.cc", - "webrtc_dummy_video_encoder.h", "webrtc_frame_scheduler.h", "webrtc_frame_scheduler_simple.cc", "webrtc_frame_scheduler_simple.h", + "webrtc_video_encoder_factory.cc", + "webrtc_video_encoder_factory.h", "webrtc_video_encoder_wrapper.cc", "webrtc_video_encoder_wrapper.h", "webrtc_video_frame_adapter.cc",
diff --git a/remoting/protocol/webrtc_connection_to_client.cc b/remoting/protocol/webrtc_connection_to_client.cc index c1133ac..2e25a97c 100644 --- a/remoting/protocol/webrtc_connection_to_client.cc +++ b/remoting/protocol/webrtc_connection_to_client.cc
@@ -23,8 +23,8 @@ #include "remoting/protocol/message_pipe.h" #include "remoting/protocol/transport_context.h" #include "remoting/protocol/webrtc_audio_stream.h" -#include "remoting/protocol/webrtc_dummy_video_encoder.h" #include "remoting/protocol/webrtc_transport.h" +#include "remoting/protocol/webrtc_video_encoder_factory.h" #include "remoting/protocol/webrtc_video_stream.h" #include "third_party/webrtc/api/media_stream_interface.h" #include "third_party/webrtc/api/peer_connection_interface.h" @@ -47,8 +47,7 @@ audio_task_runner_(audio_task_runner), control_dispatcher_(new HostControlDispatcher()), event_dispatcher_(new HostEventDispatcher()) { - auto video_encoder_factory = - std::make_unique<WebrtcDummyVideoEncoderFactory>(); + auto video_encoder_factory = std::make_unique<WebrtcVideoEncoderFactory>(); video_encoder_factory_ = video_encoder_factory.get(); transport_ = std::make_unique<WebrtcTransport>( jingle_glue::JingleThreadWrapper::current(), transport_context,
diff --git a/remoting/protocol/webrtc_connection_to_client.h b/remoting/protocol/webrtc_connection_to_client.h index 9546067f..f3ada8f 100644 --- a/remoting/protocol/webrtc_connection_to_client.h +++ b/remoting/protocol/webrtc_connection_to_client.h
@@ -22,7 +22,7 @@ namespace remoting { namespace protocol { -class WebrtcDummyVideoEncoderFactory; +class WebrtcVideoEncoderFactory; class HostControlDispatcher; class HostEventDispatcher; @@ -92,7 +92,7 @@ std::unique_ptr<Session> session_; - WebrtcDummyVideoEncoderFactory* video_encoder_factory_; + WebrtcVideoEncoderFactory* video_encoder_factory_; scoped_refptr<base::SingleThreadTaskRunner> video_encode_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner_;
diff --git a/remoting/protocol/webrtc_frame_scheduler_simple.cc b/remoting/protocol/webrtc_frame_scheduler_simple.cc index e31bd5b..f58d5fb 100644 --- a/remoting/protocol/webrtc_frame_scheduler_simple.cc +++ b/remoting/protocol/webrtc_frame_scheduler_simple.cc
@@ -12,7 +12,6 @@ #include "remoting/base/constants.h" #include "remoting/protocol/frame_stats.h" #include "remoting/protocol/webrtc_bandwidth_estimator.h" -#include "remoting/protocol/webrtc_dummy_video_encoder.h" #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" namespace remoting {
diff --git a/remoting/protocol/webrtc_frame_scheduler_unittest.cc b/remoting/protocol/webrtc_frame_scheduler_unittest.cc index be9c4850..1d0b8b2 100644 --- a/remoting/protocol/webrtc_frame_scheduler_unittest.cc +++ b/remoting/protocol/webrtc_frame_scheduler_unittest.cc
@@ -10,7 +10,6 @@ #include "base/test/task_environment.h" #include "remoting/base/session_options.h" #include "remoting/protocol/frame_stats.h" -#include "remoting/protocol/webrtc_dummy_video_encoder.h" #include "remoting/protocol/webrtc_frame_scheduler_simple.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
diff --git a/remoting/protocol/webrtc_transport_unittest.cc b/remoting/protocol/webrtc_transport_unittest.cc index 2f7f771..354e22e 100644 --- a/remoting/protocol/webrtc_transport_unittest.cc +++ b/remoting/protocol/webrtc_transport_unittest.cc
@@ -28,7 +28,7 @@ #include "remoting/protocol/message_serialization.h" #include "remoting/protocol/network_settings.h" #include "remoting/protocol/transport_context.h" -#include "remoting/protocol/webrtc_dummy_video_encoder.h" +#include "remoting/protocol/webrtc_video_encoder_factory.h" #include "remoting/signaling/fake_signal_strategy.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/libjingle_xmpp/xmllite/xmlelement.h" @@ -216,8 +216,7 @@ host_transport_ = std::make_unique<WebrtcTransport>( jingle_glue::JingleThreadWrapper::current(), TransportContext::ForTests(TransportRole::SERVER), - std::make_unique<WebrtcDummyVideoEncoderFactory>(), - &host_event_handler_); + std::make_unique<WebrtcVideoEncoderFactory>(), &host_event_handler_); host_transport_->SetThreadJoinWatchdogForTests( std::make_unique<FakeThreadJoinWatchdog>(
diff --git a/remoting/protocol/webrtc_dummy_video_encoder.cc b/remoting/protocol/webrtc_video_encoder_factory.cc similarity index 78% rename from remoting/protocol/webrtc_dummy_video_encoder.cc rename to remoting/protocol/webrtc_video_encoder_factory.cc index 2edf5b09..78a21547 100644 --- a/remoting/protocol/webrtc_dummy_video_encoder.cc +++ b/remoting/protocol/webrtc_video_encoder_factory.cc
@@ -1,8 +1,8 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. +// 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 "remoting/protocol/webrtc_dummy_video_encoder.h" +#include "remoting/protocol/webrtc_video_encoder_factory.h" #include "base/bind.h" #include "base/logging.h" @@ -15,7 +15,7 @@ namespace remoting { namespace protocol { -WebrtcDummyVideoEncoderFactory::WebrtcDummyVideoEncoderFactory() +WebrtcVideoEncoderFactory::WebrtcVideoEncoderFactory() : main_task_runner_(base::ThreadTaskRunnerHandle::Get()) { formats_.push_back(webrtc::SdpVideoFormat("VP8")); formats_.push_back(webrtc::SdpVideoFormat("VP9")); @@ -26,10 +26,10 @@ #endif } -WebrtcDummyVideoEncoderFactory::~WebrtcDummyVideoEncoderFactory() = default; +WebrtcVideoEncoderFactory::~WebrtcVideoEncoderFactory() = default; std::unique_ptr<webrtc::VideoEncoder> -WebrtcDummyVideoEncoderFactory::CreateVideoEncoder( +WebrtcVideoEncoderFactory::CreateVideoEncoder( const webrtc::SdpVideoFormat& format) { webrtc::VideoCodecType type = webrtc::PayloadStringToCodecType(format.name); auto encoder = std::make_unique<WebrtcVideoEncoderWrapper>( @@ -44,18 +44,18 @@ } std::vector<webrtc::SdpVideoFormat> -WebrtcDummyVideoEncoderFactory::GetSupportedFormats() const { +WebrtcVideoEncoderFactory::GetSupportedFormats() const { return formats_; } -void WebrtcDummyVideoEncoderFactory::RegisterEncoderSelectedCallback( +void WebrtcVideoEncoderFactory::RegisterEncoderSelectedCallback( const base::RepeatingCallback< void(webrtc::VideoCodecType, const webrtc::SdpVideoFormat::Parameters&)>& callback) { encoder_created_callback_ = callback; } -void WebrtcDummyVideoEncoderFactory::SetVideoChannelStateObserver( +void WebrtcVideoEncoderFactory::SetVideoChannelStateObserver( base::WeakPtr<VideoChannelStateObserver> video_channel_state_observer) { DCHECK(main_task_runner_->BelongsToCurrentThread()); base::AutoLock lock(lock_);
diff --git a/remoting/protocol/webrtc_dummy_video_encoder.h b/remoting/protocol/webrtc_video_encoder_factory.h similarity index 83% rename from remoting/protocol/webrtc_dummy_video_encoder.h rename to remoting/protocol/webrtc_video_encoder_factory.h index aa18032e..183772f1a 100644 --- a/remoting/protocol/webrtc_dummy_video_encoder.h +++ b/remoting/protocol/webrtc_video_encoder_factory.h
@@ -1,9 +1,9 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. +// 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 REMOTING_PROTOCOL_WEBRTC_DUMMY_VIDEO_ENCODER_H_ -#define REMOTING_PROTOCOL_WEBRTC_DUMMY_VIDEO_ENCODER_H_ +#ifndef REMOTING_PROTOCOL_WEBRTC_VIDEO_ENCODER_FACTORY_H_ +#define REMOTING_PROTOCOL_WEBRTC_VIDEO_ENCODER_FACTORY_H_ #include <memory> #include <vector> @@ -24,10 +24,10 @@ // This is the encoder factory that is passed to WebRTC when the peer connection // is created. This factory creates the video encoder, which is an instance of // WebrtcVideoEncoderWrapper which wraps a video codec from remoting/codec. -class WebrtcDummyVideoEncoderFactory : public webrtc::VideoEncoderFactory { +class WebrtcVideoEncoderFactory : public webrtc::VideoEncoderFactory { public: - WebrtcDummyVideoEncoderFactory(); - ~WebrtcDummyVideoEncoderFactory() override; + WebrtcVideoEncoderFactory(); + ~WebrtcVideoEncoderFactory() override; // webrtc::VideoEncoderFactory interface. std::unique_ptr<webrtc::VideoEncoder> CreateVideoEncoder( @@ -60,4 +60,4 @@ } // namespace protocol } // namespace remoting -#endif // REMOTING_PROTOCOL_WEBRTC_DUMMY_VIDEO_ENCODER_H_ +#endif // REMOTING_PROTOCOL_WEBRTC_VIDEO_ENCODER_FACTORY_H_
diff --git a/remoting/protocol/webrtc_video_stream.cc b/remoting/protocol/webrtc_video_stream.cc index e9a37439..2c06210 100644 --- a/remoting/protocol/webrtc_video_stream.cc +++ b/remoting/protocol/webrtc_video_stream.cc
@@ -15,9 +15,9 @@ #include "remoting/codec/webrtc_video_encoder_vpx.h" #include "remoting/protocol/frame_stats.h" #include "remoting/protocol/host_video_stats_dispatcher.h" -#include "remoting/protocol/webrtc_dummy_video_encoder.h" #include "remoting/protocol/webrtc_frame_scheduler_simple.h" #include "remoting/protocol/webrtc_transport.h" +#include "remoting/protocol/webrtc_video_encoder_factory.h" #include "remoting/protocol/webrtc_video_frame_adapter.h" #include "remoting/protocol/webrtc_video_track_source.h" #include "third_party/webrtc/api/media_stream_interface.h" @@ -88,7 +88,7 @@ void WebrtcVideoStream::Start( std::unique_ptr<webrtc::DesktopCapturer> desktop_capturer, WebrtcTransport* webrtc_transport, - WebrtcDummyVideoEncoderFactory* video_encoder_factory, + WebrtcVideoEncoderFactory* video_encoder_factory, scoped_refptr<base::SequencedTaskRunner> encode_task_runner) { DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(desktop_capturer); @@ -104,7 +104,6 @@ encode_task_runner_ = std::move(encode_task_runner); capturer_ = std::move(desktop_capturer); - video_encoder_factory_ = video_encoder_factory; video_encoder_factory->RegisterEncoderSelectedCallback(base::BindRepeating( &WebrtcVideoStream::OnEncoderCreated, weak_factory_.GetWeakPtr())); @@ -339,7 +338,7 @@ // removed. // This method is called when SDP has been negotiated and WebRTC has - // created a preferred encoder via the WebrtcDummyVideoEncoderFactory + // created a preferred encoder via the WebrtcVideoEncoderFactory // implementation. // Trigger recreating the encoder in case a previous one was being used and // SDP renegotiation selected a different one. The proper encoder will be
diff --git a/remoting/protocol/webrtc_video_stream.h b/remoting/protocol/webrtc_video_stream.h index 11d0dd5a..824e7d97 100644 --- a/remoting/protocol/webrtc_video_stream.h +++ b/remoting/protocol/webrtc_video_stream.h
@@ -35,7 +35,7 @@ namespace protocol { class HostVideoStatsDispatcher; -class WebrtcDummyVideoEncoderFactory; +class WebrtcVideoEncoderFactory; class WebrtcFrameScheduler; class WebrtcTransport; @@ -53,7 +53,7 @@ void Start(std::unique_ptr<webrtc::DesktopCapturer> desktop_capturer, WebrtcTransport* webrtc_transport, - WebrtcDummyVideoEncoderFactory* video_encoder_factory, + WebrtcVideoEncoderFactory* video_encoder_factory, scoped_refptr<base::SequencedTaskRunner> encode_task_runner); // VideoStream interface. @@ -108,8 +108,6 @@ // Capturer used to capture the screen. std::unique_ptr<webrtc::DesktopCapturer> capturer_; - // Used to send across encoded frames. - WebrtcDummyVideoEncoderFactory* video_encoder_factory_; // Task runner used by software encoders. scoped_refptr<base::SequencedTaskRunner> encode_task_runner_;
diff --git a/sandbox/policy/mojom/sandbox.mojom b/sandbox/policy/mojom/sandbox.mojom index 27d2b11..21a62aa 100644 --- a/sandbox/policy/mojom/sandbox.mojom +++ b/sandbox/policy/mojom/sandbox.mojom
@@ -21,6 +21,9 @@ // For instance, it allows dynamic code and wider access to APIs on Windows. kUtility, + // The audio service process. May be disabled by policy. + kAudio, + // Hosts the content decryption module. Allows pre-loading of CDM libraries. // - On Windows, when `CdmServiceBroker` is connected the CDM was not // sandboxed to allow CDM preloading. @@ -28,6 +31,9 @@ // - On Linux/ChromeOS, the CDM is preloaded in the zygote sandbox. kCdm, + // The network service. May be disabled by policy. + kNetwork, + // Runs with the same rights as the browser. Usually needed to improve // stability by hosting code that interacts with third party code in another // process.
diff --git a/sandbox/policy/sandbox_type.h b/sandbox/policy/sandbox_type.h index 51ccf609..a2d3a4e 100644 --- a/sandbox/policy/sandbox_type.h +++ b/sandbox/policy/sandbox_type.h
@@ -125,10 +125,14 @@ inline constexpr sandbox::policy::SandboxType MapToSandboxType( sandbox::mojom::Sandbox mojo_sandbox) { switch (mojo_sandbox) { + case sandbox::mojom::Sandbox::kAudio: + return sandbox::policy::SandboxType::kAudio; case sandbox::mojom::Sandbox::kCdm: return sandbox::policy::SandboxType::kCdm; case sandbox::mojom::Sandbox::kGpu: return sandbox::policy::SandboxType::kGpu; + case sandbox::mojom::Sandbox::kNetwork: + return sandbox::policy::SandboxType::kNetwork; case sandbox::mojom::Sandbox::kNoSandbox: return sandbox::policy::SandboxType::kNoSandbox; case sandbox::mojom::Sandbox::kPrintCompositor:
diff --git a/services/audio/public/mojom/BUILD.gn b/services/audio/public/mojom/BUILD.gn index 869517c3..c877f960 100644 --- a/services/audio/public/mojom/BUILD.gn +++ b/services/audio/public/mojom/BUILD.gn
@@ -18,6 +18,7 @@ public_deps = [ "//media/mojo/mojom", "//mojo/public/mojom/base", + "//sandbox/policy/mojom", ] cpp_typemaps = [
diff --git a/services/audio/public/mojom/audio_service.mojom b/services/audio/public/mojom/audio_service.mojom index 2c1f4cd..65f5a369 100644 --- a/services/audio/public/mojom/audio_service.mojom +++ b/services/audio/public/mojom/audio_service.mojom
@@ -5,6 +5,7 @@ module audio.mojom; import "media/mojo/mojom/audio_stream_factory.mojom"; +import "sandbox/policy/mojom/sandbox.mojom"; import "services/audio/public/mojom/debug_recording.mojom"; import "services/audio/public/mojom/device_notifications.mojom"; import "services/audio/public/mojom/log_factory_manager.mojom"; @@ -12,7 +13,9 @@ import "services/audio/public/mojom/testing_api.mojom"; // The main interface to the Audio service. This is a privileged interface and -// must only be bound by trusted processes, e.g. a browser process. +// must only be bound by trusted processes, e.g. a browser process. Note that +// the sandbox can be disabled (to kNoSandbox) by policy. +[ServiceSandbox=sandbox.mojom.Sandbox.kAudio] interface AudioService { // Binds a SystemInfo interface receiver. BindSystemInfo(pending_receiver<SystemInfo> receiver); @@ -33,4 +36,3 @@ // environments. BindTestingApi(pending_receiver<TestingApi> receiver); }; -
diff --git a/services/data_decoder/BUILD.gn b/services/data_decoder/BUILD.gn index d3cdd331..8bb7fc80 100644 --- a/services/data_decoder/BUILD.gn +++ b/services/data_decoder/BUILD.gn
@@ -13,8 +13,6 @@ "gzipper.h", "json_parser_impl.cc", "json_parser_impl.h", - "web_bundle_builder.cc", - "web_bundle_builder.h", "web_bundler.cc", "web_bundler.h", "xml_parser.cc", @@ -65,7 +63,6 @@ "public/cpp/json_sanitizer_unittest.cc", "public/cpp/safe_web_bundle_parser_unittest.cc", "public/cpp/safe_xml_parser_unittest.cc", - "web_bundle_builder_unittest.cc", "xml_parser_unittest.cc", ]
diff --git a/services/data_decoder/web_bundle_builder.cc b/services/data_decoder/web_bundle_builder.cc deleted file mode 100644 index 63cb7bbe..0000000 --- a/services/data_decoder/web_bundle_builder.cc +++ /dev/null
@@ -1,153 +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 "services/data_decoder/web_bundle_builder.h" - -#include "base/big_endian.h" -#include "components/cbor/writer.h" - -namespace data_decoder { - -namespace { - -// TODO(myrzakereyms): replace this method with cbor::writer::GetNumUintBytes. -uint64_t GetNumUintBytes(uint64_t value) { - if (value < 24) { - return 0; - } else if (value <= 0xFF) { - return 1; - } else if (value <= 0xFFFF) { - return 2; - } else if (value <= 0xFFFFFFFF) { - return 4; - } - return 8; -} - -uint64_t GetEncodedByteSizeOfString(uint64_t size) { - return 1 + GetNumUintBytes(size); -} - -uint64_t GetEncodedByteSizeOfHeaders(const WebBundleBuilder::Headers& headers) { - uint64_t byte_size = 1 + GetNumUintBytes(headers.size()); - for (const auto& header : headers) { - byte_size += - GetEncodedByteSizeOfString(header.first.size()) + header.first.size() + - GetEncodedByteSizeOfString(header.second.size()) + header.second.size(); - } - return byte_size; -} - -uint64_t GetEncodedByteSizeOfResponse(const WebBundleBuilder::Headers& headers, - uint64_t body_size) { - uint64_t encoded_header_map_size = GetEncodedByteSizeOfHeaders(headers); - return 1 /* size of header of array(2) */ + - GetEncodedByteSizeOfString(encoded_header_map_size) + - encoded_header_map_size + GetEncodedByteSizeOfString(body_size) + - body_size; -} - -cbor::Value CreateByteString(base::StringPiece s) { - return cbor::Value(base::as_bytes(base::make_span(s))); -} - -cbor::Value CreateHeaderMap(const WebBundleBuilder::Headers& headers) { - cbor::Value::MapValue map; - for (const auto& pair : headers) - map.insert({CreateByteString(pair.first), CreateByteString(pair.second)}); - return cbor::Value(std::move(map)); -} - -std::vector<uint8_t> Encode(const cbor::Value& value) { - return *cbor::Writer::Write(value); -} - -int64_t EncodedLength(const cbor::Value& value) { - return Encode(value).size(); -} -} // namespace - -WebBundleBuilder::WebBundleBuilder(const std::string& fallback_url) - : fallback_url_(fallback_url) {} - -WebBundleBuilder::~WebBundleBuilder() = default; - -void WebBundleBuilder::SetExchanges( - std::vector<mojom::SerializedResourceInfoPtr> resources, - std::vector<absl::optional<mojo_base::BigBuffer>> bodies) { - CHECK_EQ(resources.size(), bodies.size()); - int64_t responses_offset = 1 + GetNumUintBytes(resources.size()); - for (size_t i = 0; i < resources.size(); ++i) { - const auto& info = resources[i]; - const auto& body = bodies[i]; - Headers headers = {{":status", "200"}, {"content-type", info->mime_type}}; - uint64_t response_length = - GetEncodedByteSizeOfResponse(headers, body ? body->size() : 0); - ResponseLocation location = {responses_offset, - static_cast<int64_t>(response_length)}; - responses_offset += response_length; - cbor::Value::ArrayValue response_array; - response_array.emplace_back(Encode(CreateHeaderMap(headers))); - response_array.emplace_back(CreateByteString( - body ? base::StringPiece(reinterpret_cast<const char*>(body->data()), - body->size()) - : "")); - cbor::Value response(response_array); - responses_.emplace_back(std::move(response)); - GURL url = info->url; - GURL::Replacements replacements; - replacements.ClearRef(); - url = url.ReplaceComponents(replacements); - AddIndexEntry(url.spec(), "", {location}); - } -} - -void WebBundleBuilder::AddIndexEntry( - base::StringPiece url, - base::StringPiece variants_value, - std::vector<ResponseLocation> response_locations) { - cbor::Value::ArrayValue index_value_array; - index_value_array.emplace_back(CreateByteString(variants_value)); - for (const auto& location : response_locations) { - index_value_array.emplace_back(location.offset); - index_value_array.emplace_back(location.length); - } - index_.insert({cbor::Value(url), cbor::Value(index_value_array)}); -} - -void WebBundleBuilder::AddSection(base::StringPiece name, cbor::Value section) { - section_lengths_.emplace_back(name); - section_lengths_.emplace_back(EncodedLength(section)); - sections_.emplace_back(std::move(section)); -} - -std::vector<uint8_t> WebBundleBuilder::CreateBundle( - std::vector<mojom::SerializedResourceInfoPtr> resources, - std::vector<absl::optional<mojo_base::BigBuffer>> bodies) { - SetExchanges(std::move(resources), std::move(bodies)); - AddSection("index", cbor::Value(index_)); - AddSection("responses", cbor::Value(responses_)); - return CreateTopLevel(); -} - -std::vector<uint8_t> WebBundleBuilder::CreateTopLevel() { - cbor::Value::ArrayValue toplevel_array; - toplevel_array.emplace_back( - CreateByteString(u8"\U0001F310\U0001F4E6")); // "🌐📦" - toplevel_array.emplace_back(CreateByteString(base::StringPiece("b1\0\0", 4))); - toplevel_array.emplace_back(cbor::Value(fallback_url_)); - toplevel_array.emplace_back(Encode(cbor::Value(section_lengths_))); - toplevel_array.emplace_back(sections_); - // Put a dummy 8-byte bytestring. - toplevel_array.emplace_back(cbor::Value::BinaryValue(8, 0)); - - std::vector<uint8_t> bundle = Encode(cbor::Value(toplevel_array)); - char encoded[8]; - base::WriteBigEndian(encoded, static_cast<uint64_t>(bundle.size())); - // Overwrite the dummy bytestring with the actual size. - memcpy(bundle.data() + bundle.size() - 8, encoded, 8); - - return bundle; -} -} // namespace data_decoder
diff --git a/services/data_decoder/web_bundle_builder.h b/services/data_decoder/web_bundle_builder.h deleted file mode 100644 index af461d7..0000000 --- a/services/data_decoder/web_bundle_builder.h +++ /dev/null
@@ -1,56 +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 SERVICES_DATA_DECODER_WEB_BUNDLE_BUILDER_H_ -#define SERVICES_DATA_DECODER_WEB_BUNDLE_BUILDER_H_ - -#include <vector> - -#include "base/files/file.h" -#include "base/strings/string_piece.h" -#include "components/cbor/values.h" -#include "mojo/public/cpp/base/big_buffer.h" -#include "services/data_decoder/public/mojom/resource_snapshot_for_web_bundle.mojom.h" -#include "third_party/abseil-cpp/absl/types/optional.h" - -namespace data_decoder { - -class WebBundleBuilder { - public: - using Headers = std::vector<std::pair<std::string, std::string>>; - struct ResponseLocation { - // /components/cbor uses int64_t for integer types. - int64_t offset; - int64_t length; - }; - - explicit WebBundleBuilder(const std::string& fallback_url); - ~WebBundleBuilder(); - - WebBundleBuilder(const WebBundleBuilder&) = delete; - WebBundleBuilder& operator=(const WebBundleBuilder&) = delete; - - std::vector<uint8_t> CreateBundle( - std::vector<mojom::SerializedResourceInfoPtr> resources, - std::vector<absl::optional<mojo_base::BigBuffer>> bodies); - - private: - void SetExchanges(std::vector<mojom::SerializedResourceInfoPtr> resources, - std::vector<absl::optional<mojo_base::BigBuffer>> bodies); - void AddIndexEntry(base::StringPiece url, - base::StringPiece variants_value, - std::vector<ResponseLocation> response_locations); - void AddSection(base::StringPiece name, cbor::Value section); - void WriteBundleLength(uint8_t bundle_length); - std::vector<uint8_t> CreateTopLevel(); - - std::string fallback_url_; - cbor::Value::ArrayValue section_lengths_; - cbor::Value::ArrayValue sections_; - cbor::Value::MapValue index_; - cbor::Value::ArrayValue responses_; -}; -} // namespace data_decoder - -#endif // SERVICES_DATA_DECODER_WEB_BUNDLE_BUILDER_H_
diff --git a/services/data_decoder/web_bundle_builder_unittest.cc b/services/data_decoder/web_bundle_builder_unittest.cc deleted file mode 100644 index 734511b6..0000000 --- a/services/data_decoder/web_bundle_builder_unittest.cc +++ /dev/null
@@ -1,80 +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 "services/data_decoder/web_bundle_builder.h" - -#include "base/big_endian.h" -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/path_service.h" -#include "base/test/task_environment.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace data_decoder { - -namespace { - -std::string kFallbackUrl = "https://test.example.org/"; - -std::string GetTestFileContents(const base::FilePath& path) { - base::FilePath test_data_dir; - base::PathService::Get(base::DIR_SOURCE_ROOT, &test_data_dir); - test_data_dir = test_data_dir.Append( - base::FilePath(FILE_PATH_LITERAL("components/test/data/web_package"))); - - std::string contents; - EXPECT_TRUE(base::ReadFileToString(test_data_dir.Append(path), &contents)); - return contents; -} - -std::vector<uint8_t> GetStringAsBytes(base::StringPiece contents) { - auto bytes = base::as_bytes(base::make_span(contents)); - return std::vector<uint8_t>(bytes.begin(), bytes.end()); -} - -} // namespace - -class WebBundleBuilderTest : public testing::Test { - private: - base::test::TaskEnvironment task_environment_; -}; - -TEST_F(WebBundleBuilderTest, CorrectWebBundleSizeIsWritten) { - WebBundleBuilder builder(kFallbackUrl); - std::vector<mojom::SerializedResourceInfoPtr> exchanges; - mojom::SerializedResourceInfoPtr ptr = mojom::SerializedResourceInfo::New( - GURL("https://test.example.org/index.html"), "text/html", 0); - exchanges.emplace_back(std::move(ptr)); - std::vector<absl::optional<mojo_base::BigBuffer>> bodies; - bodies.emplace_back(); - std::vector<uint8_t> bundle = - builder.CreateBundle(std::move(exchanges), std::move(bodies)); - char written_size[8]; - memcpy(written_size, bundle.data() + bundle.size() - 8, 8); - uint64_t written_size_int; - base::ReadBigEndian(written_size, &written_size_int); - EXPECT_EQ(bundle.size(), written_size_int); -} - -TEST_F(WebBundleBuilderTest, ByteByByteComparison) { - WebBundleBuilder builder(kFallbackUrl); - std::vector<mojom::SerializedResourceInfoPtr> exchanges; - std::vector<absl::optional<mojo_base::BigBuffer>> bodies; - exchanges.emplace_back(mojom::SerializedResourceInfo::New( - GURL("https://test.example.org/"), "text/html; charset=UTF-8", 46)); - bodies.emplace_back(absl::optional<mojo_base::BigBuffer>( - GetStringAsBytes("<a href='index.html'>click for web bundles</a>"))); - exchanges.emplace_back(mojom::SerializedResourceInfo::New( - GURL("https://test.example.org/index.html"), "text/html; charset=UTF-8", - 25)); - bodies.emplace_back(absl::optional<mojo_base::BigBuffer>( - GetStringAsBytes("<p>Hello Web Bundles!</p>"))); - std::vector<uint8_t> bundle = - builder.CreateBundle(std::move(exchanges), std::move(bodies)); - std::vector<uint8_t> expected_bundle = GetStringAsBytes( - GetTestFileContents(base::FilePath(FILE_PATH_LITERAL("simple.wbn")))); - EXPECT_EQ(bundle, expected_bundle); -} - -} // namespace data_decoder
diff --git a/services/data_decoder/web_bundler.cc b/services/data_decoder/web_bundler.cc index 0d715a14..5d057893 100644 --- a/services/data_decoder/web_bundler.cc +++ b/services/data_decoder/web_bundler.cc
@@ -7,7 +7,7 @@ #include "base/big_endian.h" #include "base/numerics/safe_conversions.h" #include "base/strings/string_piece.h" -#include "web_bundle_builder.h" +#include "components/web_package/web_bundle_builder.h" namespace data_decoder { @@ -93,7 +93,6 @@ GURL::Replacements replacements; replacements.ClearRef(); url = url.ReplaceComponents(replacements); - WebBundleBuilder builder(url.spec()); std::set<GURL> url_set; CHECK_EQ(resources_.size(), bodies_.size()); std::vector<mojom::SerializedResourceInfoPtr> resources; @@ -113,8 +112,28 @@ } } } - std::vector<uint8_t> bundle = - builder.CreateBundle(std::move(resources), std::move(bodies)); + + CHECK_EQ(resources.size(), bodies.size()); + web_package::WebBundleBuilder builder(url.spec(), "", + web_package::BundleVersion::kB2); + for (size_t i = 0; i < resources.size(); ++i) { + const auto& info = resources[i]; + const auto& body = bodies[i]; + web_package::WebBundleBuilder::Headers headers = { + {":status", "200"}, {"content-type", info->mime_type}}; + web_package::WebBundleBuilder::ResponseLocation response_location = + builder.AddResponse( + headers, body ? base::StringPiece( + reinterpret_cast<const char*>(body->data()), + body->size()) + : ""); + GURL url = info->url; + GURL::Replacements replacements; + replacements.ClearRef(); + url = url.ReplaceComponents(replacements); + builder.AddIndexEntry(url.spec(), "", {response_location}); + } + std::vector<uint8_t> bundle = builder.CreateBundle(); int written_size = file_.WriteAtCurrentPos( reinterpret_cast<const char*>(bundle.data()), bundle.size()); DCHECK_EQ(static_cast<int>(bundle.size()), written_size);
diff --git a/services/network/BUILD.gn b/services/network/BUILD.gn index bcb498b7..f8979929 100644 --- a/services/network/BUILD.gn +++ b/services/network/BUILD.gn
@@ -412,7 +412,7 @@ "//components/network_session_configurator/browser", "//components/prefs:test_support", "//components/variations:test_support", - "//components/web_package:test_support", + "//components/web_package", "//crypto", "//jingle:fake_ssl_socket", "//mojo/public/cpp/bindings",
diff --git a/services/network/cors/cors_url_loader.cc b/services/network/cors/cors_url_loader.cc index 26984e7..1d8527448 100644 --- a/services/network/cors/cors_url_loader.cc +++ b/services/network/cors/cors_url_loader.cc
@@ -255,8 +255,7 @@ receiver_.set_disconnect_handler( base::BindOnce(&CorsURLLoader::OnMojoDisconnect, base::Unretained(this))); - request_.net_log_params = - network::ResourceRequest::NetLogParams(net_log_.source().id); + request_.net_log_create_info = net_log_.source(); DCHECK(network_loader_factory_); DCHECK(origin_access_list_); DCHECK(preflight_controller_);
diff --git a/services/network/cors/cors_url_loader_factory.cc b/services/network/cors/cors_url_loader_factory.cc index 04517719..61ae8232 100644 --- a/services/network/cors/cors_url_loader_factory.cc +++ b/services/network/cors/cors_url_loader_factory.cc
@@ -513,10 +513,18 @@ return false; } - // |net_log_params| field is expected to be used within network service. - if (request.net_log_params.has_value()) { + // `net_log_create_info` field is expected to be used within network + // service. + if (request.net_log_create_info) { mojo::ReportBadMessage( - "CorsURLLoaderFactory: net_log_params field is not expected."); + "CorsURLLoaderFactory: net_log_create_info field is not expected."); + } + + // `net_log_reference_info` field is expected to be used within network + // service. + if (request.net_log_reference_info) { + mojo::ReportBadMessage( + "CorsURLLoaderFactory: net_log_reference_info field is not expected."); } if (request.target_ip_address_space != mojom::IPAddressSpace::kUnknown) {
diff --git a/services/network/cors/preflight_cache_unittest.cc b/services/network/cors/preflight_cache_unittest.cc index 7bb828f..7f2024a 100644 --- a/services/network/cors/preflight_cache_unittest.cc +++ b/services/network/cors/preflight_cache_unittest.cc
@@ -28,9 +28,9 @@ class PreflightCacheTest : public testing::Test { public: PreflightCacheTest() - : net_log_(net::NetLogWithSource::Make( - net::NetLog::Get(), - net::NetLogSourceType::CORS_URL_LOADER)) {} + : net_log_( + net::NetLogWithSource::Make(net::NetLog::Get(), + net::NetLogSourceType::URL_REQUEST)) {} protected: size_t CountEntries() const { return cache_.CountEntriesForTesting(); } @@ -242,7 +242,7 @@ std::vector<net::NetLogEntry> entries = net_log_observer.GetEntries(); ASSERT_EQ(entries.size(), 5u); for (const auto& entry : entries) { - EXPECT_EQ(entry.source.type, net::NetLogSourceType::CORS_URL_LOADER); + EXPECT_EQ(entry.source.type, net::NetLogSourceType::URL_REQUEST); } EXPECT_EQ(entries[0].type, net::NetLogEventType::CHECK_CORS_PREFLIGHT_CACHE); EXPECT_EQ(net::GetStringValueFromParams(entries[0], "status"),
diff --git a/services/network/cors/preflight_controller.cc b/services/network/cors/preflight_controller.cc index 05b66b5..22b629e6 100644 --- a/services/network/cors/preflight_controller.cc +++ b/services/network/cors/preflight_controller.cc
@@ -15,6 +15,8 @@ #include "net/base/load_flags.h" #include "net/base/network_isolation_key.h" #include "net/http/http_request_headers.h" +#include "net/log/net_log.h" +#include "net/log/net_log_source.h" #include "net/log/net_log_with_source.h" #include "services/network/cors/cors_util.h" #include "services/network/network_service.h" @@ -82,6 +84,7 @@ std::unique_ptr<ResourceRequest> CreatePreflightRequest( const ResourceRequest& request, bool tainted, + const net::NetLogSource& net_log_source, const absl::optional<base::UnguessableToken>& devtools_request_id) { DCHECK(!request.url.has_username()); DCHECK(!request.url.has_password()); @@ -153,6 +156,7 @@ } preflight_request->is_fetch_like_api = request.is_fetch_like_api; preflight_request->is_favicon = request.is_favicon; + preflight_request->net_log_reference_info = net_log_source; return preflight_request; } @@ -321,8 +325,8 @@ net_log_(net_log) { if (devtools_observer_) devtools_request_id_ = base::UnguessableToken::Create(); - auto preflight_request = - CreatePreflightRequest(request, tainted, devtools_request_id_); + auto preflight_request = CreatePreflightRequest( + request, tainted, net_log.source(), devtools_request_id_); if (devtools_observer_) { DCHECK(devtools_request_id_); @@ -468,7 +472,11 @@ PreflightController::CreatePreflightRequestForTesting( const ResourceRequest& request, bool tainted) { - return CreatePreflightRequest(request, tainted, absl::nullopt); + return CreatePreflightRequest( + request, tainted, + net::NetLogSource(net::NetLogSourceType::URL_REQUEST, + net::NetLog::Get()->NextID()), + /*devtools_request_id=*/absl::nullopt); } // static
diff --git a/services/network/cors/preflight_controller_unittest.cc b/services/network/cors/preflight_controller_unittest.cc index 3c23fb5..a974968f 100644 --- a/services/network/cors/preflight_controller_unittest.cc +++ b/services/network/cors/preflight_controller_unittest.cc
@@ -13,6 +13,8 @@ #include "mojo/public/cpp/bindings/remote.h" #include "net/base/load_flags.h" #include "net/http/http_request_headers.h" +#include "net/log/net_log.h" +#include "net/log/net_log_source_type.h" #include "net/log/net_log_with_source.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/embedded_test_server/http_request.h" @@ -224,19 +226,21 @@ network::ResourceRequest request; request.url = GURL("https://example.com/"); request.request_initiator = url::Origin(); + net::NetLogWithSource net_log = net::NetLogWithSource::Make( + net::NetLog::Get(), net::NetLogSourceType::URL_REQUEST); preflight_controller.PerformPreflightCheck( base::BindOnce([](int, absl::optional<CorsErrorStatus>, bool) {}), request, WithTrustedHeaderClient(false), WithNonWildcardRequestHeadersSupport(false), false /* tainted */, TRAFFIC_ANNOTATION_FOR_TESTS, &url_loader_factory, net::IsolationInfo(), - /*devtools_observer=*/mojo::NullRemote(), net::NetLogWithSource()); + /*devtools_observer=*/mojo::NullRemote(), net_log); preflight_controller.PerformPreflightCheck( base::BindOnce([](int, absl::optional<CorsErrorStatus>, bool) {}), request, WithTrustedHeaderClient(true), WithNonWildcardRequestHeadersSupport(false), false /* tainted */, TRAFFIC_ANNOTATION_FOR_TESTS, &url_loader_factory, net::IsolationInfo(), - /*devtools_observer=*/mojo::NullRemote(), net::NetLogWithSource()); + /*devtools_observer=*/mojo::NullRemote(), net_log); ASSERT_EQ(2, url_loader_factory.NumPending()); EXPECT_EQ(mojom::kURLLoadOptionAsCorsPreflight, @@ -443,7 +447,9 @@ request, WithTrustedHeaderClient(false), with_non_wildcard_request_headers_support_, tainted, TRAFFIC_ANNOTATION_FOR_TESTS, url_loader_factory_remote_.get(), - isolation_info, devtools_observer_->Bind(), net::NetLogWithSource()); + isolation_info, devtools_observer_->Bind(), + net::NetLogWithSource::Make(net::NetLog::Get(), + net::NetLogSourceType::URL_REQUEST)); run_loop_->Run(); }
diff --git a/services/network/public/cpp/resource_request.cc b/services/network/public/cpp/resource_request.cc index a24972b..da7f97c 100644 --- a/services/network/public/cpp/resource_request.cc +++ b/services/network/public/cpp/resource_request.cc
@@ -8,6 +8,7 @@ #include "base/strings/string_number_conversions.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "net/base/load_flags.h" +#include "net/log/net_log_source.h" #include "services/network/public/mojom/cookie_access_observer.mojom.h" #include "services/network/public/mojom/devtools_observer.mojom.h" #include "services/network/public/mojom/url_request.mojom.h" @@ -79,6 +80,13 @@ (lhs && rhs && lhs->EqualsForTesting(*rhs)); // IN-TEST } +bool OptionalNetLogInfoEqualsForTesting( + const absl::optional<net::NetLogSource>& lhs, + const absl::optional<net::NetLogSource>& rhs) { + bool equal_members = lhs && rhs && lhs.value() == rhs.value(); + return (!lhs && !rhs) || equal_members; +} + base::debug::CrashKeyString* GetRequestUrlCrashKey() { static auto* crash_key = base::debug::AllocateCrashKeyString( "request_url", base::debug::CrashKeySize::Size256); @@ -188,10 +196,6 @@ return new_remote; } -ResourceRequest::NetLogParams::NetLogParams() = default; -ResourceRequest::NetLogParams::NetLogParams(uint32_t id) : source_id(id) {} -ResourceRequest::NetLogParams::~NetLogParams() = default; - ResourceRequest::ResourceRequest() = default; ResourceRequest::ResourceRequest(const ResourceRequest& request) = default; ResourceRequest::~ResourceRequest() = default; @@ -254,6 +258,10 @@ trust_token_params == request.trust_token_params && OptionalWebBundleTokenParamsEqualsForTesting( // IN-TEST web_bundle_token_params, request.web_bundle_token_params) && + OptionalNetLogInfoEqualsForTesting(net_log_create_info, + request.net_log_create_info) && + OptionalNetLogInfoEqualsForTesting(net_log_reference_info, + request.net_log_reference_info) && target_ip_address_space == request.target_ip_address_space; }
diff --git a/services/network/public/cpp/resource_request.h b/services/network/public/cpp/resource_request.h index 2857fb52..4900119 100644 --- a/services/network/public/cpp/resource_request.h +++ b/services/network/public/cpp/resource_request.h
@@ -18,6 +18,7 @@ #include "net/cookies/site_for_cookies.h" #include "net/filter/source_stream.h" #include "net/http/http_request_headers.h" +#include "net/log/net_log_source.h" #include "net/url_request/referrer_policy.h" #include "services/network/public/cpp/optional_trust_token_params.h" #include "services/network/public/cpp/resource_request_body.h" @@ -101,16 +102,6 @@ int32_t render_process_id = -1; }; - // Typemapped to network.mojom.NetLogParams, see comments there for - // details of each field. - struct COMPONENT_EXPORT(NETWORK_CPP_BASE) NetLogParams { - NetLogParams(); - explicit NetLogParams(uint32_t id); - ~NetLogParams(); - - uint32_t source_id; - }; - ResourceRequest(); ResourceRequest(const ResourceRequest& request); ~ResourceRequest(); @@ -186,7 +177,8 @@ // decoding any non-listed stream types. absl::optional<std::vector<net::SourceStream::SourceType>> devtools_accepted_stream_types; - absl::optional<NetLogParams> net_log_params; + absl::optional<net::NetLogSource> net_log_create_info; + absl::optional<net::NetLogSource> net_log_reference_info; mojom::IPAddressSpace target_ip_address_space = mojom::IPAddressSpace::kUnknown; };
diff --git a/services/network/public/cpp/url_request_mojom_traits.cc b/services/network/public/cpp/url_request_mojom_traits.cc index 6bd3913..a1c4a34 100644 --- a/services/network/public/cpp/url_request_mojom_traits.cc +++ b/services/network/public/cpp/url_request_mojom_traits.cc
@@ -9,10 +9,13 @@ #include "base/debug/dump_without_crashing.h" #include "base/metrics/histogram_macros.h" #include "base/notreached.h" +#include "base/time/time.h" #include "mojo/public/cpp/base/file_mojom_traits.h" #include "mojo/public/cpp/base/file_path_mojom_traits.h" #include "mojo/public/cpp/base/time_mojom_traits.h" #include "mojo/public/cpp/base/unguessable_token_mojom_traits.h" +#include "net/log/net_log_source.h" +#include "net/log/net_log_source_type.h" #include "services/network/public/cpp/crash_keys.h" #include "services/network/public/cpp/http_request_headers_mojom_traits.h" #include "services/network/public/cpp/isolation_info_mojom_traits.h" @@ -115,11 +118,19 @@ return true; } -bool StructTraits<network::mojom::NetLogParamsDataView, - network::ResourceRequest::NetLogParams>:: - Read(network::mojom::NetLogParamsDataView data, - network::ResourceRequest::NetLogParams* out) { - out->source_id = data.source_id(); +bool StructTraits<network::mojom::NetLogSourceDataView, net::NetLogSource>:: + Read(network::mojom::NetLogSourceDataView data, net::NetLogSource* out) { + if (data.source_type() >= + static_cast<uint32_t>(net::NetLogSourceType::COUNT)) { + return false; + } + base::TimeTicks start_time; + if (!data.ReadStartTime(&start_time)) { + return false; + } + *out = + net::NetLogSource(static_cast<net::NetLogSourceType>(data.source_type()), + data.source_id(), start_time); return true; } @@ -168,7 +179,8 @@ !data.ReadWebBundleTokenParams(&out->web_bundle_token_params) || !data.ReadDevtoolsAcceptedStreamTypes( &out->devtools_accepted_stream_types) || - !data.ReadNetLogParams(&out->net_log_params)) { + !data.ReadNetLogCreateInfo(&out->net_log_create_info) || + !data.ReadNetLogReferenceInfo(&out->net_log_reference_info)) { // Note that data.ReadTrustTokenParams is temporarily handled below. return false; }
diff --git a/services/network/public/cpp/url_request_mojom_traits.h b/services/network/public/cpp/url_request_mojom_traits.h index 86e6558f..2d9ba69 100644 --- a/services/network/public/cpp/url_request_mojom_traits.h +++ b/services/network/public/cpp/url_request_mojom_traits.h
@@ -141,15 +141,19 @@ template <> struct COMPONENT_EXPORT(NETWORK_CPP_BASE) - StructTraits<network::mojom::NetLogParamsDataView, - network::ResourceRequest::NetLogParams> { - static uint32_t source_id( - const network::ResourceRequest::NetLogParams& params) { - return params.source_id; + StructTraits<network::mojom::NetLogSourceDataView, net::NetLogSource> { + static uint32_t source_id(const net::NetLogSource& params) { + return params.id; + } + static uint32_t source_type(const net::NetLogSource& params) { + return static_cast<uint32_t>(params.type); + } + static base::TimeTicks start_time(const net::NetLogSource& params) { + return params.start_time; } - static bool Read(network::mojom::NetLogParamsDataView data, - network::ResourceRequest::NetLogParams* out); + static bool Read(network::mojom::NetLogSourceDataView data, + net::NetLogSource* out); }; template <> @@ -333,9 +337,13 @@ web_bundle_token_params(const network::ResourceRequest& request) { return request.web_bundle_token_params; } - static const absl::optional<network::ResourceRequest::NetLogParams>& - net_log_params(const network::ResourceRequest& request) { - return request.net_log_params; + static const absl::optional<net::NetLogSource>& net_log_create_info( + const network::ResourceRequest& request) { + return request.net_log_create_info; + } + static const absl::optional<net::NetLogSource>& net_log_reference_info( + const network::ResourceRequest& request) { + return request.net_log_reference_info; } static network::mojom::IPAddressSpace target_ip_address_space( const network::ResourceRequest& request) {
diff --git a/services/network/public/cpp/url_request_mojom_traits_unittest.cc b/services/network/public/cpp/url_request_mojom_traits_unittest.cc index 15acead..ec93331 100644 --- a/services/network/public/cpp/url_request_mojom_traits_unittest.cc +++ b/services/network/public/cpp/url_request_mojom_traits_unittest.cc
@@ -10,6 +10,9 @@ #include "mojo/public/cpp/test_support/test_utils.h" #include "net/base/isolation_info.h" #include "net/filter/source_stream.h" +#include "net/log/net_log.h" +#include "net/log/net_log_source.h" +#include "net/log/net_log_source_type.h" #include "net/url_request/referrer_policy.h" #include "services/network/public/cpp/http_request_headers_mojom_traits.h" #include "services/network/public/cpp/network_ipc_param_traits.h" @@ -93,8 +96,10 @@ absl::make_optional(ResourceRequest::WebBundleTokenParams( GURL("https://bundle.test/"), base::UnguessableToken::Create(), mojo::PendingRemote<network::mojom::WebBundleHandle>())); - original.net_log_params = - absl::make_optional(ResourceRequest::NetLogParams()); + original.net_log_create_info = absl::make_optional(net::NetLogSource( + net::NetLogSourceType::URL_REQUEST, net::NetLog::Get()->NextID())); + original.net_log_reference_info = absl::make_optional(net::NetLogSource( + net::NetLogSourceType::URL_REQUEST, net::NetLog::Get()->NextID())); original.devtools_accepted_stream_types = std::vector<net::SourceStream::SourceType>( {net::SourceStream::SourceType::TYPE_BROTLI,
diff --git a/services/network/public/mojom/BUILD.gn b/services/network/public/mojom/BUILD.gn index f7bd3d8..76d478f6 100644 --- a/services/network/public/mojom/BUILD.gn +++ b/services/network/public/mojom/BUILD.gn
@@ -363,8 +363,8 @@ cpp = "::network::ResourceRequest::WebBundleTokenParams" }, { - mojom = "network.mojom.NetLogParams" - cpp = "::network::ResourceRequest::NetLogParams" + mojom = "network.mojom.NetLogSource" + cpp = "::net::NetLogSource" }, { mojom = "network.mojom.URLRequest" @@ -891,6 +891,7 @@ ":url_loader_base", ":websocket_mojom", "//mojo/public/mojom/base", + "//sandbox/policy/mojom", "//services/proxy_resolver/public/mojom", "//url/mojom:url_mojom_gurl", "//url/mojom:url_mojom_origin",
diff --git a/services/network/public/mojom/network_service.mojom b/services/network/public/mojom/network_service.mojom index 59fbbde6..a5cfff15 100644 --- a/services/network/public/mojom/network_service.mojom +++ b/services/network/public/mojom/network_service.mojom
@@ -13,6 +13,7 @@ import "mojo/public/mojom/base/time.mojom"; import "mojo/public/mojom/base/unguessable_token.mojom"; import "mojo/public/mojom/base/values.mojom"; +import "sandbox/policy/mojom/sandbox.mojom"; import "services/network/public/mojom/cookie_manager.mojom"; import "services/network/public/mojom/host_resolver.mojom"; import "services/network/public/mojom/http_raw_headers.mojom"; @@ -150,6 +151,9 @@ // // This is a trusted interface that only the browser process should have access // to. It must not be sent to any untrusted process like a renderer process. +// The network sandbox may be disabled (to kNoSandbox) by policy, and may not +// be available on all platforms. +[ServiceSandbox=sandbox.mojom.Sandbox.kNetwork] interface NetworkService { // Sets the parameters and initializes the service. SetParams(NetworkServiceParams params);
diff --git a/services/network/public/mojom/url_request.mojom b/services/network/public/mojom/url_request.mojom index 6ad6136..571ecc5 100644 --- a/services/network/public/mojom/url_request.mojom +++ b/services/network/public/mojom/url_request.mojom
@@ -99,13 +99,12 @@ }; // Options that may be set when URLRequests need to take over NetLog related -// parameters from CorsURLLoader. The URLRequest will reuse these parameters -// on logging. If set, contains parameters to construct a NetLogWithSource for -// the request. If not set, URLRequest constructs a NetLogWitSource with -// default parameters. -struct NetLogParams { - // The ID of NetLogSource. +// parameters. The URLRequest will use these parameters on logging. +// Typemapped to net::NetLogSource. +struct NetLogSource { + uint32 source_type; uint32 source_id; + mojo_base.mojom.TimeTicks start_time; }; // Typemapped to network::ResourceRequest. @@ -431,15 +430,23 @@ // decoding any non-listed stream types. array<SourceType>? devtools_accepted_stream_types; - // This field is set within the network service, more concretely by - // CorsURLLoader, and solely used there unless the loader factory is - // overridden. Setting this field by the process outside the network service - // is currently not expected and is invalid. - // If set correctly, it contains NetLog related parameters. This value is - // filled and used when network service creates a new request for preflights - // (which happens in CorsURLLoader). See the comment of NetLogParams for - // details. - NetLogParams? net_log_params; + // This field is filled and used when network service creates a new request + // for preflights (which happens in CorsURLLoader). So this field is set + // within the network service, more concretely by CorsURLLoader, and solely + // used there unless the loader factory is overridden. Setting this field by + // the process outside the network service is currently not expected and is + // invalid. + // If set, it contains NetLog related parameters to construct a NetLogSource + // for the request. If not set, URLRequest constructs a NetLogSource with + // default parameters. + NetLogSource? net_log_create_info; + + // This field is filled and used within network service. Setting this field + // by the process outside the network service is currently not expected and + // is invalid. + // If set, it contains NetLog related parameters to identify the initiator + // of the request in NetLog. + NetLogSource? net_log_reference_info; // The IP address space to which the target endpoint of this request should // belong, or `kUnknown` if there is no such requirement.
diff --git a/services/network/url_loader.cc b/services/network/url_loader.cc index 0fb3bda..d8af3893 100644 --- a/services/network/url_loader.cc +++ b/services/network/url_loader.cc
@@ -44,6 +44,8 @@ #include "net/cookies/static_cookie_policy.h" #include "net/dns/public/secure_dns_policy.h" #include "net/http/http_request_headers.h" +#include "net/log/net_log_source_type.h" +#include "net/log/net_log_with_source.h" #include "net/ssl/client_cert_store.h" #include "net/ssl/ssl_connection_status_flags.h" #include "net/ssl/ssl_private_key.h" @@ -542,10 +544,7 @@ base::BindOnce(&URLLoader::OnMojoDisconnect, base::Unretained(this))); url_request_ = url_request_context_->CreateRequest( GURL(request.url), request.priority, this, traffic_annotation, - /*is_for_websockets=*/false, - request.net_log_params - ? absl::make_optional(request.net_log_params->source_id) - : absl::nullopt); + /*is_for_websockets=*/false, request.net_log_create_info); url_request_->set_method(request.method); url_request_->set_site_for_cookies(request.site_for_cookies); @@ -653,6 +652,13 @@ *factory_params_->top_frame_id, keepalive_request_size_); } + if (request.net_log_reference_info) { + // Log source object that created the request, if avairable. + url_request_->net_log().AddEventReferencingSource( + net::NetLogEventType::CREATED_BY, + request.net_log_reference_info.value()); + } + #if defined(OS_ANDROID) if (base::FeatureList::IsEnabled(features::kRecordRadioWakeupTrigger)) { RadioMonitorAndroid::GetInstance().MaybeRecordURLLoaderAnnotationId(
diff --git a/services/network/web_bundle/web_bundle_manager_unittest.cc b/services/network/web_bundle/web_bundle_manager_unittest.cc index b2ca317..222b1c9 100644 --- a/services/network/web_bundle/web_bundle_manager_unittest.cc +++ b/services/network/web_bundle/web_bundle_manager_unittest.cc
@@ -7,7 +7,7 @@ #include "base/test/metrics/histogram_tester.h" #include "base/test/task_environment.h" #include "base/unguessable_token.h" -#include "components/web_package/test_support/web_bundle_builder.h" +#include "components/web_package/web_bundle_builder.h" #include "mojo/public/cpp/bindings/receiver_set.h" #include "mojo/public/cpp/system/data_pipe_utils.h" #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" @@ -35,8 +35,7 @@ const int32_t process_id2 = 200; std::string CreateSmallBundleString() { - web_package::test::WebBundleBuilder builder(kResourceUrl, - "" /* manifest_url */); + web_package::WebBundleBuilder builder(kResourceUrl, "" /* manifest_url */); builder.AddExchange(kResourceUrl, {{":status", "200"}, {"content-type", "text/plain"}}, "body"); @@ -398,8 +397,7 @@ // Create a not small size bundle to trigger the quota error while reading the // body of the subresource. - web_package::test::WebBundleBuilder builder(kResourceUrl, - "" /* manifest_url */); + web_package::WebBundleBuilder builder(kResourceUrl, "" /* manifest_url */); builder.AddExchange(kResourceUrl, {{":status", "200"}, {"content-type", "text/plain"}}, std::string(10000, 'X'));
diff --git a/services/network/web_bundle/web_bundle_url_loader_factory_unittest.cc b/services/network/web_bundle/web_bundle_url_loader_factory_unittest.cc index 3598a87..b0d05e2 100644 --- a/services/network/web_bundle/web_bundle_url_loader_factory_unittest.cc +++ b/services/network/web_bundle/web_bundle_url_loader_factory_unittest.cc
@@ -7,7 +7,7 @@ #include "base/callback_helpers.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/task_environment.h" -#include "components/web_package/test_support/web_bundle_builder.h" +#include "components/web_package/web_bundle_builder.h" #include "mojo/public/cpp/bindings/remote.h" #include "mojo/public/cpp/system/data_pipe_utils.h" #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" @@ -45,8 +45,7 @@ using ::testing::Pointee; std::vector<uint8_t> CreateSmallBundle() { - web_package::test::WebBundleBuilder builder(kResourceUrl, - "" /* manifest_url */); + web_package::WebBundleBuilder builder(kResourceUrl, "" /* manifest_url */); builder.AddExchange(kResourceUrl, {{":status", "200"}, {"content-type", "text/plain"}}, "body"); @@ -54,8 +53,7 @@ } std::vector<uint8_t> CreateLargeBundle() { - web_package::test::WebBundleBuilder builder(kResourceUrl, - "" /* manifest_url */); + web_package::WebBundleBuilder builder(kResourceUrl, "" /* manifest_url */); builder.AddExchange(kResourceUrl, {{":status", "200"}, {"content-type", "text/plain"}}, "body"); @@ -69,8 +67,8 @@ } std::vector<uint8_t> CreateCrossOriginBundle() { - web_package::test::WebBundleBuilder builder(kCrossOriginJsonUrl, - "" /* manifest_url */); + web_package::WebBundleBuilder builder(kCrossOriginJsonUrl, + "" /* manifest_url */); builder.AddExchange( kCrossOriginJsonUrl, {{":status", "200"}, {"content-type", "application/json"}}, @@ -304,8 +302,7 @@ } TEST_F(WebBundleURLLoaderFactoryTest, ResponseParseError) { - web_package::test::WebBundleBuilder builder(kResourceUrl, - "" /* manifest_url */); + web_package::WebBundleBuilder builder(kResourceUrl, "" /* manifest_url */); // An invalid response. builder.AddExchange(kResourceUrl, {{":status", "0"}}, "body"); WriteBundle(builder.CreateBundle()); @@ -357,8 +354,7 @@ } TEST_F(WebBundleURLLoaderFactoryTest, RedirectResponseIsNotAllowed) { - web_package::test::WebBundleBuilder builder(kResourceUrl, - "" /* manifest_url */); + web_package::WebBundleBuilder builder(kResourceUrl, "" /* manifest_url */); builder.AddExchange(kResourceUrl, {{":status", "301"}, {"location", kResourceUrl2}}, ""); builder.AddExchange(kResourceUrl2,
diff --git a/testing/buildbot/chromium.android.fyi.json b/testing/buildbot/chromium.android.fyi.json index 3b59a117..de24201 100644 --- a/testing/buildbot/chromium.android.fyi.json +++ b/testing/buildbot/chromium.android.fyi.json
@@ -5782,7 +5782,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M95", - "revision": "version:95.0.4638.47" + "revision": "version:95.0.4638.48" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -5869,7 +5869,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M96", - "revision": "version:96.0.4664.5" + "revision": "version:96.0.4664.6" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -6043,7 +6043,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M95", - "revision": "version:95.0.4638.47" + "revision": "version:95.0.4638.48" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -6130,7 +6130,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M96", - "revision": "version:96.0.4664.5" + "revision": "version:96.0.4664.6" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json index 76ee7126..3ee72f4 100644 --- a/testing/buildbot/chromium.android.json +++ b/testing/buildbot/chromium.android.json
@@ -58019,7 +58019,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M95", - "revision": "version:95.0.4638.47" + "revision": "version:95.0.4638.48" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -58107,7 +58107,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M96", - "revision": "version:96.0.4664.5" + "revision": "version:96.0.4664.6" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -58283,7 +58283,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M95", - "revision": "version:95.0.4638.47" + "revision": "version:95.0.4638.48" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -58371,7 +58371,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M96", - "revision": "version:96.0.4664.5" + "revision": "version:96.0.4664.6" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -58620,7 +58620,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M95", - "revision": "version:95.0.4638.47" + "revision": "version:95.0.4638.48" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -58707,7 +58707,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M96", - "revision": "version:96.0.4664.5" + "revision": "version:96.0.4664.6" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -58881,7 +58881,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M95", - "revision": "version:95.0.4638.47" + "revision": "version:95.0.4638.48" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -58968,7 +58968,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M96", - "revision": "version:96.0.4664.5" + "revision": "version:96.0.4664.6" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -59217,7 +59217,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M95", - "revision": "version:95.0.4638.47" + "revision": "version:95.0.4638.48" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -59304,7 +59304,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M96", - "revision": "version:96.0.4664.5" + "revision": "version:96.0.4664.6" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -59478,7 +59478,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M95", - "revision": "version:95.0.4638.47" + "revision": "version:95.0.4638.48" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -59565,7 +59565,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M96", - "revision": "version:96.0.4664.5" + "revision": "version:96.0.4664.6" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json index 69d05b6..470771d 100644 --- a/testing/buildbot/chromium.chromiumos.json +++ b/testing/buildbot/chromium.chromiumos.json
@@ -5898,21 +5898,21 @@ }, { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v97.0.4666.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v97.0.4667.0/test_ash_chrome", "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_Lacros version skew testing ash 97.0.4666.0", + "name": "lacros_chrome_browsertests_Lacros version skew testing ash 97.0.4667.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v97.0.4666.0", - "revision": "version:97.0.4666.0" + "location": "lacros_version_skew_tests_v97.0.4667.0", + "revision": "version:97.0.4667.0" } ], "dimension_sets": [ @@ -6006,21 +6006,21 @@ }, { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v97.0.4666.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v97.0.4667.0/test_ash_chrome", "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 97.0.4666.0", + "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 97.0.4667.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v97.0.4666.0", - "revision": "version:97.0.4666.0" + "location": "lacros_version_skew_tests_v97.0.4667.0", + "revision": "version:97.0.4667.0" } ], "dimension_sets": [
diff --git a/testing/buildbot/chromium.dev.json b/testing/buildbot/chromium.dev.json index 2da8f7c..c0d4542 100644 --- a/testing/buildbot/chromium.dev.json +++ b/testing/buildbot/chromium.dev.json
@@ -709,6 +709,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { + "cores": "8|12", "cpu": "x86-64", "os": "Mac-10.15" }
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 461f2354..22e26823 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -91676,7 +91676,7 @@ }, { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v97.0.4666.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v97.0.4667.0/test_ash_chrome", "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter" ], "isolate_profile_data": true, @@ -91684,14 +91684,14 @@ "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_Lacros version skew testing ash 97.0.4666.0", + "name": "lacros_chrome_browsertests_Lacros version skew testing ash 97.0.4667.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v97.0.4666.0", - "revision": "version:97.0.4666.0" + "location": "lacros_version_skew_tests_v97.0.4667.0", + "revision": "version:97.0.4667.0" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -91768,7 +91768,7 @@ }, { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v97.0.4666.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v97.0.4667.0/test_ash_chrome", "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter" ], "isolate_profile_data": true, @@ -91776,14 +91776,14 @@ "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 97.0.4666.0", + "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 97.0.4667.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v97.0.4666.0", - "revision": "version:97.0.4666.0" + "location": "lacros_version_skew_tests_v97.0.4667.0", + "revision": "version:97.0.4667.0" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -93161,21 +93161,21 @@ }, { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v97.0.4666.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v97.0.4667.0/test_ash_chrome", "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_Lacros version skew testing ash 97.0.4666.0", + "name": "lacros_chrome_browsertests_Lacros version skew testing ash 97.0.4667.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v97.0.4666.0", - "revision": "version:97.0.4666.0" + "location": "lacros_version_skew_tests_v97.0.4667.0", + "revision": "version:97.0.4667.0" } ], "dimension_sets": [ @@ -93273,21 +93273,21 @@ }, { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v97.0.4666.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v97.0.4667.0/test_ash_chrome", "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 97.0.4666.0", + "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 97.0.4667.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v97.0.4666.0", - "revision": "version:97.0.4666.0" + "location": "lacros_version_skew_tests_v97.0.4667.0", + "revision": "version:97.0.4667.0" } ], "dimension_sets": [ @@ -94834,21 +94834,21 @@ }, { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v97.0.4666.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v97.0.4667.0/test_ash_chrome", "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_Lacros version skew testing ash 97.0.4666.0", + "name": "lacros_chrome_browsertests_Lacros version skew testing ash 97.0.4667.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v97.0.4666.0", - "revision": "version:97.0.4666.0" + "location": "lacros_version_skew_tests_v97.0.4667.0", + "revision": "version:97.0.4667.0" } ], "dimension_sets": [ @@ -94946,21 +94946,21 @@ }, { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v97.0.4666.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v97.0.4667.0/test_ash_chrome", "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 97.0.4666.0", + "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 97.0.4667.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v97.0.4666.0", - "revision": "version:97.0.4666.0" + "location": "lacros_version_skew_tests_v97.0.4667.0", + "revision": "version:97.0.4667.0" } ], "dimension_sets": [ @@ -95703,21 +95703,21 @@ }, { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v97.0.4666.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v97.0.4667.0/test_ash_chrome", "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_Lacros version skew testing ash 97.0.4666.0", + "name": "lacros_chrome_browsertests_Lacros version skew testing ash 97.0.4667.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v97.0.4666.0", - "revision": "version:97.0.4666.0" + "location": "lacros_version_skew_tests_v97.0.4667.0", + "revision": "version:97.0.4667.0" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -95799,21 +95799,21 @@ }, { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v97.0.4666.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v97.0.4667.0/test_ash_chrome", "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 97.0.4666.0", + "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 97.0.4667.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v97.0.4666.0", - "revision": "version:97.0.4666.0" + "location": "lacros_version_skew_tests_v97.0.4667.0", + "revision": "version:97.0.4667.0" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index 01728ec..a53e748 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -1340,6 +1340,17 @@ '--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.content_browsertests.filter', ], }, + # https://crbug.com/1255940 + 'mac-rel-swarming': { + 'swarming': { + 'dimension_sets': [ + { + # These test would time out when running on 4 cores instances. + 'cores': '8|12', + } + ], + }, + }, }, }, 'content_browsertests_wayland': {
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl index a1dbab1fe..37db846 100644 --- a/testing/buildbot/variants.pyl +++ b/testing/buildbot/variants.pyl
@@ -52,16 +52,16 @@ }, 'LACROS_VERSION_SKEW_CANARY': { 'args': [ - '--ash-chrome-path-override=../../lacros_version_skew_tests_v97.0.4666.0/test_ash_chrome', + '--ash-chrome-path-override=../../lacros_version_skew_tests_v97.0.4667.0/test_ash_chrome', '--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter', ], - 'identifier': 'Lacros version skew testing ash 97.0.4666.0', + 'identifier': 'Lacros version skew testing ash 97.0.4667.0', 'swarming': { 'cipd_packages': [ { 'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip', - 'location': 'lacros_version_skew_tests_v97.0.4666.0', - 'revision': 'version:97.0.4666.0', + 'location': 'lacros_version_skew_tests_v97.0.4667.0', + 'revision': 'version:97.0.4667.0', }, ], }, @@ -387,7 +387,7 @@ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M96', - 'revision': 'version:96.0.4664.5', + 'revision': 'version:96.0.4664.6', } ], }, @@ -411,7 +411,7 @@ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M95', - 'revision': 'version:95.0.4638.47', + 'revision': 'version:95.0.4638.48', } ], }, @@ -459,7 +459,7 @@ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M96', - 'revision': 'version:96.0.4664.5', + 'revision': 'version:96.0.4664.6', } ], }, @@ -483,7 +483,7 @@ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M95', - 'revision': 'version:95.0.4638.47', + 'revision': 'version:95.0.4638.48', } ], }, @@ -531,7 +531,7 @@ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M96', - 'revision': 'version:96.0.4664.5', + 'revision': 'version:96.0.4664.6', } ], }, @@ -555,7 +555,7 @@ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M95', - 'revision': 'version:95.0.4638.47', + 'revision': 'version:95.0.4638.48', } ], },
diff --git a/third_party/blink/public/devtools_protocol/OWNERS b/third_party/blink/public/devtools_protocol/OWNERS index 30b2e7e7..cacd3c83 100644 --- a/third_party/blink/public/devtools_protocol/OWNERS +++ b/third_party/blink/public/devtools_protocol/OWNERS
@@ -1,3 +1,4 @@ +alexrudenko@chromium.org caseq@chromium.org dgozman@chromium.org pfeldman@chromium.org
diff --git a/third_party/blink/renderer/core/css/cssom/css_rotate.cc b/third_party/blink/renderer/core/css/cssom/css_rotate.cc index afb154a..86f5a82e 100644 --- a/third_party/blink/renderer/core/css/cssom/css_rotate.cc +++ b/third_party/blink/renderer/core/css/cssom/css_rotate.cc
@@ -163,11 +163,6 @@ } const CSSFunctionValue* CSSRotate::ToCSSValue() const { - DCHECK(x_->to(CSSPrimitiveValue::UnitType::kNumber)); - DCHECK(y_->to(CSSPrimitiveValue::UnitType::kNumber)); - DCHECK(z_->to(CSSPrimitiveValue::UnitType::kNumber)); - DCHECK(angle_->to(CSSPrimitiveValue::UnitType::kRadians)); - CSSFunctionValue* result = MakeGarbageCollected<CSSFunctionValue>( is2D() ? CSSValueID::kRotate : CSSValueID::kRotate3d); if (!is2D()) { @@ -186,6 +181,11 @@ if (!angle) return nullptr; + DCHECK(x_->to(CSSPrimitiveValue::UnitType::kNumber)); + DCHECK(y_->to(CSSPrimitiveValue::UnitType::kNumber)); + DCHECK(z_->to(CSSPrimitiveValue::UnitType::kNumber)); + DCHECK(angle_->to(CSSPrimitiveValue::UnitType::kRadians)); + result->Append(*angle); return result; }
diff --git a/third_party/blink/renderer/core/frame/visual_viewport_test.cc b/third_party/blink/renderer/core/frame/visual_viewport_test.cc index 8d7186a..161fb0a 100644 --- a/third_party/blink/renderer/core/frame/visual_viewport_test.cc +++ b/third_party/blink/renderer/core/frame/visual_viewport_test.cc
@@ -854,8 +854,8 @@ // Ensure the scroll contents size matches the frame view's size. EXPECT_EQ(gfx::Size(320, 240), visual_viewport.LayerForScrolling()->bounds()); - EXPECT_EQ(gfx::Size(320, 240), - visual_viewport.GetScrollNode()->ContentsSize()); + EXPECT_EQ(gfx::Rect(0, 0, 320, 240), + visual_viewport.GetScrollNode()->ContentsRect()); // Ensure the location and scale were reset. EXPECT_EQ(FloatSize(), visual_viewport.GetScrollOffset()); @@ -1720,7 +1720,7 @@ float scale = GetFrame()->GetPage()->GetVisualViewport().Scale(); EXPECT_EQ(gfx::Size(100 / scale, 150 / scale), scroll_node->ContainerRect().size()); - EXPECT_EQ(gfx::Size(1500, 2400), scroll_node->ContentsSize()); + EXPECT_EQ(gfx::Rect(0, 0, 1500, 2400), scroll_node->ContentsRect()); } // Tests that resizing the visual viepwort keeps its bounds within the outer @@ -2517,20 +2517,20 @@ VisualViewport& visual_viewport = WebView().GetPage()->GetVisualViewport(); EXPECT_EQ(gfx::Size(320, 480), visual_viewport.LayerForScrolling()->bounds()); - EXPECT_EQ(gfx::Size(400, 600), - visual_viewport.GetScrollNode()->ContainerRect().size()); - EXPECT_EQ(gfx::Size(320, 480), - visual_viewport.GetScrollNode()->ContentsSize()); + EXPECT_EQ(gfx::Rect(0, 0, 400, 600), + visual_viewport.GetScrollNode()->ContainerRect()); + EXPECT_EQ(gfx::Rect(0, 0, 320, 480), + visual_viewport.GetScrollNode()->ContentsRect()); WebView().MainFrameViewWidget()->ApplyViewportChangesForTesting( {gfx::Vector2dF(1, 1), gfx::Vector2dF(), 2, false, 1, 0, cc::BrowserControlsState::kBoth}); EXPECT_EQ(gfx::Size(320, 480), visual_viewport.LayerForScrolling()->bounds()); - EXPECT_EQ(gfx::Size(400, 600), - visual_viewport.GetScrollNode()->ContainerRect().size()); - EXPECT_EQ(gfx::Size(320, 480), - visual_viewport.GetScrollNode()->ContentsSize()); + EXPECT_EQ(gfx::Rect(0, 0, 400, 600), + visual_viewport.GetScrollNode()->ContainerRect()); + EXPECT_EQ(gfx::Rect(0, 0, 320, 480), + visual_viewport.GetScrollNode()->ContentsRect()); } class VisualViewportScrollIntoViewTest : public VisualViewportSimTest {
diff --git a/third_party/blink/renderer/core/frame/web_frame_test.cc b/third_party/blink/renderer/core/frame/web_frame_test.cc index b178e732..f8afaf0 100644 --- a/third_party/blink/renderer/core/frame/web_frame_test.cc +++ b/third_party/blink/renderer/core/frame/web_frame_test.cc
@@ -2051,8 +2051,8 @@ auto* scroll_node = visual_viewport.GetScrollTranslationNode()->ScrollNode(); EXPECT_EQ(gfx::Rect(viewport_width, viewport_height), scroll_node->ContainerRect()); - EXPECT_EQ(gfx::Size(viewport_width, viewport_height), - scroll_node->ContentsSize()); + EXPECT_EQ(gfx::Rect(viewport_width, viewport_height), + scroll_node->ContentsRect()); } TEST_F(WebFrameTest, SetForceZeroLayoutHeight) {
diff --git a/third_party/blink/renderer/core/html/forms/file_input_type.cc b/third_party/blink/renderer/core/html/forms/file_input_type.cc index 3b04500..71bd003 100644 --- a/third_party/blink/renderer/core/html/forms/file_input_type.cc +++ b/third_party/blink/renderer/core/html/forms/file_input_type.cc
@@ -126,7 +126,7 @@ auto* file_list = MakeGarbageCollected<FileList>(); for (const auto& file : file_vector) file_list->Append(file); - SetFilesAndDispatchEvents(file_list); + SetFiles(file_list); } void FileInputType::AppendToFormData(FormData& form_data) const {
diff --git a/third_party/blink/renderer/core/html/html_frame_owner_element.cc b/third_party/blink/renderer/core/html/html_frame_owner_element.cc index 1bbd7b6..b7c229e4 100644 --- a/third_party/blink/renderer/core/html/html_frame_owner_element.cc +++ b/third_party/blink/renderer/core/html/html_frame_owner_element.cc
@@ -22,6 +22,7 @@ #include "base/feature_list.h" #include "base/metrics/field_trial_params.h" +#include "base/metrics/histogram_functions.h" #include "services/network/public/mojom/content_security_policy.mojom-blink-forward.h" #include "third_party/blink/public/common/features.h" #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h" @@ -196,12 +197,26 @@ return allowed_websites; } +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. +enum class AutomaticLazyLoadFrame { + kFeatureNotEnabled = 0, + kTargetFramesNotFound = 1, + kTargetFramesFound = 2, + kMaxValue = kTargetFramesFound, +}; + // Checks if the passed `url` is in the allowlist for automatic lazy-loading. // Returns true if the feature flag is enabled and the url is in the list. bool IsLazyLoadableUrl(KURL url) { + constexpr const char kAutomaticLazyLoadFrameHistogram[] = + "Blink.AutomaticLazyLoadFrame"; if (!base::FeatureList::IsEnabled( - features::kAutomaticLazyFrameLoadingToEmbeds)) + features::kAutomaticLazyFrameLoadingToEmbeds)) { + base::UmaHistogramEnumeration(kAutomaticLazyLoadFrameHistogram, + AutomaticLazyLoadFrame::kFeatureNotEnabled); return false; + } scoped_refptr<const SecurityOrigin> origin = SecurityOrigin::Create(url); for (const auto& it : AllowedWebsitesForLazyLoading()) { @@ -214,10 +229,17 @@ // test. That will affect the test reliability. if ((origin.get()->Protocol() == it.first->Protocol() && origin.get()->Host() == it.first->Host()) && - (url.GetPath().Contains(it.second) || url.Query().Contains(it.second))) + (url.GetPath().Contains(it.second) || + url.Query().Contains(it.second))) { + base::UmaHistogramEnumeration(kAutomaticLazyLoadFrameHistogram, + AutomaticLazyLoadFrame::kTargetFramesFound); return true; + } } + base::UmaHistogramEnumeration(kAutomaticLazyLoadFrameHistogram, + AutomaticLazyLoadFrame::kTargetFramesNotFound); + return false; }
diff --git a/third_party/blink/renderer/core/html/html_marquee_element.cc b/third_party/blink/renderer/core/html/html_marquee_element.cc index a6be9d67..af29bf4f 100644 --- a/third_party/blink/renderer/core/html/html_marquee_element.cc +++ b/third_party/blink/renderer/core/html/html_marquee_element.cc
@@ -56,7 +56,7 @@ HTMLMarqueeElement::HTMLMarqueeElement(Document& document) : HTMLElement(html_names::kMarqueeTag, document) { UseCounter::Count(document, WebFeature::kHTMLMarqueeElement); - EnsureUserAgentShadowRoot(); + EnsureUserAgentShadowRoot().EnableNameBasedSlotAssignment(); } void HTMLMarqueeElement::DidAddUserAgentShadowRoot(ShadowRoot& shadow_root) { @@ -73,8 +73,7 @@ auto* mover = MakeGarbageCollected<HTMLDivElement>(GetDocument()); shadow_root.AppendChild(mover); - mover->AppendChild( - HTMLSlotElement::CreateUserAgentDefaultSlot(GetDocument())); + mover->AppendChild(MakeGarbageCollected<HTMLSlotElement>(GetDocument())); mover_ = mover; }
diff --git a/third_party/blink/renderer/core/html/html_meter_element.cc b/third_party/blink/renderer/core/html/html_meter_element.cc index 3349032..b8a24f34 100644 --- a/third_party/blink/renderer/core/html/html_meter_element.cc +++ b/third_party/blink/renderer/core/html/html_meter_element.cc
@@ -40,7 +40,7 @@ HTMLMeterElement::HTMLMeterElement(Document& document) : HTMLElement(html_names::kMeterTag, document) { UseCounter::Count(document, WebFeature::kMeterElement); - EnsureUserAgentShadowRoot(); + EnsureUserAgentShadowRoot().EnableNameBasedSlotAssignment(); } HTMLMeterElement::~HTMLMeterElement() = default; @@ -191,8 +191,7 @@ inner->AppendChild(bar); auto* fallback = MakeGarbageCollected<HTMLDivElement>(GetDocument()); - fallback->AppendChild( - HTMLSlotElement::CreateUserAgentDefaultSlot(GetDocument())); + fallback->AppendChild(MakeGarbageCollected<HTMLSlotElement>(GetDocument())); fallback->SetShadowPseudoId(AtomicString("-internal-fallback")); root.AppendChild(fallback); }
diff --git a/third_party/blink/renderer/core/layout/layout_tree_as_text.cc b/third_party/blink/renderer/core/layout/layout_tree_as_text.cc index aee7d50..edb3f74 100644 --- a/third_party/blink/renderer/core/layout/layout_tree_as_text.cc +++ b/third_party/blink/renderer/core/layout/layout_tree_as_text.cc
@@ -459,7 +459,7 @@ ts << " state=(" << fragment->LocalBorderBoxProperties().ToString() << ")"; } - if (RuntimeEnabledFeatures::CullRectUpdateEnabled()) { + if (RuntimeEnabledFeatures::CullRectUpdateEnabled() && o.HasLayer()) { ts << " cull_rect=(" << fragment->GetCullRect().ToString() << ") contents_cull_rect=(" << fragment->GetContentsCullRect().ToString() << ")";
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.cc index 8ce470ec..0960068 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.cc
@@ -357,8 +357,8 @@ line[new_index].rect.offset.inline_offset += line[index_right].inline_size - line[new_index].inline_size; PlaceEllipsisNextTo(line_box, &line[new_index]); - available_width_left += - available_width_right - line[new_index].inline_size; + available_width_left += available_width_right - + line[new_index].inline_size.ClampNegativeToZero(); } LayoutUnit ellipsis_offset = line[line.size() - 1].InlineOffset();
diff --git a/third_party/blink/renderer/core/paint/box_painter_test.cc b/third_party/blink/renderer/core/paint/box_painter_test.cc index e423f58..53ca4ec 100644 --- a/third_party/blink/renderer/core/paint/box_painter_test.cc +++ b/third_party/blink/renderer/core/paint/box_painter_test.cc
@@ -287,7 +287,7 @@ const auto& contents_transform = ToUnaliased(contents_chunk.properties.Transform()); const auto* contents_scroll = contents_transform.ScrollNode(); - EXPECT_EQ(gfx::Size(200, 300), contents_scroll->ContentsSize()); + EXPECT_EQ(gfx::Rect(0, 0, 200, 300), contents_scroll->ContentsRect()); EXPECT_EQ(gfx::Rect(0, 0, 200, 200), contents_scroll->ContainerRect()); const auto& contents_clip = ToUnaliased(contents_chunk.properties.Clip()); EXPECT_EQ(FloatRect(0, 0, 200, 200), contents_clip.PaintClipRect().Rect());
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc b/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc index bcd4091..152192f 100644 --- a/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc +++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc
@@ -221,7 +221,7 @@ const auto* scroll = scroller_properties->ScrollTranslation()->ScrollNode(); EXPECT_EQ(DocScroll(), scroll->Parent()); EXPECT_EQ(gfx::Rect(0, 0, 413, 317), scroll->ContainerRect()); - EXPECT_EQ(gfx::Size(660, 10200), scroll->ContentsSize()); + EXPECT_EQ(gfx::Rect(0, 0, 660, 10200), scroll->ContentsRect()); EXPECT_FALSE(scroll->UserScrollableHorizontal()); EXPECT_TRUE(scroll->UserScrollableVertical()); EXPECT_EQ(gfx::Vector2dF(120, 340), @@ -397,7 +397,7 @@ EXPECT_EQ(scroll, scroll_translation->ScrollNode()); // 10: border width. 85: container client size (== 100 - scrollbar width). EXPECT_EQ(gfx::Rect(10, 10, 85, 85), scroll->ContainerRect()); - EXPECT_EQ(gfx::Size(400, 400), scroll->ContentsSize()); + EXPECT_EQ(gfx::Rect(10, 10, 400, 400), scroll->ContentsRect()); EXPECT_EQ(PhysicalOffset(), scroller->FirstFragment().PaintOffset()); EXPECT_EQ(IntPoint(315, 0), scroller->ScrollOrigin()); EXPECT_EQ(PhysicalOffset(10, 10), content->FirstFragment().PaintOffset()); @@ -416,7 +416,7 @@ // Other properties are the same as before. EXPECT_EQ(scroll, scroll_translation->ScrollNode()); EXPECT_EQ(gfx::Rect(10, 10, 85, 85), scroll->ContainerRect()); - EXPECT_EQ(gfx::Size(400, 400), scroll->ContentsSize()); + EXPECT_EQ(gfx::Rect(10, 10, 400, 400), scroll->ContentsRect()); EXPECT_EQ(PhysicalOffset(), scroller->FirstFragment().PaintOffset()); EXPECT_EQ(IntPoint(315, 0), scroller->ScrollOrigin()); EXPECT_EQ(PhysicalOffset(10, 10), content->FirstFragment().PaintOffset()); @@ -450,7 +450,7 @@ // 25: border width (10) + scrollbar (on the left) width (15). // 85: container client size (== 100 - scrollbar width). EXPECT_EQ(gfx::Rect(25, 10, 85, 85), scroll->ContainerRect()); - EXPECT_EQ(gfx::Size(400, 400), scroll->ContentsSize()); + EXPECT_EQ(gfx::Rect(25, 10, 400, 400), scroll->ContentsRect()); EXPECT_EQ(PhysicalOffset(), scroller->FirstFragment().PaintOffset()); EXPECT_EQ(IntPoint(315, 0), scroller->ScrollOrigin()); EXPECT_EQ(PhysicalOffset(25, 10), content->FirstFragment().PaintOffset()); @@ -469,7 +469,7 @@ // Other properties are the same as before. EXPECT_EQ(scroll, scroll_translation->ScrollNode()); EXPECT_EQ(gfx::Rect(25, 10, 85, 85), scroll->ContainerRect()); - EXPECT_EQ(gfx::Size(400, 400), scroll->ContentsSize()); + EXPECT_EQ(gfx::Rect(25, 10, 400, 400), scroll->ContentsRect()); EXPECT_EQ(PhysicalOffset(), scroller->FirstFragment().PaintOffset()); EXPECT_EQ(IntPoint(315, 0), scroller->ScrollOrigin()); EXPECT_EQ(PhysicalOffset(25, 10), content->FirstFragment().PaintOffset()); @@ -3984,7 +3984,7 @@ EXPECT_EQ(gfx::Rect(0, 0, 5, 3), overflow_a_scroll_node->ContainerRect()); // 107 is the forceScroll element plus the height of the overflow scroll child // (overflowB). - EXPECT_EQ(gfx::Size(9, 107), overflow_a_scroll_node->ContentsSize()); + EXPECT_EQ(gfx::Rect(0, 0, 9, 107), overflow_a_scroll_node->ContentsRect()); EXPECT_TRUE(overflow_a_scroll_node->UserScrollableHorizontal()); EXPECT_TRUE(overflow_a_scroll_node->UserScrollableVertical()); @@ -3998,7 +3998,7 @@ EXPECT_EQ(overflow_a_scroll_node, overflow_b_scroll_node->Parent()); EXPECT_EQ(gfx::Vector2dF(0, -41), scroll_b_translation->Translation2D()); EXPECT_EQ(gfx::Rect(0, 0, 9, 7), overflow_b_scroll_node->ContainerRect()); - EXPECT_EQ(gfx::Size(9, 100), overflow_b_scroll_node->ContentsSize()); + EXPECT_EQ(gfx::Rect(0, 0, 9, 100), overflow_b_scroll_node->ContentsRect()); EXPECT_TRUE(overflow_b_scroll_node->UserScrollableHorizontal()); EXPECT_TRUE(overflow_b_scroll_node->UserScrollableVertical()); } @@ -4070,7 +4070,7 @@ // The height should be 4000px because the (dom-order) overflow children are // positioned and do not contribute to the height. Only the 4000px // "forceScroll" height is present. - EXPECT_EQ(gfx::Size(5, 4000), overflow_scroll_node->ContentsSize()); + EXPECT_EQ(gfx::Rect(0, 0, 5, 4000), overflow_scroll_node->ContentsRect()); const ObjectPaintProperties* abspos_overflow_scroll_properties = abspos_overflow->GetLayoutObject()->FirstFragment().PaintProperties(); @@ -4083,7 +4083,8 @@ EXPECT_EQ(gfx::Vector2dF(0, -41), abspos_scroll_translation->Translation2D()); EXPECT_EQ(gfx::Rect(0, 0, 9, 7), abspos_overflow_scroll_node->ContainerRect()); - EXPECT_EQ(gfx::Size(9, 4000), abspos_overflow_scroll_node->ContentsSize()); + EXPECT_EQ(gfx::Rect(0, 0, 9, 4000), + abspos_overflow_scroll_node->ContentsRect()); const ObjectPaintProperties* fixed_overflow_scroll_properties = fixed_overflow->GetLayoutObject()->FirstFragment().PaintProperties(); @@ -4096,7 +4097,8 @@ EXPECT_EQ(gfx::Vector2dF(0, -43), fixed_scroll_translation->Translation2D()); EXPECT_EQ(gfx::Rect(0, 0, 13, 11), fixed_overflow_scroll_node->ContainerRect()); - EXPECT_EQ(gfx::Size(13, 4000), fixed_overflow_scroll_node->ContentsSize()); + EXPECT_EQ(gfx::Rect(0, 0, 13, 4000), + fixed_overflow_scroll_node->ContentsRect()); } TEST_P(PaintPropertyTreeBuilderTest, NestedPositionedScrollProperties) { @@ -4152,7 +4154,7 @@ EXPECT_EQ(gfx::Rect(0, 0, 20, 20), overflow_a_scroll_node->ContainerRect()); // 100 is the forceScroll element's height because the overflow child does not // contribute to the height. - EXPECT_EQ(gfx::Size(20, 100), overflow_a_scroll_node->ContentsSize()); + EXPECT_EQ(gfx::Rect(0, 0, 20, 100), overflow_a_scroll_node->ContentsRect()); EXPECT_TRUE(overflow_a_scroll_node->UserScrollableHorizontal()); EXPECT_TRUE(overflow_a_scroll_node->UserScrollableVertical()); @@ -4166,7 +4168,7 @@ EXPECT_EQ(overflow_a_scroll_node, overflow_b_scroll_node->Parent()); EXPECT_EQ(gfx::Vector2dF(0, -41), scroll_b_translation->Translation2D()); EXPECT_EQ(gfx::Rect(0, 0, 5, 3), overflow_b_scroll_node->ContainerRect()); - EXPECT_EQ(gfx::Size(5, 100), overflow_b_scroll_node->ContentsSize()); + EXPECT_EQ(gfx::Rect(0, 0, 5, 100), overflow_b_scroll_node->ContentsRect()); EXPECT_TRUE(overflow_b_scroll_node->UserScrollableHorizontal()); EXPECT_TRUE(overflow_b_scroll_node->UserScrollableVertical()); } @@ -6147,7 +6149,7 @@ const auto* properties = PaintPropertiesForElement("scroller"); const auto* scroll_node = properties->ScrollTranslation()->ScrollNode(); EXPECT_EQ(gfx::Rect(0, 0, 200, 200), scroll_node->ContainerRect()); - EXPECT_EQ(gfx::Size(1000, 200), scroll_node->ContentsSize()); + EXPECT_EQ(gfx::Rect(0, 0, 1000, 200), scroll_node->ContentsRect()); } TEST_P(PaintPropertyTreeBuilderTest,
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_update_tests.cc b/third_party/blink/renderer/core/paint/paint_property_tree_update_tests.cc index ce64aa5..138917c 100644 --- a/third_party/blink/renderer/core/paint/paint_property_tree_update_tests.cc +++ b/third_party/blink/renderer/core/paint/paint_property_tree_update_tests.cc
@@ -793,7 +793,7 @@ ->ScrollTranslation() ->ScrollNode(); EXPECT_EQ(gfx::Rect(0, 0, 100, 100), scroll_node->ContainerRect()); - EXPECT_EQ(gfx::Size(200, 200), scroll_node->ContentsSize()); + EXPECT_EQ(gfx::Rect(0, 0, 200, 200), scroll_node->ContentsRect()); GetDocument().getElementById("content")->setAttribute( html_names::kStyleAttr, "width: 200px; height: 300px"); @@ -803,7 +803,7 @@ ->ScrollTranslation() ->ScrollNode()); EXPECT_EQ(gfx::Rect(0, 0, 100, 100), scroll_node->ContainerRect()); - EXPECT_EQ(gfx::Size(200, 300), scroll_node->ContentsSize()); + EXPECT_EQ(gfx::Rect(0, 0, 200, 300), scroll_node->ContentsRect()); } // The scrollbars are attached to the visual viewport but created by (and have @@ -825,8 +825,8 @@ EXPECT_EQ(gfx::Rect(0, 0, 800, 600), visual_viewport.GetScrollNode()->ContainerRect()); - EXPECT_EQ(gfx::Size(800, 600), - visual_viewport.GetScrollNode()->ContentsSize()); + EXPECT_EQ(gfx::Rect(0, 0, 800, 600), + visual_viewport.GetScrollNode()->ContentsRect()); } TEST_P(PaintPropertyTreeUpdateTest, ViewportAddRemoveDeviceEmulationNode) {
diff --git a/third_party/blink/renderer/core/paint/view_painter_test.cc b/third_party/blink/renderer/core/paint/view_painter_test.cc index 8c624b0..28675d1 100644 --- a/third_party/blink/renderer/core/paint/view_painter_test.cc +++ b/third_party/blink/renderer/core/paint/view_painter_test.cc
@@ -191,7 +191,7 @@ const auto& contents_transform = ToUnaliased(contents_chunk.properties.Transform()); const auto* contents_scroll = contents_transform.ScrollNode(); - EXPECT_EQ(gfx::Size(800, 2000), contents_scroll->ContentsSize()); + EXPECT_EQ(gfx::Rect(0, 0, 800, 2000), contents_scroll->ContentsRect()); EXPECT_EQ(gfx::Rect(0, 0, 800, 600), contents_scroll->ContainerRect()); const auto& contents_clip = ToUnaliased(contents_chunk.properties.Clip()); EXPECT_EQ(FloatRect(0, 0, 800, 600), contents_clip.PaintClipRect().Rect());
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc index bc24db3..9741678 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc +++ b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc
@@ -1052,7 +1052,7 @@ const cc::ScrollNode& cc_scroll) { EXPECT_TRUE(cc_scroll.scrollable); EXPECT_EQ(blink_scroll.ContainerRect().size(), cc_scroll.container_bounds); - EXPECT_EQ(blink_scroll.ContentsSize(), cc_scroll.bounds); + EXPECT_EQ(blink_scroll.ContentsRect().size(), cc_scroll.bounds); EXPECT_EQ(blink_scroll.UserScrollableHorizontal(), cc_scroll.user_scrollable_horizontal); EXPECT_EQ(blink_scroll.UserScrollableVertical(),
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.cc b/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.cc index e10cef3..e9c878f1 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.cc +++ b/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.cc
@@ -861,7 +861,7 @@ scroll_node; scroll_node = scroll_node->Parent()) { if (scroll_node->UserScrollableHorizontal() && scroll_node->ContainerRect().width() < - scroll_node->ContentsSize().width()) { + scroll_node->ContentsRect().width()) { disable_cursor_control = TouchAction::kInternalPanXScrolls; break; }
diff --git a/third_party/blink/renderer/platform/graphics/compositing/pending_layer.cc b/third_party/blink/renderer/platform/graphics/compositing/pending_layer.cc index 738e503..da48887 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/pending_layer.cc +++ b/third_party/blink/renderer/platform/graphics/compositing/pending_layer.cc
@@ -32,10 +32,8 @@ absl::optional<gfx::RectF> VisibilityLimit(const PropertyTreeState& state) { if (&state.Clip().LocalTransformSpace() == &state.Transform()) return ToGfxRectF(state.Clip().PaintClipRect().Rect()); - if (const auto* scroll = state.Transform().ScrollNode()) { - return gfx::RectF( - gfx::Rect(scroll->ContainerRect().origin(), scroll->ContentsSize())); - } + if (const auto* scroll = state.Transform().ScrollNode()) + return gfx::RectF(scroll->ContentsRect()); return absl::nullopt; }
diff --git a/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc b/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc index 14fba30..0616c41 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc +++ b/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc
@@ -588,7 +588,7 @@ compositor_node.scrollable = true; compositor_node.container_bounds = scroll_node.ContainerRect().size(); - compositor_node.bounds = scroll_node.ContentsSize(); + compositor_node.bounds = scroll_node.ContentsRect().size(); compositor_node.user_scrollable_horizontal = scroll_node.UserScrollableHorizontal(); compositor_node.user_scrollable_vertical =
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 2b24010f..6aa820c 100644 --- a/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc +++ b/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc
@@ -96,14 +96,13 @@ // We create scroll node for the root scroller even it's not scrollable. // Don't expand in the case. - if (scroll->ContainerRect().width() >= scroll->ContentsSize().width() && - scroll->ContainerRect().height() >= scroll->ContentsSize().height()) + gfx::Rect contents_rect = scroll->ContentsRect(); + if (scroll->ContainerRect().width() >= contents_rect.width() && + scroll->ContainerRect().height() >= contents_rect.height()) return kNotExpanded; // Expand the cull rect for scrolling contents for composited scrolling. rect_.Outset(LocalPixelDistanceToExpand(root_transform, scroll_translation)); - gfx::Rect contents_rect(scroll->ContainerRect().origin(), - scroll->ContentsSize()); rect_.Intersect(contents_rect); return rect_ == contents_rect ? kExpandedForWholeScrollingContents : kExpandedForPartialScrollingContents; @@ -247,9 +246,7 @@ bool expanded = false; if (last_scroll_translation_result == kExpandedForPartialScrollingContents) { DCHECK(last_transform->ScrollNode()); - expansion_bounds.emplace( - last_transform->ScrollNode()->ContainerRect().origin(), - last_transform->ScrollNode()->ContentsSize()); + expansion_bounds = last_transform->ScrollNode()->ContentsRect(); if (last_transform != &destination.Transform() || last_clip != &destination.Clip()) { // Map expansion_bounds in the same way as we did for rect_ in the last
diff --git a/third_party/blink/renderer/platform/graphics/paint/geometry_mapper.cc b/third_party/blink/renderer/platform/graphics/paint/geometry_mapper.cc index 4eed379..40b49c1 100644 --- a/third_party/blink/renderer/platform/graphics/paint/geometry_mapper.cc +++ b/third_party/blink/renderer/platform/graphics/paint/geometry_mapper.cc
@@ -37,7 +37,7 @@ // Calculate the max scroll offset and expand by that amount. The max scroll // offset is the contents size minus one viewport's worth of space (i.e. the // container rect size). - gfx::Size contents_size = node->ScrollNode()->ContentsSize(); + gfx::Size contents_size = node->ScrollNode()->ContentsRect().size(); gfx::Size container_size = node->ScrollNode()->ContainerRect().size(); rect_to_map.Rect().Expand(FloatSize(contents_size - container_size)); }
diff --git a/third_party/blink/renderer/platform/graphics/paint/scroll_paint_property_node.h b/third_party/blink/renderer/platform/graphics/paint/scroll_paint_property_node.h index 3db1585..5fc58f2 100644 --- a/third_party/blink/renderer/platform/graphics/paint/scroll_paint_property_node.h +++ b/third_party/blink/renderer/platform/graphics/paint/scroll_paint_property_node.h
@@ -132,13 +132,17 @@ } // Rect of the container area that the contents scrolls in, in the space of - // the parent of the associated transform node (ScrollTranslation). - // It doesn't include non-overlay scrollbars. Overlay scrollbars do not affect - // the rect. + // the parent of the associated transform node, i.e. PaintOffsetTranslation + // which is the parent of ScrollTranslation. It doesn't include non-overlay + // scrollbars. Overlay scrollbars do not affect the rect. const gfx::Rect& ContainerRect() const { return state_.container_rect; } - // Size of the contents that is scrolled within the container rect. - const gfx::Size& ContentsSize() const { return state_.contents_size; } + // Rect of the contents that is scrolled within the container rect, in the + // space of the associated transform node (ScrollTranslation). It has the + // same origin as ContainerRect(). + gfx::Rect ContentsRect() const { + return gfx::Rect(state_.container_rect.origin(), state_.contents_size); + } bool UserScrollableHorizontal() const { return state_.user_scrollable_horizontal;
diff --git a/third_party/blink/web_tests/fast/dom/HTMLMeterElement/meter-element-markup-expected.txt b/third_party/blink/web_tests/fast/dom/HTMLMeterElement/meter-element-markup-expected.txt index a39a6a3..1462245 100644 --- a/third_party/blink/web_tests/fast/dom/HTMLMeterElement/meter-element-markup-expected.txt +++ b/third_party/blink/web_tests/fast/dom/HTMLMeterElement/meter-element-markup-expected.txt
@@ -20,7 +20,6 @@ | pseudo="-internal-fallback" | shadow:pseudoId="-internal-fallback" | <slot> -| name="user-agent-default-slot" | " " | <meter> @@ -45,7 +44,6 @@ | pseudo="-internal-fallback" | shadow:pseudoId="-internal-fallback" | <slot> -| name="user-agent-default-slot" | " " | <meter> @@ -70,6 +68,5 @@ | pseudo="-internal-fallback" | shadow:pseudoId="-internal-fallback" | <slot> -| name="user-agent-default-slot" | " "
diff --git a/third_party/blink/web_tests/fast/forms/file/file-input-change-event-on-back-forward.html b/third_party/blink/web_tests/fast/forms/file/file-input-change-event-on-back-forward.html new file mode 100644 index 0000000..d9a1f821 --- /dev/null +++ b/third_party/blink/web_tests/fast/forms/file/file-input-change-event-on-back-forward.html
@@ -0,0 +1,52 @@ +<!DOCTYPE html> +<title>Input and change events for file inputs</title> +<link rel="author" href="mailto:masonf@chromium.org"> +<link rel="help" href="https://github.com/whatwg/html/issues/6853"> +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> +<script src="resources/file-drag-common.js"></script> + +<body onload="setTimeout(runTest, 0)"> + <input type=file oninput=onInputHandler() onchange=onChangeHandler()> + <input id="been-here" value="start"> + <form action="../../../resources/back.html" method="POST"></form> +</body> + +<script> +var seenOnInput = false; +var seenOnChange = false; +var restorationEventTest = async_test('File input restoration: should not fire input and change events'); + +function onInputHandler() { + var beenHere = document.getElementById("been-here"); + if (beenHere.value) + seenOnInput = true; +} + +function onChangeHandler() { + var beenHere = document.getElementById("been-here"); + if (beenHere.value) + seenOnChange = true; +} + +function runTest() { + var beenHere = document.getElementById('been-here'); + var fileInput = document.querySelector('input[type=file]'); + + if (beenHere.value == 'start') { + if (window.eventSender) + dragFilesOntoElement(fileInput, ['foo.txt']); + assert_equals(fileInput.value, 'C:\\fakepath\\foo.txt'); + beenHere.value = 'visited'; + var form = document.querySelector('form'); + // Submit form in a timeout to make sure that we create a new back/forward list item. + setTimeout(function() {form.submit();}, 0); + } else { + restorationEventTest.step(function() { + assert_false(seenOnInput); + assert_false(seenOnChange); + }); + restorationEventTest.done(); + } +} +</script>
diff --git a/third_party/blink/web_tests/fast/forms/file/file-truncation-crash.html b/third_party/blink/web_tests/fast/forms/file/file-truncation-crash.html index f14b6fc..b568bf4 100644 --- a/third_party/blink/web_tests/fast/forms/file/file-truncation-crash.html +++ b/third_party/blink/web_tests/fast/forms/file/file-truncation-crash.html
@@ -2,6 +2,7 @@ <script src="../../../resources/testharness.js"></script> <script src="../../../resources/testharnessreport.js"></script> <input style="letter-spacing:-89920240; word-spacing:639549764px;" type="file"> +<input style="direction: rtl; letter-spacing:-89920240; word-spacing:639549764px;" type=file> <script> test(() => {}, 'Crash test for a negative inline_size item'); </script>
diff --git a/third_party/blink/web_tests/shadow-dom/ua/meter-fallback-expected.html b/third_party/blink/web_tests/shadow-dom/ua/meter-fallback-expected.html index e73ddb0..69e09ea 100644 --- a/third_party/blink/web_tests/shadow-dom/ua/meter-fallback-expected.html +++ b/third_party/blink/web_tests/shadow-dom/ua/meter-fallback-expected.html
@@ -1,4 +1,4 @@ <!DOCTYPE html> -<meter style="-webkit-appearance: none">A<span>B</span><span>C</span></meter> +<meter style="-webkit-appearance: none">A<span>C</span></meter> <div><meter style="-webkit-appearance: none"><span>X</span></meter>
diff --git a/third_party/closure_compiler/externs/terminal_private.js b/third_party/closure_compiler/externs/terminal_private.js index d57249b6..57ac93c 100644 --- a/third_party/closure_compiler/externs/terminal_private.js +++ b/third_party/closure_compiler/externs/terminal_private.js
@@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. @@ -7,7 +7,7 @@ // NOTE: The format of types has changed. 'FooType' is now // 'chrome.terminalPrivate.FooType'. // Please run the closure compiler before committing changes. -// See https://chromium.googlesource.com/chromium/src/+/master/docs/closure_compilation.md +// See https://chromium.googlesource.com/chromium/src/+/main/docs/closure_compilation.md /** @fileoverview Externs generated from namespace: terminalPrivate */ @@ -84,10 +84,11 @@ /** * Open the Terminal tabbed window. - * @param {function(): void} callback Callback that will be called when - * complete. + * @param {{ + * url: (string|undefined) + * }=} data */ -chrome.terminalPrivate.openWindow = function(callback) {}; +chrome.terminalPrivate.openWindow = function(data) {}; /** * Open the Terminal Settings page.
diff --git a/third_party/crashpad/README.chromium b/third_party/crashpad/README.chromium index 01cd541..cb186cf 100644 --- a/third_party/crashpad/README.chromium +++ b/third_party/crashpad/README.chromium
@@ -2,7 +2,7 @@ Short Name: crashpad URL: https://crashpad.chromium.org/ Version: unknown -Revision: 413dedd90fbefd377417d7c5947a1d11c09220ae +Revision: dd539703805b9c289f4990f42f710bd3a68c41f1 License: Apache 2.0 License File: crashpad/LICENSE Security Critical: yes
diff --git a/third_party/crashpad/crashpad/snapshot/linux/debug_rendezvous_test.cc b/third_party/crashpad/crashpad/snapshot/linux/debug_rendezvous_test.cc index c77e862..4754528e 100644 --- a/third_party/crashpad/crashpad/snapshot/linux/debug_rendezvous_test.cc +++ b/third_party/crashpad/crashpad/snapshot/linux/debug_rendezvous_test.cc
@@ -162,7 +162,9 @@ ASSERT_GE(possible_mappings->Count(), 1u); std::unique_ptr<ElfImageReader> module_reader; +#if !defined(OS_ANDROID) const MemoryMap::Mapping* module_mapping = nullptr; +#endif const MemoryMap::Mapping* mapping = nullptr; while ((mapping = possible_mappings->Next())) { auto parsed_module = std::make_unique<ElfImageReader>(); @@ -172,7 +174,9 @@ parsed_module->GetDynamicArrayAddress(&dynamic_address) && dynamic_address == module.dynamic_array) { module_reader = std::move(parsed_module); +#if !defined(OS_ANDROID) module_mapping = mapping; +#endif break; } }
diff --git a/third_party/nearby/README.chromium b/third_party/nearby/README.chromium index 31867eb..da1b067 100644 --- a/third_party/nearby/README.chromium +++ b/third_party/nearby/README.chromium
@@ -1,7 +1,7 @@ Name: Nearby Connections Library Short Name: Nearby URL: https://github.com/google/nearby-connections -Version: dceb1e216bdd22daf37f71026db3d93124841cd4 +Version: 51a19d24c1644cccdf33d56a48db4dad3e418447 License: Apache 2.0 License File: LICENSE Security Critical: yes
diff --git a/third_party/wayland-protocols/unstable/remote-shell/remote-shell-unstable-v2.xml b/third_party/wayland-protocols/unstable/remote-shell/remote-shell-unstable-v2.xml index 622ebea..bcf1afb5 100644 --- a/third_party/wayland-protocols/unstable/remote-shell/remote-shell-unstable-v2.xml +++ b/third_party/wayland-protocols/unstable/remote-shell/remote-shell-unstable-v2.xml
@@ -38,7 +38,7 @@ reset. </description> - <interface name="zcr_remote_shell_v2" version="1"> + <interface name="zcr_remote_shell_v2" version="2"> <description summary="remote_shell"> The global interface that allows clients to turn a wl_surface into a "real window" which is remotely managed but can be stacked, activated @@ -162,7 +162,7 @@ </interface> - <interface name="zcr_remote_surface_v2" version="1"> + <interface name="zcr_remote_surface_v2" version="2"> <description summary="A desktop window"> An interface that may be implemented by a wl_surface, for implementations that provide a desktop-style user interface @@ -736,7 +736,7 @@ <request name="set_resize_lock" since="1"> <description summary="set resize lock state"> - Enable the resize lock and put restrictions related to resizing on + [Deprecated] Enable the resize lock and put restrictions related to resizing on the shell surface. The resize lock state is double buffered, and will be applied at the @@ -746,7 +746,7 @@ <request name="unset_resize_lock" since="1"> <description summary="unset resize lock state"> - Disable the resize lock and allow the shell surface to be resized + [Deprecated] Disable the resize lock and allow the shell surface to be resized freely. The resize lock state is double buffered, and will be applied at the @@ -806,6 +806,28 @@ <arg name="width" type="int"/> <arg name="height" type="int"/> </request> + + <!-- Version 2 additions --> + + <enum name="resize_lock_type"> + <description summary="resize lock type"> + Resize lock type that can be used to put restrictions related to resizing. + </description> + <entry name="none" value="0" summary="follows normal resizeable policies"/> + <entry name="resize_enabled_togglable" value="1" summary="resizing is enabled and resize lock type is togglable" /> + <entry name="resize_disabled_togglable" value="2" summary="resizing is disabled and resize lock type is togglable" /> + <entry name="resize_disalbed_nontoggleable" value="3" summary="resizing is disabled and resize lock type is not togglable"/> + </enum> + + <request name="set_resize_lock_type" since="2"> + <description summary="set resize lock type"> + Set resize lock type and put restrictions related to resizing on the shell surface. + + The resize lock type is double buffered, and will be applied at the + time wl_surface.commit of the corresponding wl_surface is called. + </description> + <arg name="type" type="uint" enum="resize_lock_type" summary="resize lock type"/> + </request> </interface> <interface name="zcr_notification_surface_v2" version="1">
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index 359dc35..2d9ab11 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -450,8 +450,8 @@ 'Chromium Android ARM 32-bit Goma RBE ToT (ATS)': 'android_release_bot_minimal_symbols', 'Chromium Android ARM 32-bit Goma RBE Staging': 'android_release_bot_minimal_symbols', - 'chromeos-amd64-generic-rel-goma-rbe-tot': 'chromeos_amd64-generic', - 'chromeos-amd64-generic-rel-goma-rbe-staging': 'chromeos_amd64-generic', + 'chromeos-amd64-generic-rel-goma-rbe-tot': 'chromeos_amd64-generic_use_fake_dbus_clients_vm_optimized', + 'chromeos-amd64-generic-rel-goma-rbe-staging': 'chromeos_amd64-generic_use_fake_dbus_clients_vm_optimized', }, 'chromium.gpu': { @@ -945,7 +945,7 @@ # and two kevin bots when the PFQ has it enabled. 'chromeos-amd64-generic-cfi-thin-lto-rel': 'chromeos_amd64-generic_cfi_thin_lto', 'chromeos-amd64-generic-dbg': 'chromeos_amd64-generic_dbg', - 'chromeos-amd64-generic-rel': 'chromeos_amd64-generic_use_fake_dbus_clients_vm_optimized', + 'chromeos-amd64-generic-rel': 'chromeos_amd64-generic_use_fake_dbus_clients_vm_optimized_dchecks', 'chromeos-amd64-generic-rel-dchecks': 'chromeos_amd64-generic_use_fake_dbus_clients_vm_optimized_dchecks', 'chromeos-amd64-generic-rel-rts': 'chromeos_amd64-generic_use_fake_dbus_clients', 'chromeos-arm-generic-dbg': 'chromeos_arm-generic_dbg', @@ -1817,10 +1817,6 @@ 'cfi_full', 'cfi_icall', 'cfi_diag', 'thin_lto', 'release', 'static', 'dcheck_always_on', 'goma', ], - 'chromeos_amd64-generic': [ - 'chromeos_amd64-generic', - ], - 'chromeos_amd64-generic_asan': [ 'chromeos_amd64-generic', 'asan', ],
diff --git a/tools/mb/mb_config_expectations/chromium.goma.json b/tools/mb/mb_config_expectations/chromium.goma.json index 988acdc..28418f2 100644 --- a/tools/mb/mb_config_expectations/chromium.goma.json +++ b/tools/mb/mb_config_expectations/chromium.goma.json
@@ -194,21 +194,23 @@ } }, "chromeos-amd64-generic-rel-goma-rbe-staging": { - "args_file": "//build/args/chromeos/amd64-generic.gni", + "args_file": "//build/args/chromeos/amd64-generic-vm.gni", "gn_args": { "dcheck_always_on": false, "is_chromeos_device": true, "ozone_platform_headless": true, - "use_goma": true + "use_goma": true, + "use_real_dbus_clients": false } }, "chromeos-amd64-generic-rel-goma-rbe-tot": { - "args_file": "//build/args/chromeos/amd64-generic.gni", + "args_file": "//build/args/chromeos/amd64-generic-vm.gni", "gn_args": { "dcheck_always_on": false, "is_chromeos_device": true, "ozone_platform_headless": true, - "use_goma": true + "use_goma": true, + "use_real_dbus_clients": false } } } \ No newline at end of file
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.chromiumos.json b/tools/mb/mb_config_expectations/tryserver.chromium.chromiumos.json index 32cd214..e8b3b8c 100644 --- a/tools/mb/mb_config_expectations/tryserver.chromium.chromiumos.json +++ b/tools/mb/mb_config_expectations/tryserver.chromium.chromiumos.json
@@ -24,7 +24,7 @@ "chromeos-amd64-generic-rel": { "args_file": "//build/args/chromeos/amd64-generic-vm.gni", "gn_args": { - "dcheck_always_on": false, + "dcheck_always_on": true, "is_chromeos_device": true, "ozone_platform_headless": true, "use_goma": true,
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 5b351aa..0ca17d5f 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -3846,6 +3846,17 @@ </int> </enum> +<enum name="ArcImageCopyPasteCompatOperationType"> + <summary> + Defines the combinations of operation types (copy-paste and drag-drop) and + sources (from browser and Files app) for ARC image copy-paste app compat. + </summary> + <int value="0" label="An image pasted from FilesApp"/> + <int value="1" label="An image dragged from FilesApp"/> + <int value="2" label="An image pasted from browser"/> + <int value="3" label="An image dragged from browser"/> +</enum> + <enum name="ArcIntentHandlerAction"> <summary>Defines Arc intent handler actions</summary> <int value="0" label="Error after showing picker"/> @@ -6953,6 +6964,12 @@ <int value="3" label="[Deprecated] AUTO_LAUNCH_FOREGROUND_USELESS"/> </enum> +<enum name="AutomaticLazyLoadFrameState"> + <int value="0" label="Feature is not enabled"/> + <int value="1" label="Target frames not found"/> + <int value="2" label="Target frames found"/> +</enum> + <enum name="AutoplayBlockedReason"> <int value="0" label="[Deprecated] Data Saver enabled"/> <int value="1" label="Disabled by setting"/> @@ -11398,6 +11415,7 @@ <int value="3" label="User selected the Tab Scrolling lab"/> <int value="4" label="User selected the Side Panel lab"/> <int value="5" label="User selected the Lens Region Search lab"/> + <int value="6" label="User selected the WebUI Tab Strip lab"/> </enum> <enum name="ChromeMLServiceDecisionTreePredictionResult"> @@ -19291,6 +19309,7 @@ <int value="7" label="kDebugSubframeProxyCreationWithNoRVH"/> <int value="8" label="kDebugBackForwardCacheEntryExistsOnSubframeHistoryNav"/> <int value="9" label="kDebugNoRenderFrameProxyHostOnSetFocusedFrame"/> + <int value="10" label="kDebugNoRestoredRFHOnNonRestartedNavigation"/> </enum> <enum name="DeclarativeAPIFunctionType">
diff --git a/tools/metrics/histograms/metadata/arc/histograms.xml b/tools/metrics/histograms/metadata/arc/histograms.xml index 201ccfb4..0e29700 100644 --- a/tools/metrics/histograms/metadata/arc/histograms.xml +++ b/tools/metrics/histograms/metadata/arc/histograms.xml
@@ -913,6 +913,24 @@ </summary> </histogram> +<histogram name="Arc.ImageCopyPasteCompatOperationType" + enum="ArcImageCopyPasteCompatOperationType" expires_after="2022-04-01"> + <owner>tetsui@chromium.org</owner> + <owner>yhanada@chromium.org</owner> + <summary> + The operation type (copy-paste or drag-drop) and the source of the image + (from browser or Files app), counted when image copy-paste app compat is + triggered. Image copy-paste app compat is a feature that allows insertion of + images to Android apps through commitContent IME API or Android intent, when + the app don't support images in the clipboard. For example, when a user + pastes an image from Files app to an Android app and the app compat logic + succeeds to insert the image, then that is one histogram count. If it fails + (for example the app does not implement commitContent API) or the app + already supports image pasting from the clipboard and the app compat logic + is not used, that will not be counted. + </summary> +</histogram> + <histogram name="Arc.ImeCount" units="units" expires_after="2022-04-01"> <owner>yhanada@chromium.org</owner> <owner>tetsui@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/blink/histograms.xml b/tools/metrics/histograms/metadata/blink/histograms.xml index 237cc34..e59bbb14 100644 --- a/tools/metrics/histograms/metadata/blink/histograms.xml +++ b/tools/metrics/histograms/metadata/blink/histograms.xml
@@ -99,6 +99,22 @@ </summary> </histogram> +<histogram name="Blink.AutomaticLazyLoadFrame" + enum="AutomaticLazyLoadFrameState" expires_after="2022-04-09"> + <owner>sisidovski@google.com</owner> + <owner>kouhei@chromium.org</owner> + <summary> + Records if the automatic lazy-load for selected performance problematic + iframes is applied or not. This is recorded when each frame having a url in + the page is created. See HTMLFrameOwnerElement::LazyLoadIfPossible() for + more details. + + Note: There are two groups that lazy-load isn't applied. One group is simply + the feature itself is disabled, another groupd is that feature is enabled, + but there are no targeted frames on the page. + </summary> +</histogram> + <histogram name="Blink.Canvas.2DPrintingAsVector" enum="BooleanSuccess" expires_after="2022-01-31"> <owner>fserb@chromium.org</owner>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index 563ac4c..7cb7a7cc 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -6,11 +6,11 @@ }, "win": { "hash": "52f421824816597171d49ad99769576b6eb8c1e8", - "remote_path": "perfetto_binaries/trace_processor_shell/win/a24cded09fce516821605181a032190110db2fd7/trace_processor_shell.exe" + "remote_path": "perfetto_binaries/trace_processor_shell/win/a380238d9c232c8be236d141d0c81ca358a2597e/trace_processor_shell.exe" }, "mac": { "hash": "c23e575ca7971342be4b254789513a3d9e75e19f", - "remote_path": "perfetto_binaries/trace_processor_shell/mac/a24cded09fce516821605181a032190110db2fd7/trace_processor_shell" + "remote_path": "perfetto_binaries/trace_processor_shell/mac/a380238d9c232c8be236d141d0c81ca358a2597e/trace_processor_shell" }, "linux_arm64": { "hash": "5074025a2898ec41a872e70a5719e417acb0a380",
diff --git a/ui/base/models/dialog_model.cc b/ui/base/models/dialog_model.cc index 762a113..0404ac5 100644 --- a/ui/base/models/dialog_model.cc +++ b/ui/base/models/dialog_model.cc
@@ -28,8 +28,8 @@ base::OnceClosure callback, std::u16string label, const DialogModelButton::Params& params) { - DCHECK(!model_->accept_callback_); - model_->accept_callback_ = std::move(callback); + DCHECK(!model_->accept_action_callback_); + model_->accept_action_callback_ = std::move(callback); // NOTREACHED() is used below to make sure this callback isn't used. // DialogModelHost should be using OnDialogAccepted() instead. model_->ok_button_.emplace( @@ -44,8 +44,8 @@ base::OnceClosure callback, std::u16string label, const DialogModelButton::Params& params) { - DCHECK(!model_->cancel_callback_); - model_->cancel_callback_ = std::move(callback); + DCHECK(!model_->cancel_action_callback_); + model_->cancel_action_callback_ = std::move(callback); // NOTREACHED() is used below to make sure this callback isn't used. // DialogModelHost should be using OnDialogCanceled() instead. model_->cancel_button_.emplace( @@ -136,24 +136,24 @@ return GetFieldByUniqueId(unique_id)->AsTextfield(); } -void DialogModel::OnDialogAccepted(base::PassKey<DialogModelHost>) { - if (accept_callback_) - std::move(accept_callback_).Run(); +void DialogModel::OnDialogAcceptAction(base::PassKey<DialogModelHost>) { + if (accept_action_callback_) + std::move(accept_action_callback_).Run(); } -void DialogModel::OnDialogCancelled(base::PassKey<DialogModelHost>) { - if (cancel_callback_) - std::move(cancel_callback_).Run(); +void DialogModel::OnDialogCancelAction(base::PassKey<DialogModelHost>) { + if (cancel_action_callback_) + std::move(cancel_action_callback_).Run(); } -void DialogModel::OnDialogClosed(base::PassKey<DialogModelHost>) { - if (close_callback_) - std::move(close_callback_).Run(); +void DialogModel::OnDialogCloseAction(base::PassKey<DialogModelHost>) { + if (close_action_callback_) + std::move(close_action_callback_).Run(); } -void DialogModel::OnWindowClosing(base::PassKey<DialogModelHost>) { - if (window_closing_callback_) - std::move(window_closing_callback_).Run(); +void DialogModel::OnDialogDestroying(base::PassKey<DialogModelHost>) { + if (dialog_destroying_callback_) + std::move(dialog_destroying_callback_).Run(); } void DialogModel::AddField(std::unique_ptr<DialogModelField> field) {
diff --git a/ui/base/models/dialog_model.h b/ui/base/models/dialog_model.h index c2a6c90..8a8a7fd 100644 --- a/ui/base/models/dialog_model.h +++ b/ui/base/models/dialog_model.h
@@ -151,17 +151,20 @@ // Called when the dialog is explicitly closed (Esc, close-x). Not called // during accept/cancel. - Builder& SetCloseCallback(base::OnceClosure callback) { - model_->close_callback_ = std::move(callback); + Builder& SetCloseActionCallback(base::OnceClosure callback) { + model_->close_action_callback_ = std::move(callback); return *this; } // TODO(pbos): Clarify and enforce (through tests) that this is called after // {accept,cancel,close} callbacks. - // Unconditionally called when the dialog closes. Called on top of - // {accept,cancel,close} callbacks. - Builder& SetWindowClosingCallback(base::OnceClosure callback) { - model_->window_closing_callback_ = std::move(callback); + // Unconditionally called when the dialog destroys. Happens after + // user-action callbacks (accept, cancel, close), or as a result of dialog + // destruction. The latter can happen without a user action, for instance as + // a result of the OS destroying a native Widget in which this dialog is + // hosted. + Builder& SetDialogDestroyingCallback(base::OnceClosure callback) { + model_->dialog_destroying_callback_ = std::move(callback); return *this; } @@ -278,10 +281,11 @@ // Methods with base::PassKey<DialogModelHost> are only intended to be called // by the DialogModelHost implementation. - void OnDialogAccepted(base::PassKey<DialogModelHost>); - void OnDialogCancelled(base::PassKey<DialogModelHost>); - void OnDialogClosed(base::PassKey<DialogModelHost>); - void OnWindowClosing(base::PassKey<DialogModelHost>); + void OnDialogAcceptAction(base::PassKey<DialogModelHost>); + void OnDialogCancelAction(base::PassKey<DialogModelHost>); + void OnDialogCloseAction(base::PassKey<DialogModelHost>); + + void OnDialogDestroying(base::PassKey<DialogModelHost>); // Called when added to a DialogModelHost. void set_host(base::PassKey<DialogModelHost>, DialogModelHost* host) { @@ -360,11 +364,11 @@ absl::optional<DialogModelButton> cancel_button_; absl::optional<DialogModelButton> extra_button_; - base::OnceClosure accept_callback_; - base::OnceClosure cancel_callback_; - base::OnceClosure close_callback_; + base::OnceClosure accept_action_callback_; + base::OnceClosure cancel_action_callback_; + base::OnceClosure close_action_callback_; - base::OnceClosure window_closing_callback_; + base::OnceClosure dialog_destroying_callback_; }; } // namespace ui
diff --git a/ui/base/models/dialog_model_unittest.cc b/ui/base/models/dialog_model_unittest.cc index 4db911f..95625e48 100644 --- a/ui/base/models/dialog_model_unittest.cc +++ b/ui/base/models/dialog_model_unittest.cc
@@ -126,7 +126,7 @@ switch (button_id) { case kCancelButton: button = model->cancel_button(TestDialogModelHost::GetPassKey()); - model->OnDialogCancelled(TestDialogModelHost::GetPassKey()); + model->OnDialogCancelAction(TestDialogModelHost::GetPassKey()); break; case kExtraButton: button = model->extra_button(TestDialogModelHost::GetPassKey()); @@ -135,7 +135,7 @@ break; case kOkButton: button = model->ok_button(TestDialogModelHost::GetPassKey()); - model->OnDialogAccepted(TestDialogModelHost::GetPassKey()); + model->OnDialogAcceptAction(TestDialogModelHost::GetPassKey()); break; } ASSERT_TRUE(button);
diff --git a/ui/ozone/common/features.cc b/ui/ozone/common/features.cc index c2279f9..c4bd2ec 100644 --- a/ui/ozone/common/features.cc +++ b/ui/ozone/common/features.cc
@@ -17,12 +17,25 @@ #endif }; +// This feature flag enables a mode where the wayland client would submit +// buffers at a scale of 1 and the server applies the respective scale transform +// to properly composite the buffers. This mode is used to support fractional +// scale factor. +const base::Feature kWaylandSurfaceSubmissionInPixelCoordinates{ + "WaylandSurfaceSubmissionInPixelCoordinates", + base::FEATURE_DISABLED_BY_DEFAULT}; + // This feature flag is used for fractional display scale factor development for // LaCros. When enabled, the wayland client would use the xdg output protocol to // receive extra output metrics (logical size) to calculate the scale factor. const base::Feature kXdgOutputProtocolSupport{ "XdgOutputProtocolSupport", base::FEATURE_DISABLED_BY_DEFAULT}; +bool IsWaylandSurfaceSubmissionInPixelCoordinatesEnabled() { + return base::FeatureList::IsEnabled( + kWaylandSurfaceSubmissionInPixelCoordinates); +} + bool IsWaylandOverlayDelegationEnabled() { return base::FeatureList::IsEnabled(kWaylandOverlayDelegation); }
diff --git a/ui/ozone/common/features.h b/ui/ozone/common/features.h index 2c1034d08..fe969af 100644 --- a/ui/ozone/common/features.h +++ b/ui/ozone/common/features.h
@@ -9,9 +9,11 @@ namespace ui { +extern const base::Feature kWaylandSurfaceSubmissionInPixelCoordinates; extern const base::Feature kWaylandOverlayDelegation; extern const base::Feature kXdgOutputProtocolSupport; +bool IsWaylandSurfaceSubmissionInPixelCoordinatesEnabled(); bool IsWaylandOverlayDelegationEnabled(); bool IsXdgOutputProtocolSupportEnabled();
diff --git a/ui/ozone/platform/wayland/host/wayland_connection.cc b/ui/ozone/platform/wayland/host/wayland_connection.cc index cd00153e..b1e946e 100644 --- a/ui/ozone/platform/wayland/host/wayland_connection.cc +++ b/ui/ozone/platform/wayland/host/wayland_connection.cc
@@ -156,6 +156,9 @@ } #endif + surface_submission_in_pixel_coordinates_ = + IsWaylandSurfaceSubmissionInPixelCoordinatesEnabled(); + // Register factories for classes that implement wl::GlobalObjectRegistrar<T>. // Keep alphabetical order for convenience. RegisterGlobalObjectFactory(GtkPrimarySelectionDeviceManager::kInterfaceName,
diff --git a/ui/ozone/platform/wayland/host/wayland_connection.h b/ui/ozone/platform/wayland/host/wayland_connection.h index 32d3aa9..f619fb1 100644 --- a/ui/ozone/platform/wayland/host/wayland_connection.h +++ b/ui/ozone/platform/wayland/host/wayland_connection.h
@@ -270,6 +270,9 @@ return available_globals_; } + bool surface_submission_in_pixel_coordinates() const { + return surface_submission_in_pixel_coordinates_; + } wl::SerialTracker& serial_tracker() { return serial_tracker_; } private: @@ -417,6 +420,12 @@ bool scheduled_flush_ = false; + // Surfaces are submitted in pixel coordinates. Their buffer scales are always + // advertised to server as 1, and the scale via vp_viewporter won't be + // applied. The server will be responsible to scale the buffers to the right + // sizes. + bool surface_submission_in_pixel_coordinates_ = false; + wl::SerialTracker serial_tracker_; // Global Wayland interfaces available in the current session, with their
diff --git a/ui/ozone/platform/wayland/host/wayland_event_source.cc b/ui/ozone/platform/wayland/host/wayland_event_source.cc index 476c1ca0..4a24049 100644 --- a/ui/ozone/platform/wayland/host/wayland_event_source.cc +++ b/ui/ozone/platform/wayland/host/wayland_event_source.cc
@@ -162,12 +162,15 @@ pointer_location_ = location; bool focused = !!window; - if (focused) + if (focused) { + if (SurfaceSubmissionInPixelCoordinates()) + pointer_location_.Scale(1.0f / window->window_scale()); window_manager_->SetPointerFocusedWindow(window); + } EventType type = focused ? ET_MOUSE_ENTERED : ET_MOUSE_EXITED; - MouseEvent event(type, location, location, EventTimeForNow(), pointer_flags_, - 0); + MouseEvent event(type, pointer_location_, pointer_location_, + EventTimeForNow(), pointer_flags_, 0); DispatchEvent(&event); if (!focused) @@ -201,6 +204,13 @@ void WaylandEventSource::OnPointerMotionEvent(const gfx::PointF& location) { pointer_location_ = location; + + if (SurfaceSubmissionInPixelCoordinates()) { + if (WaylandWindow* window = + window_manager_->GetCurrentPointerFocusedWindow()) + pointer_location_.Scale(1.0f / window->window_scale()); + } + int flags = pointer_flags_ | keyboard_modifiers_; MouseEvent event(ET_MOUSE_MOVED, pointer_location_, pointer_location_, EventTimeForNow(), flags, 0); @@ -299,16 +309,20 @@ DCHECK(window); HandleTouchFocusChange(window, true); + gfx::PointF loc = + SurfaceSubmissionInPixelCoordinates() + ? gfx::ScalePoint(location, 1.f / window->window_scale()) + : location; // Make sure this touch point wasn't present before. - auto success = touch_points_.try_emplace( - id, std::make_unique<TouchPoint>(location, window)); + auto success = + touch_points_.try_emplace(id, std::make_unique<TouchPoint>(loc, window)); if (!success.second) { LOG(WARNING) << "Touch down fired with wrong id"; return; } PointerDetails details(EventPointerType::kTouch, id); - TouchEvent event(ET_TOUCH_PRESSED, location, location, timestamp, details); + TouchEvent event(ET_TOUCH_PRESSED, loc, loc, timestamp, details); DispatchEvent(&event); } @@ -341,9 +355,14 @@ LOG(WARNING) << "Touch event fired with wrong id"; return; } - it->second->last_known_location = location; + + gfx::PointF loc = + SurfaceSubmissionInPixelCoordinates() + ? gfx::ScalePoint(location, 1.f / it->second->window->window_scale()) + : location; + it->second->last_known_location = loc; PointerDetails details(EventPointerType::kTouch, id); - TouchEvent event(ET_TOUCH_MOVED, location, location, timestamp, details); + TouchEvent event(ET_TOUCH_MOVED, loc, loc, timestamp, details); DispatchEvent(&event); } @@ -502,4 +521,8 @@ : gfx::Vector2dF(dx * dt_inv, dy * dt_inv); } +bool WaylandEventSource::SurfaceSubmissionInPixelCoordinates() const { + return connection_->surface_submission_in_pixel_coordinates(); +} + } // namespace ui
diff --git a/ui/ozone/platform/wayland/host/wayland_event_source.h b/ui/ozone/platform/wayland/host/wayland_event_source.h index da7fade7..32e85251 100644 --- a/ui/ozone/platform/wayland/host/wayland_event_source.h +++ b/ui/ozone/platform/wayland/host/wayland_event_source.h
@@ -170,6 +170,7 @@ // Computes initial velocity of fling scroll based on recent frames. gfx::Vector2dF ComputeFlingVelocity(); + bool SurfaceSubmissionInPixelCoordinates() const; WaylandWindowManager* const window_manager_; WaylandConnection* const connection_;
diff --git a/ui/ozone/platform/wayland/host/wayland_surface.cc b/ui/ozone/platform/wayland/host/wayland_surface.cc index d6928fc..ad11597 100644 --- a/ui/ozone/platform/wayland/host/wayland_surface.cc +++ b/ui/ozone/platform/wayland/host/wayland_surface.cc
@@ -273,8 +273,10 @@ void WaylandSurface::SetSurfaceBufferScale(int32_t scale) { DCHECK_GE(scale, 1); - wl_surface_set_buffer_scale(surface_.get(), scale); - buffer_scale_ = scale; + if (!SurfaceSubmissionInPixelCoordinates()) { + wl_surface_set_buffer_scale(surface_.get(), scale); + buffer_scale_ = scale; + } connection_->ScheduleFlush(); } @@ -315,6 +317,8 @@ auto window_shape_in_dips = root_window_->GetWindowShape(); + bool surface_submission_in_pixel_coordinates = + SurfaceSubmissionInPixelCoordinates(); // Only root_surface and primary_subsurface should use |window_shape_in_dips|. // Do not use non empty |window_shape_in_dips| if |region_px| is empty, i.e. // this surface is transluscent. @@ -326,15 +330,23 @@ std::all_of(region_px.begin(), region_px.end(), [](const gfx::Rect& rect) { return rect.IsEmpty(); }); if (window_shape_in_dips.has_value() && !is_empty && is_primary_or_root) { - for (const auto& rect : window_shape_in_dips.value()) + for (auto& rect : window_shape_in_dips.value()) { + if (surface_submission_in_pixel_coordinates) + rect = gfx::ScaleToEnclosingRect(rect, root_window_->window_scale()); wl_region_add(region.get(), rect.x(), rect.y(), rect.width(), rect.height()); + } } else { - for (const auto& rect : region_px) { - gfx::Rect region_dip = - gfx::ScaleToEnclosingRect(rect, 1.f / root_window_->window_scale()); - wl_region_add(region.get(), region_dip.x(), region_dip.y(), - region_dip.width(), region_dip.height()); + for (const auto& rect_px : region_px) { + if (surface_submission_in_pixel_coordinates) { + wl_region_add(region.get(), rect_px.x(), rect_px.y(), rect_px.width(), + rect_px.height()); + } else { + gfx::Rect rect = gfx::ScaleToEnclosingRect( + rect_px, 1.f / root_window_->window_scale()); + wl_region_add(region.get(), rect.x(), rect.y(), rect.width(), + rect.height()); + } } } return region; @@ -486,6 +498,10 @@ } } +bool WaylandSurface::SurfaceSubmissionInPixelCoordinates() const { + return connection_->surface_submission_in_pixel_coordinates(); +} + // static void WaylandSurface::FencedRelease( void* data,
diff --git a/ui/ozone/platform/wayland/host/wayland_surface.h b/ui/ozone/platform/wayland/host/wayland_surface.h index 5da93a8..f0bb6242 100644 --- a/ui/ozone/platform/wayland/host/wayland_surface.h +++ b/ui/ozone/platform/wayland/host/wayland_surface.h
@@ -170,6 +170,7 @@ wl::Object<wl_region> CreateAndAddRegion( const std::vector<gfx::Rect>& region_px); + bool SurfaceSubmissionInPixelCoordinates() const; // Creates (if not created) the synchronization surface and returns a pointer // to it. zwp_linux_surface_synchronization_v1* GetSurfaceSync();
diff --git a/ui/ozone/platform/wayland/host/wayland_zaura_shell.cc b/ui/ozone/platform/wayland/host/wayland_zaura_shell.cc index a9e72376..778b1f5 100644 --- a/ui/ozone/platform/wayland/host/wayland_zaura_shell.cc +++ b/ui/ozone/platform/wayland/host/wayland_zaura_shell.cc
@@ -18,7 +18,7 @@ namespace ui { namespace { -constexpr uint32_t kMaxAuraShellVersion = 24; +constexpr uint32_t kMaxAuraShellVersion = 26; } // static @@ -46,11 +46,6 @@ ReportShellUMA(UMALinuxWaylandShell::kZauraShell); } -void OnActivated(void* data, - struct zaura_shell* zaura_shell, - wl_surface* x, - wl_surface* y) {} - WaylandZAuraShell::WaylandZAuraShell(zaura_shell* aura_shell, WaylandConnection* connection) : obj_(aura_shell), connection_(connection) { @@ -62,6 +57,8 @@ &OnActivated, }; zaura_shell_add_listener(obj_.get(), &zaura_shell_listener, this); + if (connection->surface_submission_in_pixel_coordinates()) + zaura_shell_surface_submission_in_pixel_coordinates(obj_.get()); } WaylandZAuraShell::~WaylandZAuraShell() = default; @@ -134,4 +131,9 @@ self->active_desk_index_ = active_desk_index; } +// static +void WaylandZAuraShell::OnActivated(void* data, + struct zaura_shell* zaura_shell, + wl_surface* gained_active, + wl_surface* lost_active) {} } // namespace ui
diff --git a/ui/ozone/platform/wayland/host/wayland_zaura_shell.h b/ui/ozone/platform/wayland/host/wayland_zaura_shell.h index 19144508..56b7e9c4 100644 --- a/ui/ozone/platform/wayland/host/wayland_zaura_shell.h +++ b/ui/ozone/platform/wayland/host/wayland_zaura_shell.h
@@ -52,6 +52,10 @@ static void OnDeskActivationChanged(void* data, struct zaura_shell* zaura_shell, int active_desk_index); + static void OnActivated(void* data, + struct zaura_shell* zaura_shell, + struct wl_surface* gained_active, + struct wl_surface* lost_active); wl::Object<zaura_shell> obj_; WaylandConnection* const connection_;
diff --git a/ui/views/bubble/bubble_dialog_model_host.cc b/ui/views/bubble/bubble_dialog_model_host.cc index 5a245987..8b45d0a 100644 --- a/ui/views/bubble/bubble_dialog_model_host.cc +++ b/ui/views/bubble/bubble_dialog_model_host.cc
@@ -199,13 +199,13 @@ // Dialog callbacks can safely refer to |model_|, they can't be called after // Widget::Close() calls WidgetWillClose() synchronously so there shouldn't // be any dangling references after model removal. - SetAcceptCallback(base::BindOnce(&ui::DialogModel::OnDialogAccepted, + SetAcceptCallback(base::BindOnce(&ui::DialogModel::OnDialogAcceptAction, base::Unretained(model_.get()), GetPassKey())); - SetCancelCallback(base::BindOnce(&ui::DialogModel::OnDialogCancelled, + SetCancelCallback(base::BindOnce(&ui::DialogModel::OnDialogCancelAction, base::Unretained(model_.get()), GetPassKey())); - SetCloseCallback(base::BindOnce(&ui::DialogModel::OnDialogClosed, + SetCloseCallback(base::BindOnce(&ui::DialogModel::OnDialogCloseAction, base::Unretained(model_.get()), GetPassKey())); @@ -335,7 +335,7 @@ // Notify the model of window closing before destroying it (as if // Widget::Close) - model_->OnWindowClosing(GetPassKey()); + model_->OnDialogDestroying(GetPassKey()); // TODO(pbos): Consider turning this into for-each-field remove field. // TODO(pbos): Move this into a better-named call inside contents_view_ to @@ -428,7 +428,8 @@ // ::Close() stack. if (!model_) return; - model_->OnWindowClosing(GetPassKey()); + model_->OnDialogDestroying(GetPassKey()); + // TODO(pbos): Do we need to reset `model_` and destroy contents? See Close(). } void BubbleDialogModelHost::AddOrUpdateBodyText(
diff --git a/ui/views/bubble/bubble_dialog_model_host_unittest.cc b/ui/views/bubble/bubble_dialog_model_host_unittest.cc index 419242e..e7b1173 100644 --- a/ui/views/bubble/bubble_dialog_model_host_unittest.cc +++ b/ui/views/bubble/bubble_dialog_model_host_unittest.cc
@@ -42,7 +42,7 @@ int window_closing_count = 0; auto host = std::make_unique<BubbleDialogModelHost>( ui::DialogModel::Builder(std::move(delegate)) - .SetWindowClosingCallback(base::BindOnce(base::BindOnce( + .SetDialogDestroyingCallback(base::BindOnce(base::BindOnce( [](int* window_closing_count) { ++(*window_closing_count); }, &window_closing_count))) .Build(),