diff --git a/DEPS b/DEPS index 734c5bf..a1419f9 100644 --- a/DEPS +++ b/DEPS
@@ -289,11 +289,11 @@ # 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': 'db33e71a9c34633b16460cc63c3bd80ac865f164', + 'v8_revision': '8a767c9c45cd7093d85056290c9b422394e7ad5b', # 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': '84122b1d94c3828ad4d7d6a46b65cecd71b5a507', + 'angle_revision': 'd6d7e551cb185c310a2a200ed9b3bcfd27653051', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -336,7 +336,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling freetype # and whatever else without interference from each other. - 'freetype_revision': '8154d8e2be329b1a0a145faae7d5fe0dd6aa7a7a', + 'freetype_revision': '9806414c15230d253d5219ea0dafeddb717307b1', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling freetype # and whatever else without interference from each other. @@ -782,7 +782,7 @@ 'src/clank': { 'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' + - '4c6a0f83d1f8ae05cf292fd3f95a6308e2548db3', + '19356589399a6f3c1161e789b8d09027dc0c1020', 'condition': 'checkout_android and checkout_src_internal', }, @@ -881,7 +881,7 @@ 'packages': [ { 'package': 'chromium/rts/model/linux-amd64', - 'version': 'q7-HK0MDlUQ5G0JVOcfIpC635OjZD32U8JNgmTSXjisC', + 'version': 'NwqsSa9DyVc5Pm679NMFs0bEH0FMLfcM_eHTYQ-3HjwC', }, ], 'dep_type': 'cipd', @@ -892,7 +892,7 @@ 'packages': [ { 'package': 'chromium/rts/model/mac-amd64', - 'version': 'n3Iyb-TkKbeWROEYJKd6pyIm3aq23m_9yhuOOt9mEToC', + 'version': 'w76jP8BrlOCe2-A-VRUqrUmNLdc8giAIl33fQuBJUtgC', }, ], 'dep_type': 'cipd', @@ -903,7 +903,7 @@ 'packages': [ { 'package': 'chromium/rts/model/windows-amd64', - 'version': 'Z66rVDOzHTiF_hKoLbLgV1oNwKrt8EaFy2zB2lw1zNUC', + 'version': 'a3zHZlT_eR9ZN3aYIJTm-N1zRSMj4DMq-sUrD5sayTwC', }, ], 'dep_type': 'cipd', @@ -1687,7 +1687,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '5437caf87b2d6711ead7eef50c762fd1114e7ef9', + Var('android_git') + '/platform/external/perfetto.git' + '@' + 'aa34142ee605c81ba5cad2b8a36bdcfd1c3c2fbf', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1962,7 +1962,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': Var('chrome_git') + '/chrome/src-internal.git@af40017478f66582691dcbca90a4557770411853', + 'url': Var('chrome_git') + '/chrome/src-internal.git@2d151942439e738fd87439117acbe0597e757d7d', 'condition': 'checkout_src_internal', }, @@ -1992,7 +1992,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/help_app/app', - 'version': 'Swwgc_G4rUTy5me9sJ6K2xMHJ3G9GwTJtYtnRHblW3EC', + 'version': 'PQZS77LjDYkFRUgKzXa2J1keoJrr_-9iu2O2ydWtS5cC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/android_webview/browser/aw_browser_process.cc b/android_webview/browser/aw_browser_process.cc index 92638a5..2cf5d45 100644 --- a/android_webview/browser/aw_browser_process.cc +++ b/android_webview/browser/aw_browser_process.cc
@@ -64,7 +64,7 @@ &AwBrowserProcess::OnLoseForeground, base::Unretained(this))); app_link_manager_ = - absl::make_unique<EnterpriseAuthenticationAppLinkManager>(local_state()); + std::make_unique<EnterpriseAuthenticationAppLinkManager>(local_state()); } AwBrowserProcess::~AwBrowserProcess() {
diff --git a/ash/app_list/views/paged_apps_grid_view.cc b/ash/app_list/views/paged_apps_grid_view.cc index ca69bb5..1ba20106 100644 --- a/ash/app_list/views/paged_apps_grid_view.cc +++ b/ash/app_list/views/paged_apps_grid_view.cc
@@ -328,8 +328,8 @@ } void PagedAppsGridView::GetAccessibleNodeData(ui::AXNodeData* node_data) { - node_data->AddBoolAttribute(ax::mojom::BoolAttribute::kClipsChildren, true); AppsGridView::GetAccessibleNodeData(node_data); + node_data->AddBoolAttribute(ax::mojom::BoolAttribute::kClipsChildren, true); } void PagedAppsGridView::OnThemeChanged() {
diff --git a/ash/app_list/views/search_result_view.cc b/ash/app_list/views/search_result_view.cc index 2367d7d..5f2e2fbff 100644 --- a/ash/app_list/views/search_result_view.cc +++ b/ash/app_list/views/search_result_view.cc
@@ -117,7 +117,8 @@ } } -ui::ColorId GetLabelColorId(bool is_title, const SearchResult::Tags& tags) { +ui::ColorId GetLabelColorId(SearchResultView::LabelType label_type, + const SearchResult::Tags& tags) { auto color_tag = SearchResult::Tag::NONE; for (const auto& tag : tags) { // Each label only supports one type of color tag. `color_tag` should only @@ -139,26 +140,77 @@ } } + const bool is_jelly_enabled = chromeos::features::IsJellyEnabled(); switch (color_tag) { case SearchResult::Tag::NONE: ABSL_FALLTHROUGH_INTENDED; case SearchResult::Tag::DIM: ABSL_FALLTHROUGH_INTENDED; case SearchResult::Tag::MATCH: - if (chromeos::features::IsJellyEnabled()) { - return is_title ? cros_tokens::kCrosSysOnSurface - : cros_tokens::kCrosSysOnSurfaceVariant; + if (is_jelly_enabled) { + switch (label_type) { + case SearchResultView::LabelType::kBigTitle: + case SearchResultView::LabelType::kBigTitleSuperscript: + case SearchResultView::LabelType::kTitle: + return cros_tokens::kCrosSysOnSurface; + case SearchResultView::LabelType::kDetails: + return cros_tokens::kCrosSysOnSurfaceVariant; + case SearchResultView::LabelType::kKeyboardShortcut: + return cros_tokens::kCrosSysPrimary; + } } - return is_title ? kColorAshTextColorPrimary : kColorAshTextColorSecondary; + return IsTitleLabel(label_type) ? kColorAshTextColorPrimary + : kColorAshTextColorSecondary; case SearchResult::Tag::URL: - return kColorAshTextColorURL; + return is_jelly_enabled + ? static_cast<ui::ColorId>(cros_tokens::kCrosSysPrimary) + : kColorAshTextColorURL; case SearchResult::Tag::GREEN: - return kColorAshTextColorPositive; + return is_jelly_enabled + ? static_cast<ui::ColorId>(cros_tokens::kCrosSysPositive) + : kColorAshTextColorPositive; case SearchResult::Tag::RED: - return kColorAshTextColorAlert; + return is_jelly_enabled + ? static_cast<ui::ColorId>(cros_tokens::kCrosSysError) + : kColorAshTextColorAlert; } } +absl::optional<TypographyToken> GetTypographyToken( + SearchResultView::LabelType label_type, + bool is_match, + bool is_inline_detail) { + if (!chromeos::features::IsJellyEnabled()) { + return absl::nullopt; + } + + if (is_match) { + return IsTitleLabel(label_type) ? TypographyToken::kCrosButton1 + : TypographyToken::kCrosBody1; + } + + switch (label_type) { + case SearchResultView::LabelType::kBigTitle: + return TypographyToken::kCrosDisplay2; + case SearchResultView::LabelType::kBigTitleSuperscript: + return TypographyToken::kCrosDisplay7; + case SearchResultView::LabelType::kTitle: + return TypographyToken::kCrosBody1; + case SearchResultView::LabelType::kDetails: + // has_keyboard_shortcut_contents forces inline title and details text + // for answer cards so title and details text should use the same + // context. + if (is_inline_detail) { + return TypographyToken::kCrosBody1; + } + ABSL_FALLTHROUGH_INTENDED; + case SearchResultView::LabelType::kKeyboardShortcut: + return TypographyToken::kCrosAnnotation1; + } + + return absl::nullopt; +} + views::ImageView* SetupChildImageView(views::FlexLayoutView* parent) { views::ImageView* image_view = parent->AddChildView(std::make_unique<views::ImageView>()); @@ -174,6 +226,7 @@ SearchResultView::SearchResultViewType view_type, SearchResultView::LabelType label_type, ui::ColorId color_id, + absl::optional<TypographyToken> typography_token, int flex_order, bool has_keyboard_shortcut_contents, bool is_multi_line, @@ -205,24 +258,25 @@ views::MaximumFlexSizeRule::kPreferred) .WithOrder(flex_order)); + if (label_type == SearchResultView::LabelType::kBigTitleSuperscript) { + // kBigTitleSuperscript labels are top-aligned to support superscripting. + label->SetVerticalAlignment(gfx::ALIGN_TOP); + } + // Apply label text styling. - if (chromeos::features::IsJellyEnabled()) { + if (typography_token.has_value()) { + TypographyProvider::Get()->StyleLabel(typography_token.value(), *label); + } else { + ash::AshTextContext text_context; switch (label_type) { case SearchResultView::LabelType::kBigTitle: - TypographyProvider::Get()->StyleLabel(TypographyToken::kCrosDisplay2, - *label); - label->SetEnabledColorId(cros_tokens::kCrosSysOnSurface); + text_context = CONTEXT_SEARCH_RESULT_BIG_TITLE; break; case SearchResultView::LabelType::kBigTitleSuperscript: - label->SetVerticalAlignment(gfx::ALIGN_TOP); - TypographyProvider::Get()->StyleLabel(TypographyToken::kCrosDisplay7, - *label); - label->SetEnabledColorId(cros_tokens::kCrosSysOnSurface); + text_context = CONTEXT_SEARCH_RESULT_BIG_TITLE_SUPERSCRIPT; break; case SearchResultView::LabelType::kTitle: - TypographyProvider::Get()->StyleLabel(TypographyToken::kCrosBody1, - *label); - label->SetEnabledColorId(cros_tokens::kCrosSysOnSurface); + text_context = CONTEXT_SEARCH_RESULT_VIEW; break; case SearchResultView::LabelType::kDetails: // has_keyboard_shortcut_contents forces inline title and details text @@ -230,52 +284,19 @@ // context. if (view_type == SearchResultView::SearchResultViewType::kAnswerCard && !has_keyboard_shortcut_contents) { - TypographyProvider::Get()->StyleLabel( - TypographyToken::kCrosAnnotation1, *label); + text_context = CONTEXT_SEARCH_RESULT_VIEW_INLINE_ANSWER_DETAILS; } else { - TypographyProvider::Get()->StyleLabel(TypographyToken::kCrosBody1, - *label); + text_context = CONTEXT_SEARCH_RESULT_VIEW; } - label->SetEnabledColorId(cros_tokens::kCrosSysOnSurfaceVariant); break; case SearchResultView::LabelType::kKeyboardShortcut: - TypographyProvider::Get()->StyleLabel(TypographyToken::kCrosAnnotation1, - *label); - label->SetEnabledColorId(cros_tokens::kCrosSysPrimary); + text_context = CONTEXT_SEARCH_RESULT_VIEW; break; } - return label; + label->SetTextContext(text_context); + label->SetTextStyle(STYLE_LAUNCHER); } - ash::AshTextContext text_context; - switch (label_type) { - case SearchResultView::LabelType::kBigTitle: - text_context = CONTEXT_SEARCH_RESULT_BIG_TITLE; - break; - case SearchResultView::LabelType::kBigTitleSuperscript: - // kBigTitleSuperscript labels are top-aligned to support superscripting. - label->SetVerticalAlignment(gfx::ALIGN_TOP); - text_context = CONTEXT_SEARCH_RESULT_BIG_TITLE_SUPERSCRIPT; - break; - case SearchResultView::LabelType::kTitle: - text_context = CONTEXT_SEARCH_RESULT_VIEW; - break; - case SearchResultView::LabelType::kDetails: - // has_keyboard_shortcut_contents forces inline title and details text for - // answer cards so title and details text should use the same context. - if (view_type == SearchResultView::SearchResultViewType::kAnswerCard && - !has_keyboard_shortcut_contents) { - text_context = CONTEXT_SEARCH_RESULT_VIEW_INLINE_ANSWER_DETAILS; - } else { - text_context = CONTEXT_SEARCH_RESULT_VIEW; - } - break; - case SearchResultView::LabelType::kKeyboardShortcut: - text_context = CONTEXT_SEARCH_RESULT_VIEW; - break; - } - label->SetTextContext(text_context); - label->SetTextStyle(STYLE_LAUNCHER); return label; } @@ -451,12 +472,14 @@ title_container_->SetFlexAllocationOrder( views::FlexAllocationOrder::kReverse); - result_text_separator_label_ = - SetupChildLabelView(title_and_details_container_, view_type_, - LabelType::kDetails, kColorAshTextColorSecondary, - kSeparatorOrder, has_keyboard_shortcut_contents_, - /*is_multi_line=*/false, - SearchResultTextItem::OverflowBehavior::kNoElide); + result_text_separator_label_ = SetupChildLabelView( + title_and_details_container_, view_type_, LabelType::kDetails, + kColorAshTextColorSecondary, + GetTypographyToken(LabelType::kDetails, /*is_match=*/false, + IsInlineSearchResult()), + kSeparatorOrder, has_keyboard_shortcut_contents_, + /*is_multi_line=*/false, + SearchResultTextItem::OverflowBehavior::kNoElide); result_text_separator_label_->SetText( l10n_util::GetStringUTF16(IDS_ASH_SEARCH_RESULT_SEPARATOR)); result_text_separator_label_->GetViewAccessibility().OverrideIsIgnored(true); @@ -473,22 +496,26 @@ .WithOrder(TitleDetailContainerOrder) .WithWeight(1)); - rating_separator_label_ = - SetupChildLabelView(title_and_details_container_, view_type_, - LabelType::kDetails, kColorAshTextColorSecondary, - kSeparatorOrder, has_keyboard_shortcut_contents_, - /*is_multi_line=*/false, - SearchResultTextItem::OverflowBehavior::kNoElide); + rating_separator_label_ = SetupChildLabelView( + title_and_details_container_, view_type_, LabelType::kDetails, + kColorAshTextColorSecondary, + GetTypographyToken(LabelType::kDetails, /*is_match=*/false, + IsInlineSearchResult()), + kSeparatorOrder, has_keyboard_shortcut_contents_, + /*is_multi_line=*/false, + SearchResultTextItem::OverflowBehavior::kNoElide); rating_separator_label_->SetText( l10n_util::GetStringUTF16(IDS_ASH_SEARCH_RESULT_SEPARATOR)); rating_separator_label_->GetViewAccessibility().OverrideIsIgnored(true); - rating_ = - SetupChildLabelView(title_and_details_container_, view_type_, - LabelType::kDetails, kColorAshTextColorSecondary, - kRatingOrder, has_keyboard_shortcut_contents_, - /*is_multi_line=*/false, - SearchResultTextItem::OverflowBehavior::kNoElide); + rating_ = SetupChildLabelView( + title_and_details_container_, view_type_, LabelType::kDetails, + kColorAshTextColorSecondary, + GetTypographyToken(LabelType::kDetails, /*is_match=*/false, + IsInlineSearchResult()), + kRatingOrder, has_keyboard_shortcut_contents_, + /*is_multi_line=*/false, + SearchResultTextItem::OverflowBehavior::kNoElide); rating_star_ = SetupChildImageView(title_and_details_container_); rating_star_->SetBorder(views::CreateEmptyBorder( @@ -504,6 +531,13 @@ SearchResultView::~SearchResultView() = default; +bool SearchResultView::IsInlineSearchResult() { + // has_keyboard_shortcut_contents_ forces inline title and details text for + // answer cards. + return view_type_ != SearchResultView::SearchResultViewType::kAnswerCard || + has_keyboard_shortcut_contents_; +} + void SearchResultView::OnResultChanged() { OnMetadataChanged(); SchedulePaint(); @@ -714,7 +748,9 @@ SearchResultTextItem::OverflowBehavior::kNoElide; views::Label* label = SetupChildLabelView( parent, view_type_, label_type, - GetLabelColorId(IsTitleLabel(label_type), span.GetTextTags()), + GetLabelColorId(label_type, span.GetTextTags()), + GetTypographyToken(label_type, /*is_match=*/false, + IsInlineSearchResult()), !elidable ? kNonElideLabelOrder : kElidableLabelOrderStart + label_count, has_keyboard_shortcut_contents,
diff --git a/ash/app_list/views/search_result_view.h b/ash/app_list/views/search_result_view.h index 3b2a920..41ee6570 100644 --- a/ash/app_list/views/search_result_view.h +++ b/ash/app_list/views/search_result_view.h
@@ -247,6 +247,8 @@ void OnSearchResultActionActivated(size_t index) override; bool IsSearchResultHoveredOrSelected() override; + bool IsInlineSearchResult(); + // Parent list view. Owned by views hierarchy. const raw_ptr<SearchResultListView, ExperimentalAsh> list_view_;
diff --git a/ash/public/cpp/shell_window_ids.h b/ash/public/cpp/shell_window_ids.h index 0eb60fe..fd2774a 100644 --- a/ash/public/cpp/shell_window_ids.h +++ b/ash/public/cpp/shell_window_ids.h
@@ -90,7 +90,6 @@ kShellWindowId_AlwaysOnTopContainer, // The container for the floating window. - // Experimental feature, please don't use this container. kShellWindowId_FloatContainer, // The container for the app list.
diff --git a/ash/quick_pair/fast_pair_handshake/fast_pair_gatt_service_client_impl.cc b/ash/quick_pair/fast_pair_handshake/fast_pair_gatt_service_client_impl.cc index 80ee621..33e47a1 100644 --- a/ash/quick_pair/fast_pair_handshake/fast_pair_gatt_service_client_impl.cc +++ b/ash/quick_pair/fast_pair_handshake/fast_pair_gatt_service_client_impl.cc
@@ -323,6 +323,7 @@ adapter_.reset(); adapter_observation_.Reset(); gatt_connection_.reset(); + StopAllWriteRequestTimers(); gatt_service_ = nullptr; account_key_characteristic_ = nullptr; key_based_characteristic_ = nullptr; @@ -331,11 +332,8 @@ gatt_disconnect_timer_.Stop(); passkey_notify_session_timer_.Stop(); keybased_notify_session_timer_.Stop(); - passkey_write_request_timer_.Stop(); - key_based_write_request_timer_.Stop(); key_based_notify_session_.reset(); passkey_notify_session_.reset(); - account_key_write_request_timer_.Stop(); } void FastPairGattServiceClientImpl::NotifyInitializedError( @@ -355,7 +353,7 @@ void FastPairGattServiceClientImpl::NotifyWriteRequestError( PairFailure failure) { - key_based_write_request_timer_.Stop(); + StopWriteRequestTimer(key_based_characteristic_); // |key_based_write_response_callback_| should always exist here. // If |OnWriteRequestError| is used to notify error before the timer @@ -369,7 +367,7 @@ void FastPairGattServiceClientImpl::NotifyWritePasskeyError( PairFailure failure) { - passkey_write_request_timer_.Stop(); + StopWriteRequestTimer(passkey_characteristic_); // |passkey_write_response_callback_| should always exist here. // If |OnWritePasskeyError| is used to notify error before the timer @@ -383,7 +381,7 @@ void FastPairGattServiceClientImpl::NotifyWriteAccountKeyError( ash::quick_pair::AccountKeyFailure failure) { - account_key_write_request_timer_.Stop(); + StopWriteRequestTimer(account_key_characteristic_); DCHECK(write_account_key_callback_); std::move(write_account_key_callback_).Run(failure); } @@ -478,15 +476,13 @@ key_based_notify_session_ = std::move(session); key_based_write_request_start_time_ = base::TimeTicks::Now(); - key_based_write_request_timer_.Start( - FROM_HERE, kGattOperationTimeout, + + WriteGattCharacteristicWithTimeout( + key_based_characteristic_, request_data, + device::BluetoothRemoteGattCharacteristic::WriteType::kWithResponse, base::BindOnce(&FastPairGattServiceClientImpl::NotifyWriteRequestError, weak_ptr_factory_.GetWeakPtr(), - PairFailure::kKeyBasedPairingResponseTimeout)); - - key_based_characteristic_->WriteRemoteCharacteristic( - request_data, - device::BluetoothRemoteGattCharacteristic::WriteType::kWithResponse, + PairFailure::kKeyBasedPairingResponseTimeout), base::BindOnce(&FastPairGattServiceClientImpl::OnWriteRequest, weak_ptr_factory_.GetWeakPtr()), base::BindOnce(&FastPairGattServiceClientImpl::OnWriteRequestError, @@ -509,15 +505,13 @@ FastPairGattConnectionSteps::kNotifiationsEnabledForKeybasedPairing); passkey_write_request_start_time_ = base::TimeTicks::Now(); - passkey_write_request_timer_.Start( - FROM_HERE, kGattOperationTimeout, + + WriteGattCharacteristicWithTimeout( + passkey_characteristic_, passkey_data, + device::BluetoothRemoteGattCharacteristic::WriteType::kWithResponse, base::BindOnce(&FastPairGattServiceClientImpl::NotifyWritePasskeyError, weak_ptr_factory_.GetWeakPtr(), - PairFailure::kPasskeyResponseTimeout)); - - passkey_characteristic_->WriteRemoteCharacteristic( - passkey_data, - device::BluetoothRemoteGattCharacteristic::WriteType::kWithResponse, + PairFailure::kPasskeyResponseTimeout), base::BindOnce(&FastPairGattServiceClientImpl::OnWritePasskey, weak_ptr_factory_.GetWeakPtr()), base::BindOnce(&FastPairGattServiceClientImpl::OnWritePasskeyError, @@ -694,16 +688,14 @@ const std::array<uint8_t, kBlockSizeBytes> data_to_write = fast_pair_data_encryptor->EncryptBytes(account_key); - account_key_write_request_timer_.Start( - FROM_HERE, kGattOperationTimeout, + WriteGattCharacteristicWithTimeout( + account_key_characteristic_, + std::vector<uint8_t>(data_to_write.begin(), data_to_write.end()), + device::BluetoothRemoteGattCharacteristic::WriteType::kWithResponse, base::BindOnce(&FastPairGattServiceClientImpl::NotifyWriteAccountKeyError, weak_ptr_factory_.GetWeakPtr(), ash::quick_pair::AccountKeyFailure:: - kAccountKeyCharacteristicWriteTimeout)); - - account_key_characteristic_->WriteRemoteCharacteristic( - std::vector<uint8_t>(data_to_write.begin(), data_to_write.end()), - device::BluetoothRemoteGattCharacteristic::WriteType::kWithResponse, + kAccountKeyCharacteristicWriteTimeout), base::BindOnce(&FastPairGattServiceClientImpl::OnWriteAccountKey, weak_ptr_factory_.GetWeakPtr(), base::TimeTicks::Now()), base::BindOnce(&FastPairGattServiceClientImpl::OnWriteAccountKeyError, @@ -725,7 +717,7 @@ key_based_write_response_callback_) { RecordKeyBasedWriteRequestTime(base::TimeTicks::Now() - key_based_write_request_start_time_); - key_based_write_request_timer_.Stop(); + StopWriteRequestTimer(key_based_characteristic_); std::move(key_based_write_response_callback_) .Run(value, /*failure=*/absl::nullopt); RecordNotifyKeyBasedCharacteristicTime(base::TimeTicks::Now() - @@ -734,7 +726,7 @@ passkey_write_response_callback_) { RecordPasskeyWriteRequestTime(base::TimeTicks::Now() - passkey_write_request_start_time_); - passkey_write_request_timer_.Stop(); + StopWriteRequestTimer(passkey_characteristic_); RecordNotifyPasskeyCharacteristicTime(base::TimeTicks::Now() - notify_passkey_start_time_); std::move(passkey_write_response_callback_) @@ -766,7 +758,7 @@ void FastPairGattServiceClientImpl::OnWriteAccountKey( base::TimeTicks write_account_key_start_time) { - account_key_write_request_timer_.Stop(); + StopWriteRequestTimer(account_key_characteristic_); QP_LOG(INFO) << __func__; RecordWriteAccountKeyTime(base::TimeTicks::Now() - write_account_key_start_time); @@ -781,5 +773,59 @@ // |this| may be destroyed after this line. } +void FastPairGattServiceClientImpl::WriteGattCharacteristicWithTimeout( + device::BluetoothRemoteGattCharacteristic* characteristic, + const std::vector<uint8_t>& encrypted_request, + device::BluetoothRemoteGattCharacteristic::WriteType write_type, + base::OnceClosure on_timeout, + base::OnceClosure on_success, + base::OnceCallback<void(device::BluetoothGattService::GattErrorCode)> + on_failure) { + CHECK(!characteristic_write_request_timers_.contains(characteristic) || + !characteristic_write_request_timers_[characteristic]->IsRunning()); + std::unique_ptr<base::OneShotTimer> timer = + std::make_unique<base::OneShotTimer>(); + timer->Start(FROM_HERE, kGattOperationTimeout, std::move(on_timeout)); + characteristic_write_request_timers_.insert( + {characteristic, std::move(timer)}); + characteristic->WriteRemoteCharacteristic( + encrypted_request, write_type, + base::BindOnce(&FastPairGattServiceClientImpl::StopTimerRunSuccess, + weak_ptr_factory_.GetWeakPtr(), characteristic, + std::move(on_success)), + base::BindOnce(&FastPairGattServiceClientImpl::StopTimerRunFailure, + weak_ptr_factory_.GetWeakPtr(), characteristic, + std::move(on_failure))); +} + +void FastPairGattServiceClientImpl::StopTimerRunSuccess( + device::BluetoothRemoteGattCharacteristic* characteristic, + base::OnceClosure on_success) { + StopWriteRequestTimer(characteristic); + std::move(on_success).Run(); +} + +void FastPairGattServiceClientImpl::StopTimerRunFailure( + device::BluetoothRemoteGattCharacteristic* characteristic, + base::OnceCallback<void(device::BluetoothGattService::GattErrorCode)> + on_failure, + device::BluetoothGattService::GattErrorCode error) { + StopWriteRequestTimer(characteristic); + std::move(on_failure).Run(/*error=*/error); +} + +void FastPairGattServiceClientImpl::StopAllWriteRequestTimers() { + for (auto& [characteristic, timer] : characteristic_write_request_timers_) { + timer->Stop(); + } +} + +void FastPairGattServiceClientImpl::StopWriteRequestTimer( + device::BluetoothRemoteGattCharacteristic* characteristic) { + if (characteristic_write_request_timers_.contains(characteristic)) { + characteristic_write_request_timers_[characteristic]->Stop(); + } +} + } // namespace quick_pair } // namespace ash
diff --git a/ash/quick_pair/fast_pair_handshake/fast_pair_gatt_service_client_impl.h b/ash/quick_pair/fast_pair_handshake/fast_pair_gatt_service_client_impl.h index b6dbd689..ddc0fa605 100644 --- a/ash/quick_pair/fast_pair_handshake/fast_pair_gatt_service_client_impl.h +++ b/ash/quick_pair/fast_pair_handshake/fast_pair_gatt_service_client_impl.h
@@ -20,6 +20,7 @@ #include "base/time/time.h" #include "base/timer/timer.h" #include "device/bluetooth/bluetooth_adapter.h" +#include "device/bluetooth/bluetooth_remote_gatt_characteristic.h" #include "third_party/abseil-cpp/absl/types/optional.h" namespace device { @@ -152,6 +153,37 @@ GetCharacteristicsByUUIDs(const device::BluetoothUUID& uuidV1, const device::BluetoothUUID& uuidV2); + // Writes `encrypted_request` to `characteristic`. + void WriteGattCharacteristicWithTimeout( + device::BluetoothRemoteGattCharacteristic* characteristic, + const std::vector<uint8_t>& encrypted_request, + device::BluetoothRemoteGattCharacteristic::WriteType write_type, + base::OnceClosure on_timeout, + base::OnceClosure on_sucess, + base::OnceCallback<void(device::BluetoothGattService::GattErrorCode)> + on_failure); + + // Helper functions to WriteGattCharacteristicTimeout. + // Both stop `characteristic`'s corresponding timer in + // `characteristic_write_request_timers_` and run `on_success`/`on_failure` + // callbacks. `on_failure` must take parameter `error`. + void StopTimerRunSuccess( + device::BluetoothRemoteGattCharacteristic* characteristic, + base::OnceClosure on_success); + void StopTimerRunFailure( + device::BluetoothRemoteGattCharacteristic* characteristic, + base::OnceCallback<void(device::BluetoothGattService::GattErrorCode)> + on_failure, + device::BluetoothGattService::GattErrorCode error); + + // Stops `characteristic`'s corresponding timer in + // `characteristic_write_request_timers_` if it exists. + void StopWriteRequestTimer( + device::BluetoothRemoteGattCharacteristic* characteristic); + + // Stops all timers in `characteristic_write_request_timers_`. + void StopAllWriteRequestTimers(); + // BluetoothRemoteGattCharacteristic StartNotifySession callbacks void OnKeyBasedRequestNotifySession( const std::vector<uint8_t>& request_data, @@ -176,9 +208,11 @@ base::OneShotTimer gatt_service_discovery_timer_; base::OneShotTimer passkey_notify_session_timer_; base::OneShotTimer keybased_notify_session_timer_; - base::OneShotTimer passkey_write_request_timer_; base::OneShotTimer key_based_write_request_timer_; - base::OneShotTimer account_key_write_request_timer_; + + std::map<device::BluetoothRemoteGattCharacteristic*, + std::unique_ptr<base::OneShotTimer>> + characteristic_write_request_timers_; base::TimeTicks gatt_service_discovery_start_time_; base::TimeTicks passkey_notify_session_start_time_;
diff --git a/ash/session/session_controller_impl.cc b/ash/session/session_controller_impl.cc index 4224c32..cb7522d 100644 --- a/ash/session/session_controller_impl.cc +++ b/ash/session/session_controller_impl.cc
@@ -182,6 +182,15 @@ return active_user_type == user_manager::USER_TYPE_CHILD; } +bool SessionControllerImpl::IsUserGuest() const { + if (!IsActiveUserSessionStarted()) { + return false; + } + + user_manager::UserType active_user_type = GetUserSession(0)->user_info.type; + return active_user_type == user_manager::USER_TYPE_GUEST; +} + bool SessionControllerImpl::IsUserPublicAccount() const { if (!IsActiveUserSessionStarted()) return false;
diff --git a/ash/session/session_controller_impl.h b/ash/session/session_controller_impl.h index ea5da57..4c4792f 100644 --- a/ash/session/session_controller_impl.h +++ b/ash/session/session_controller_impl.h
@@ -119,6 +119,9 @@ // Returns true if the current user is a child account. bool IsUserChild() const; + // Returns true if the current user is a guest account. + bool IsUserGuest() const; + // Returns true if the current user is a public account. bool IsUserPublicAccount() const;
diff --git a/ash/system/unified/power_button.cc b/ash/system/unified/power_button.cc index 4fd28ed..2c44473 100644 --- a/ash/system/unified/power_button.cc +++ b/ash/system/unified/power_button.cc
@@ -117,8 +117,8 @@ switch (user_session->user_info.type) { case user_manager::USER_TYPE_REGULAR: case user_manager::USER_TYPE_CHILD: - case user_manager::USER_TYPE_GUEST: return true; + case user_manager::USER_TYPE_GUEST: case user_manager::USER_TYPE_PUBLIC_ACCOUNT: case user_manager::USER_TYPE_KIOSK_APP: case user_manager::USER_TYPE_ARC_KIOSK_APP: @@ -129,28 +129,12 @@ } } -// Returns the icon for the email address item in the power menu. -const gfx::VectorIcon& GetEmailMenuItemIcon() { - // The 0th user session is the current one. - const UserSession* user_session = - Shell::Get()->session_controller()->GetUserSession(/*index=*/0); - CHECK(user_session); - if (user_session->user_info.type == user_manager::USER_TYPE_GUEST) { - return kSystemMenuGuestIcon; - } - return kSystemMenuNewUserIcon; -} - // Returns the text for the email address item in the power menu. std::u16string GetEmailMenuItemText() { // The 0th user session is the current one. const UserSession* user_session = Shell::Get()->session_controller()->GetUserSession(/*index=*/0); CHECK(user_session); - // Guest mode shows the string "Guest". - if (user_session->user_info.type == user_manager::USER_TYPE_GUEST) { - return l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_GUEST_LABEL); - } return base::UTF8ToUTF16(user_session->user_info.display_email); } @@ -254,7 +238,7 @@ if (ShouldShowEmailMenuItem()) { context_menu_model_->AddItemWithIcon( VIEW_ID_QS_POWER_EMAIL_MENU_BUTTON, GetEmailMenuItemText(), - ui::ImageModel::FromVectorIcon(GetEmailMenuItemIcon(), + ui::ImageModel::FromVectorIcon(kSystemMenuNewUserIcon, ui::kColorAshSystemUIMenuIcon, kTrayTopShortcutButtonIconSize)); context_menu_model_->AddSeparator(ui::NORMAL_SEPARATOR);
diff --git a/ash/system/unified/power_button_unittest.cc b/ash/system/unified/power_button_unittest.cc index 994f06c..b16a50e 100644 --- a/ash/system/unified/power_button_unittest.cc +++ b/ash/system/unified/power_button_unittest.cc
@@ -329,7 +329,7 @@ SimulateGuestLogin(); SimulatePowerButtonPress(); EXPECT_TRUE(IsMenuShowing()); - EXPECT_TRUE(GetEmailButton()->GetVisible()); + EXPECT_EQ(nullptr, GetEmailButton()); EXPECT_EQ(nullptr, GetLockButton()); EXPECT_TRUE(GetSignOutButton()->GetVisible()); EXPECT_TRUE(GetPowerOffButton()->GetVisible()); @@ -353,15 +353,6 @@ EXPECT_EQ(u"child@gmail.com", GetEmailButton()->title()); } -TEST_F(PowerButtonTest, GuestIsShownForGuestMode) { - SimulateGuestLogin(); - SimulatePowerButtonPress(); - EXPECT_TRUE(GetEmailButton()->GetVisible()); - // The multi-profile user chooser is disabled in guest mode. - EXPECT_FALSE(GetEmailButton()->GetEnabled()); - EXPECT_EQ(u"Guest", GetEmailButton()->title()); -} - TEST_F(PowerButtonTest, EmailIsNotShownForPublicAccount) { SimulateUserLogin("test@test.com", user_manager::USER_TYPE_PUBLIC_ACCOUNT); SimulatePowerButtonPress();
diff --git a/ash/system/unified/quick_settings_footer.cc b/ash/system/unified/quick_settings_footer.cc index 6b962c7..eae17f7 100644 --- a/ash/system/unified/quick_settings_footer.cc +++ b/ash/system/unified/quick_settings_footer.cc
@@ -13,6 +13,7 @@ #include "ash/constants/quick_settings_catalogs.h" #include "ash/public/cpp/ash_view_ids.h" #include "ash/resources/vector_icons/vector_icons.h" +#include "ash/session/session_controller_impl.h" #include "ash/shell.h" #include "ash/strings/grit/ash_strings.h" #include "ash/style/icon_button.h" @@ -22,6 +23,7 @@ #include "ash/system/unified/power_button.h" #include "ash/system/unified/quick_settings_metrics_util.h" #include "ash/system/unified/unified_system_tray_controller.h" +#include "ash/system/user/login_status.h" #include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_service.h" #include "components/vector_icons/vector_icons.h" @@ -42,6 +44,23 @@ constexpr int kHorizontalSpacing = 12; constexpr int kPaddingReduction = 0; +bool ShouldShowSignOutButton() { + auto* session_controller = Shell::Get()->session_controller(); + // Don't show before login. + if (!session_controller->IsActiveUserSessionStarted()) { + return false; + } + // Show "Exit guest" or "Exit session" button for special account types. + if (session_controller->IsUserGuest() || + session_controller->IsUserPublicAccount()) { + return true; + } + // For regular accounts, only show if there is more than one account on the + // device. + absl::optional<int> user_count = session_controller->GetExistingUsersCount(); + return user_count.has_value() && user_count.value() > 1; +} + } // namespace QsBatteryInfoViewBase::QsBatteryInfoViewBase( @@ -170,13 +189,28 @@ front_buttons_container->SetLayoutManager( std::make_unique<views::BoxLayout>( views::BoxLayout::Orientation::kHorizontal)); - button_container_layout->set_between_child_spacing(16); + button_container_layout->set_between_child_spacing(8); power_button_ = front_buttons_container->AddChildView( std::make_unique<PowerButton>(controller)); - // TODO(b/278323464): Add a "Sign out" button to `front_buttons_container` if - // there are multiple accounts on the device. + if (ShouldShowSignOutButton()) { + sign_out_button_ = + front_buttons_container->AddChildView(std::make_unique<PillButton>( + base::BindRepeating( + [](UnifiedSystemTrayController* controller) { + quick_settings_metrics_util::RecordQsButtonActivated( + QsButtonCatalogName::kSignOutButton); + controller->HandleSignOutAction(); + }, + base::Unretained(controller)), + user::GetLocalizedSignOutStringForStatus( + Shell::Get()->session_controller()->login_status(), + /*multiline=*/false), + PillButton::Type::kDefaultWithoutIcon, + /*icon=*/nullptr)); + sign_out_button_->SetID(VIEW_ID_QS_SIGN_OUT_BUTTON); + } // `PowerButton` should start aligned , also battery icons and // `settings_button_` should be end aligned, so here adding a empty spacing
diff --git a/ash/system/unified/quick_settings_footer.h b/ash/system/unified/quick_settings_footer.h index f1ddfd2..124b6a17 100644 --- a/ash/system/unified/quick_settings_footer.h +++ b/ash/system/unified/quick_settings_footer.h
@@ -18,6 +18,7 @@ namespace ash { class IconButton; +class PillButton; class UnifiedSystemTrayController; // A base class for both `QsBatteryLabelView` and `QsBatteryIconView`. This view @@ -109,6 +110,7 @@ // Owned by views hierarchy. raw_ptr<PowerButton, ExperimentalAsh> power_button_ = nullptr; + raw_ptr<PillButton, ExperimentalAsh> sign_out_button_ = nullptr; // The registrar used to watch prefs changes. PrefChangeRegistrar local_state_pref_change_registrar_;
diff --git a/ash/system/unified/quick_settings_footer_unittest.cc b/ash/system/unified/quick_settings_footer_unittest.cc index fefc641..c1a9bc5 100644 --- a/ash/system/unified/quick_settings_footer_unittest.cc +++ b/ash/system/unified/quick_settings_footer_unittest.cc
@@ -18,7 +18,7 @@ #include "base/memory/scoped_refptr.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" -#include "ui/views/controls/menu/menu_item_view.h" +#include "components/user_manager/user_type.h" #include "ui/views/test/views_test_utils.h" #include "ui/views/view_utils.h" #include "ui/views/widget/widget.h" @@ -55,43 +55,7 @@ ->unified_system_tray_controller())); } - views::MenuItemView* GetMenuView() { - return GetPowerButton()->GetMenuViewForTesting(); - } - - bool IsMenuShowing() { return GetPowerButton()->IsMenuShowing(); } - - views::View* GetSignOutButton() { - if (!IsMenuShowing()) { - return nullptr; - } - - return GetMenuView()->GetMenuItemByID(VIEW_ID_QS_POWER_SIGNOUT_MENU_BUTTON); - } - - views::View* GetLockButton() { - if (!IsMenuShowing()) { - return nullptr; - } - - return GetMenuView()->GetMenuItemByID(VIEW_ID_QS_POWER_LOCK_MENU_BUTTON); - } - - views::View* GetRestartButton() { - if (!IsMenuShowing()) { - return nullptr; - } - - return GetMenuView()->GetMenuItemByID(VIEW_ID_QS_POWER_RESTART_MENU_BUTTON); - } - - views::View* GetPowerOffButton() { - if (!IsMenuShowing()) { - return nullptr; - } - - return GetMenuView()->GetMenuItemByID(VIEW_ID_QS_POWER_OFF_MENU_BUTTON); - } + PillButton* GetSignOutButton() { return footer_->sign_out_button_; } views::Button* GetSettingsButton() { return footer_->settings_button_; } @@ -141,13 +105,6 @@ EXPECT_TRUE(GetBatteryButton()->GetVisible()); EXPECT_EQ(VIEW_ID_QS_BATTERY_BUTTON, GetBatteryButton()->GetID()); - // No menu buttons are visible before showing the menu. - EXPECT_FALSE(IsMenuShowing()); - EXPECT_EQ(nullptr, GetRestartButton()); - EXPECT_EQ(nullptr, GetSignOutButton()); - EXPECT_EQ(nullptr, GetLockButton()); - EXPECT_EQ(nullptr, GetPowerOffButton()); - // Test the UMA tracking. LeftClickOn(GetPowerButton()); @@ -157,14 +114,6 @@ QsButtonCatalogName::kPowerButton, /*expected_count=*/1); - EXPECT_TRUE(IsMenuShowing()); - - // Show all buttons in the menu. - EXPECT_TRUE(GetLockButton()->GetVisible()); - EXPECT_TRUE(GetSignOutButton()->GetVisible()); - EXPECT_TRUE(GetPowerOffButton()->GetVisible()); - EXPECT_TRUE(GetRestartButton()->GetVisible()); - // Close the power button menu. PressAndReleaseKey(ui::VKEY_ESCAPE); @@ -183,6 +132,7 @@ EXPECT_EQ(nullptr, GetSettingsButton()); EXPECT_TRUE(GetPowerButton()->GetVisible()); EXPECT_TRUE(GetBatteryButton()->GetVisible()); + EXPECT_EQ(nullptr, GetSignOutButton()); } // All buttons are shown after login. @@ -194,23 +144,8 @@ EXPECT_TRUE(GetPowerButton()->GetVisible()); EXPECT_TRUE(GetBatteryButton()->GetVisible()); - // No menu buttons are visible before showing the menu. - EXPECT_FALSE(IsMenuShowing()); - EXPECT_EQ(nullptr, GetRestartButton()); + // No sign-out button because there is only one account on the device. EXPECT_EQ(nullptr, GetSignOutButton()); - EXPECT_EQ(nullptr, GetLockButton()); - EXPECT_EQ(nullptr, GetPowerOffButton()); - - // Clicks on the power button. - LeftClickOn(GetPowerButton()); - - EXPECT_TRUE(IsMenuShowing()); - - // Show all buttons in the menu. - EXPECT_TRUE(GetLockButton()->GetVisible()); - EXPECT_TRUE(GetSignOutButton()->GetVisible()); - EXPECT_TRUE(GetPowerOffButton()->GetVisible()); - EXPECT_TRUE(GetRestartButton()->GetVisible()); } // Settings button is hidden at the lock screen. @@ -235,6 +170,69 @@ EXPECT_TRUE(GetBatteryButton()->GetVisible()); } +TEST_F(QuickSettingsFooterTest, ButtonStatesGuestMode) { + SimulateGuestLogin(); + SetUpView(); + + ASSERT_TRUE(GetSettingsButton()); + EXPECT_TRUE(GetSettingsButton()->GetVisible()); + + ASSERT_TRUE(GetPowerButton()); + EXPECT_TRUE(GetPowerButton()->GetVisible()); + + ASSERT_TRUE(GetBatteryButton()); + EXPECT_TRUE(GetBatteryButton()->GetVisible()); + + ASSERT_TRUE(GetSignOutButton()); + EXPECT_TRUE(GetSignOutButton()->GetVisible()); + EXPECT_EQ(u"Exit guest", GetSignOutButton()->GetText()); +} + +TEST_F(QuickSettingsFooterTest, ButtonStatesPublicAccount) { + SimulateUserLogin("foo@example.com", user_manager::USER_TYPE_PUBLIC_ACCOUNT); + SetUpView(); + + ASSERT_TRUE(GetSettingsButton()); + EXPECT_TRUE(GetSettingsButton()->GetVisible()); + + ASSERT_TRUE(GetPowerButton()); + EXPECT_TRUE(GetPowerButton()->GetVisible()); + + ASSERT_TRUE(GetBatteryButton()); + EXPECT_TRUE(GetBatteryButton()->GetVisible()); + + ASSERT_TRUE(GetSignOutButton()); + EXPECT_TRUE(GetSignOutButton()->GetVisible()); + EXPECT_EQ(u"Exit session", GetSignOutButton()->GetText()); +} + +TEST_F(QuickSettingsFooterTest, SignOutShowsWithMultipleAccounts) { + GetSessionControllerClient()->set_existing_users_count(2); + CreateUserSessions(1); + SetUpView(); + + ASSERT_TRUE(GetSignOutButton()); + EXPECT_TRUE(GetSignOutButton()->GetVisible()); + EXPECT_EQ(u"Sign out", GetSignOutButton()->GetText()); +} + +TEST_F(QuickSettingsFooterTest, SignOutButtonRecordsUmaAndSignsOut) { + GetSessionControllerClient()->set_existing_users_count(2); + CreateUserSessions(1); + SetUpView(); + + base::HistogramTester histogram_tester; + LeftClickOn(GetSignOutButton()); + + histogram_tester.ExpectTotalCount("Ash.QuickSettings.Button.Activated", + /*expected_count=*/1); + histogram_tester.ExpectBucketCount("Ash.QuickSettings.Button.Activated", + QsButtonCatalogName::kSignOutButton, + /*expected_count=*/1); + + EXPECT_EQ(1, GetSessionControllerClient()->request_sign_out_count()); +} + // Settings button is disabled when kSettingsIconDisabled is set. TEST_F(QuickSettingsFooterTest, DisableSettingsIconPolicy) { GetSessionControllerClient()->AddUserSession("foo@example.com",
diff --git a/ash/webui/common/resources/navigation_view_panel.html b/ash/webui/common/resources/navigation_view_panel.html index ac887ef..a4b1b3d 100644 --- a/ash/webui/common/resources/navigation_view_panel.html +++ b/ash/webui/common/resources/navigation_view_panel.html
@@ -23,6 +23,7 @@ display: grid; grid-template-areas: var(--areas-nav-banner); grid-template-columns: var(--columns-nav); + grid-template-rows: auto auto 1fr; width: 100%; } @@ -30,6 +31,7 @@ display: grid; grid-template-areas: var(--areas-no-header-nav-banner); grid-template-columns: var(--columns-nav); + grid-template-rows: auto 1fr; width: 100%; } @@ -37,6 +39,7 @@ display: grid; grid-template-areas: var(--areas-nav); grid-template-columns: var(--columns-nav); + grid-template-rows: auto 1fr; width: 100%; } @@ -60,6 +63,11 @@ z-index: 3; } + #container { + height: 100%; + overflow: hidden; + } + cr-drawer { --cr-separator-line: none; --cr-drawer-background-color: var(--navigation-view-panel-bg-color); @@ -85,10 +93,13 @@ } #navigationBody { + box-sizing: border-box; grid-area: main; - justify-self: center; + height: 100%; min-width: 0; + overflow: overlay; padding-inline: var(--container-padding-nav); + width: 100%; } .left-aligned {
diff --git a/ash/webui/diagnostics_ui/resources/diagnostics_app.html b/ash/webui/diagnostics_ui/resources/diagnostics_app.html index 28aeb0e..0771a4a9 100644 --- a/ash/webui/diagnostics_ui/resources/diagnostics_app.html +++ b/ash/webui/diagnostics_ui/resources/diagnostics_app.html
@@ -9,6 +9,10 @@ --navigation-view-panel-bg-color: var(--cros-sys-app_base_shaded); } + #navigationPanel::part(top-nav) { + height: 56px; + } + page-toolbar { min-height: 56px; position: sticky;
diff --git a/ash/webui/diagnostics_ui/resources/routine_section.ts b/ash/webui/diagnostics_ui/resources/routine_section.ts index 1788f96a..ea484d4 100644 --- a/ash/webui/diagnostics_ui/resources/routine_section.ts +++ b/ash/webui/diagnostics_ui/resources/routine_section.ts
@@ -521,9 +521,11 @@ 'chargeTestResultText' : 'dischargeTestResultText'; const percentText = loadTimeData.getStringF( - 'percentageLabel', this.powerRoutineResult.percentChange.toFixed(2)); + 'percentageLabel', + (this.powerRoutineResult?.percentChange || 0).toFixed(2)); return loadTimeData.getStringF( - stringId, percentText, this.powerRoutineResult.timeElapsedSeconds); + stringId, percentText, + this.powerRoutineResult?.timeElapsedSeconds || 0); } private setBadgeAndStatusText(badgeType: BadgeType, statusText: string):
diff --git a/ash/webui/scanning/resources/loading_page.html b/ash/webui/scanning/resources/loading_page.html index d9e3b70..3c1a683 100644 --- a/ash/webui/scanning/resources/loading_page.html +++ b/ash/webui/scanning/resources/loading_page.html
@@ -43,7 +43,8 @@ margin-bottom: 32px; } - img { + img, + svg { height: 256px; } </style> @@ -52,8 +53,18 @@ </iron-media-query> <div id="loadingContainer"> <div id="loadingDiv" hidden="[[noScannersAvailable_]]"> - <img src$="[[getScannersLoadingSvgSrc_(isDarkModeEnabled_)]]" - alt="[[i18n('scannersLoadingText')]]"> + <!-- TODO(b/276493795): After the Jelly experiment is launched, remove + used image elements and SVGs. --> + <template is="dom-if" if="[[!isJellyEnabled_]]"> + <img src$="[[getScannersLoadingSvgSrc_(isDarkModeEnabled_)]]" + alt="[[i18n('scannersLoadingText')]]"> + </template> + <template is="dom-if" if="[[isJellyEnabled_]]"> + <svg preserveAspectRatio="xMidYMid meet" role="img" viewBox="0 0 257 256"> + <title>[[i18n('scannersLoadingText')]]</title> + <use href="svg/illo_loading_scanner.svg#illo_loading_scanner"></use> + </svg> + </template> <h1>[[i18n('scannersLoadingText')]]</h1> <paper-progress indeterminate></paper-progress> </div>
diff --git a/ash/webui/scanning/resources/loading_page.js b/ash/webui/scanning/resources/loading_page.js index 053518f..54ccb9c 100644 --- a/ash/webui/scanning/resources/loading_page.js +++ b/ash/webui/scanning/resources/loading_page.js
@@ -8,6 +8,7 @@ import './strings.m.js'; import {I18nBehavior} from 'chrome://resources/ash/common/i18n_behavior.js'; +import {loadTimeData} from 'chrome://resources/ash/common/load_time_data.m.js'; import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {AppState} from './scanning_app_types.js'; @@ -35,6 +36,14 @@ type: Boolean, }, + /** @protected {boolean} */ + isJellyEnabled_: { + type: Boolean, + value: () => { + return loadTimeData.getBoolean('isJellyEnabledForScanningApp'); + }, + }, + /** @private {boolean} */ noScannersAvailable_: { type: Boolean, @@ -76,4 +85,9 @@ onLearnMoreClick_() { this.fire('learn-more-click'); }, + + /** @param {boolean} enabled */ + setIsJellyEnabledForTesting(enabled) { + this.isJellyEnabled_ = enabled; + }, });
diff --git a/ash/webui/scanning/resources/scanning_app_resources.grd b/ash/webui/scanning/resources/scanning_app_resources.grd index 30dfc9c57..a49337f 100644 --- a/ash/webui/scanning/resources/scanning_app_resources.grd +++ b/ash/webui/scanning/resources/scanning_app_resources.grd
@@ -54,6 +54,7 @@ <include name="IDR_SCANNING_APP_ICON_128" file="scanning_app_icon_128.png" type="BINDATA" /> <include name="IDR_SCANNING_APP_ICON_192" file="scanning_app_icon_192.png" type="BINDATA" /> <include name="IDR_SCANNING_APP_ICON_256" file="scanning_app_icon_256.png" type="BINDATA" /> + <include name="IDR_SCANNING_APP_SCANNERS_LOADING_ILLO_SVG" file="svg/illo_loading_scanner.svg" type="BINDATA" /> <include name="IDR_SCANNING_APP_SCANNERS_LOADING_SVG" file="svg/scanners_loading.svg" type="BINDATA" /> <include name="IDR_SCANNING_APP_SCANNERS_LOADING_DARK_SVG" file="svg/scanners_loading_dark.svg" type="BINDATA" /> <include name="IDR_SCANNING_APP_NO_SCANNERS_SVG" file="svg/no_scanners.svg" type="BINDATA" />
diff --git a/ash/webui/scanning/resources/svg/illo_loading_scanner.svg b/ash/webui/scanning/resources/svg/illo_loading_scanner.svg new file mode 100644 index 0000000..eeb0b8b --- /dev/null +++ b/ash/webui/scanning/resources/svg/illo_loading_scanner.svg
@@ -0,0 +1,58 @@ +<svg id="illo_loading_scanner" xmlns="http://www.w3.org/2000/svg" width="257" height="256" viewBox="0 0 257 256" fill="none"> +<g clip-path="url(#clip0_3_31049)"> +<path d="M95.7439 185.8H29.0439C28.5415 185.827 28.0388 185.752 27.5665 185.578C27.0943 185.404 26.6624 185.136 26.2974 184.79C25.9323 184.443 25.6417 184.026 25.4434 183.564C25.2451 183.101 25.1432 182.603 25.1439 182.1V40.6C25.1306 40.1009 25.2158 39.6042 25.3946 39.138C25.5733 38.6719 25.8422 38.2455 26.1858 37.8833C26.5294 37.5212 26.941 37.2302 27.3971 37.0272C27.8532 36.8242 28.3449 36.713 28.8439 36.7H124.944C125.971 36.6987 126.959 37.0926 127.704 37.8C128.449 38.5074 128.893 39.4742 128.944 40.5V153.9L95.7439 185.8Z" fill="var(--cros-sys-illo-color1-2)" /> +<path d="M137.798 167.021C132.258 170.686 128.378 176.614 127.418 178.171C127.261 178.425 127.174 178.709 127.167 179.007C127.132 180.561 127.249 185.898 130.112 191.484C133.516 198.125 140.028 206.7 140.028 206.7C140.028 206.7 138.943 200.835 147.18 199.01C153.548 197.6 156.37 202.691 157.322 205.074C157.592 205.748 158.229 206.239 158.955 206.239C159.998 206.239 160.754 205.254 160.468 204.251C159.697 201.555 158.169 196.442 156.177 190.936C153.872 184.568 152.948 168.899 152.66 162.561C152.599 161.209 151.253 160.309 149.998 160.817C147.031 162.017 142.004 164.238 137.798 167.021Z" fill="var(--cros-sys-illo-base)" /> +<path d="M152.244 160.6L172.644 156.7C171.444 167.333 171.444 178.067 172.644 188.7C173.338 194.767 174.44 200.781 175.944 206.7H160.644C158.035 198.831 156.029 190.774 154.644 182.6C153.34 175.33 152.538 167.98 152.244 160.6Z" fill="var(--cros-sys-illo-color1-2)" stroke="var(--cros-sys-illo-color1)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" /> +<path d="M171.244 156.3L152.444 159.8C147.138 161.056 143.544 162.6 139.044 166C134.26 169.649 130.017 173.959 126.444 178.8" stroke="var(--cros-sys-illo-color1)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" /> +<path d="M165.444 145.6C166.144 147.4 167.144 150.3 168.444 153.9C169.744 157.5 170.544 158.8 170.244 160.5C169.944 162.2 167.044 166.6 163.344 166.2C161.804 166.031 160.379 165.31 159.33 164.17C158.282 163.03 157.683 161.548 157.644 160C157.444 157.8 157.344 155.6 157.144 153.4C158.897 153.443 160.616 152.917 162.044 151.9C163.011 151.138 163.812 150.186 164.397 149.103C164.982 148.019 165.338 146.827 165.444 145.6Z" fill="var(--cros-sys-illo-base)" stroke="var(--cros-sys-illo-color1)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" /> +<path d="M166.252 144.627C167.037 138.659 162.88 133.189 156.967 132.411C151.053 131.632 145.622 135.839 144.836 141.808C144.051 147.776 148.208 153.246 154.121 154.024C160.035 154.803 165.466 150.595 166.252 144.627Z" fill="var(--cros-sys-illo-base)" stroke="var(--cros-sys-illo-color1)" stroke-width="2" stroke-miterlimit="10" stroke-linecap="round" /> +<path d="M144.344 139.7L152.744 134.8L166.144 143.8C167.644 138.5 163.644 133 157.744 131.7C151.844 130.4 145.044 133.9 144.344 139.7Z" fill="var(--cros-sys-illo-color1)" /> +<path d="M149.344 146.1C149.482 146.609 149.734 147.081 150.08 147.479C150.427 147.877 150.859 148.192 151.344 148.4C151.97 148.598 152.641 148.598 153.267 148.401C153.893 148.205 154.444 147.82 154.844 147.3" stroke="var(--cros-sys-illo-color1)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" /> +<path d="M191.389 184.907L189.905 196.036L175.722 201.311C173.196 189.2 171.674 174.472 173.608 156.923C177.912 156.185 179.209 156.074 182.406 156.27C187.09 155.728 194.465 157.131 199.844 159.2C211.844 163.9 225.344 176.6 226.844 192.9C228.744 213.3 211.744 234.8 185.944 239L172.444 204.2L194.244 196C194.165 193.738 191.866 187.115 191.389 184.907Z" fill="var(--cros-sys-illo-base)" /> +<path d="M169.644 156.6L171.244 156.3C199.144 151 223.944 170 226.544 192.4C228.944 213.2 211.544 235.8 185.644 238.6L172.144 203.8L193.944 195.5L191.644 185.5" stroke="var(--cros-sys-illo-color1)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" /> +<path d="M159.344 130.7C158.544 128.8 155.544 128 152.344 127.8C146.761 126.484 140.956 126.416 135.344 127.6C131.045 128.585 126.543 129.839 122.836 132.229C117.12 135.678 112.752 140.959 109.344 146.7C105.044 154 102.944 163 103.944 167.6C109.834 173.107 113.016 173.431 123.444 168C123.344 167.5 122.944 166 122.344 164C121.744 162 121.444 160.8 121.744 160C123.444 158.798 126.094 156.766 127.644 155.1C130.558 152.007 132.775 148.324 134.144 144.3C136.385 142.42 139.743 141.2 142.616 140.655C148.342 140.655 150.944 141.6 152.544 139.4C152.868 138.967 153.044 138.441 153.044 137.9C153.795 137.783 154.512 137.509 155.15 137.095C155.788 136.681 156.331 136.138 156.744 135.5C156.99 135.213 157.162 134.869 157.244 134.5H157.344C157.756 134.384 158.14 134.182 158.467 133.906C158.795 133.63 159.06 133.287 159.244 132.9C159.528 132.2 159.563 131.423 159.344 130.7Z" fill="var(--cros-sys-illo-base)" /> +<path d="M129.644 134.1C133.834 132.319 138.299 131.271 142.844 131C147.444 130.7 156.144 131 156.944 134C157.012 134.781 156.799 135.561 156.344 136.2C155.936 136.812 155.406 137.333 154.786 137.729C154.166 138.125 153.471 138.387 152.744 138.5" fill="var(--cros-sys-illo-base)" /> +<path d="M129.644 134.1C133.834 132.319 138.299 131.271 142.844 131C147.444 130.7 156.144 131 156.944 134C157.012 134.781 156.799 135.561 156.344 136.2C155.936 136.812 155.406 137.333 154.786 137.729C154.166 138.125 153.471 138.387 152.744 138.5" stroke="var(--cros-sys-illo-color1)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" /> +<path d="M121.344 160.1C123.166 159.084 124.876 157.877 126.444 156.5C133.544 150.4 132.044 145.7 136.944 142.7C141.844 139.7 150.644 143.1 152.544 139.4C152.87 138.714 152.94 137.934 152.744 137.2C151.344 133.8 141.144 135.1 139.344 135.4C135.985 135.818 132.693 136.658 129.544 137.9" stroke="var(--cros-sys-illo-color1)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" /> +<path d="M129.944 131.2C134.104 129.875 138.396 129.003 142.744 128.6C146.544 128.3 157.444 127.4 158.944 131.3C159.08 131.671 159.14 132.065 159.123 132.46C159.106 132.855 159.011 133.242 158.844 133.6C158.654 133.972 158.386 134.299 158.058 134.558C157.73 134.817 157.35 135.002 156.944 135.1" stroke="var(--cros-sys-illo-color1)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" /> +<path d="M151.144 127.5C146.194 126.227 141.034 125.997 135.99 126.823C130.946 127.649 126.129 129.514 121.844 132.3C115.882 136.216 111.054 141.63 107.844 148C106.064 151.486 104.849 155.233 104.244 159.1" stroke="var(--cros-sys-illo-color1)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" /> +<path d="M121.339 160.1C123.338 167.469 125.338 174.838 127.238 182.305L135.248 206.106C133.673 204.945 131.727 204.259 129.621 204.259C124.809 204.259 120.834 207.839 120.214 212.481C115.644 212.944 110.486 212.46 105.341 209.914C91.0436 202.84 83.8448 181.126 93.8432 160.591L121.339 160.1Z" fill="var(--cros-sys-illo-base)" /> +<path d="M121.339 160.1C123.338 167.469 125.338 174.838 127.238 182.305L135.248 206.106C133.673 204.945 131.727 204.259 129.621 204.259C124.809 204.259 120.834 207.839 120.214 212.481C115.644 212.944 110.486 212.46 105.341 209.914C91.0436 202.84 83.8448 181.126 93.8432 160.591L121.339 160.1Z" stroke="var(--cros-sys-illo-color1)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" /> +<path d="M121.344 216.4L111.944 198.3C111.645 196.643 111.869 194.934 112.586 193.411C113.303 191.888 114.476 190.625 115.944 189.8C117.388 189.02 119.029 188.68 120.664 188.822C122.299 188.964 123.856 189.583 125.144 190.6C128.844 196.2 132.91 202.714 136.61 208.314" stroke="var(--cros-sys-illo-color1)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" /> +<path d="M140.451 209.608L131.644 191.4C131.444 190.354 131.457 189.278 131.683 188.237C131.909 187.196 132.344 186.211 132.96 185.342C133.577 184.474 134.363 183.739 135.271 183.181C136.179 182.624 137.19 182.256 138.244 182.1C139.424 181.863 140.643 181.902 141.805 182.214C142.967 182.526 144.042 183.103 144.944 183.9L156.947 203.971" stroke="var(--cros-sys-illo-color1)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" /> +<path d="M127.244 195.9C127.033 195.165 127.076 194.38 127.367 193.672C127.657 192.964 128.177 192.375 128.844 192C129.601 191.577 130.48 191.426 131.335 191.571C132.19 191.717 132.969 192.15 133.544 192.8L137.744 200.6L131.644 203.9L127.244 195.9Z" fill="var(--cros-sys-illo-base)" stroke="var(--cros-sys-illo-color1)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" /> +<path d="M135.329 205.785C137.24 205.493 138.566 203.795 138.29 201.994C138.014 200.192 136.242 198.969 134.331 199.261C132.42 199.554 131.095 201.251 131.37 203.053C131.646 204.854 133.419 206.078 135.329 205.785Z" fill="var(--cros-sys-illo-base)" stroke="var(--cros-sys-illo-color1)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" /> +<path d="M128.544 198.3C127.911 197.553 127.135 196.939 126.263 196.493C125.39 196.048 124.438 195.781 123.461 195.706C122.484 195.632 121.503 195.752 120.573 196.06C119.643 196.368 118.783 196.857 118.044 197.5C116.727 198.593 115.843 200.12 115.55 201.805C115.257 203.491 115.574 205.227 116.444 206.7" stroke="var(--cros-sys-illo-color1)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" /> +<path d="M149.144 191C148.132 189.521 146.618 188.459 144.882 188.012C143.146 187.565 141.307 187.763 139.707 188.57C138.106 189.376 136.853 190.736 136.179 192.397C135.505 194.058 135.457 195.906 136.044 197.6" stroke="var(--cros-sys-illo-color1)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" /> +<path d="M129.544 222.1C134.349 222.1 138.244 218.205 138.244 213.4C138.244 208.595 134.349 204.7 129.544 204.7C124.739 204.7 120.844 208.595 120.844 213.4C120.844 218.205 124.739 222.1 129.544 222.1Z" fill="var(--cros-sys-illo-color1-1)" stroke="var(--cros-sys-illo-color1)" stroke-width="2" stroke-miterlimit="10" /> +<path d="M149.044 216.5C153.849 216.5 157.744 212.605 157.744 207.8C157.744 202.995 153.849 199.1 149.044 199.1C144.239 199.1 140.344 202.995 140.344 207.8C140.344 212.605 144.239 216.5 149.044 216.5Z" fill="var(--cros-sys-illo-color1-1)" stroke="var(--cros-sys-illo-color1)" stroke-width="2" stroke-miterlimit="10" /> +<path d="M180.544 227.1C178.344 221.6 176.244 216.1 174.044 210.7H167.344C158.344 210.5 156.844 209.8 153.244 209.8C143.344 210 133.944 216.1 131.744 220C131.536 220.265 131.392 220.574 131.323 220.903C131.254 221.233 131.261 221.574 131.344 221.9C131.344 222.1 131.444 222.2 131.544 222.4L132.944 222C132.364 222.772 131.955 223.658 131.744 224.6C131.55 224.988 131.449 225.416 131.449 225.85C131.449 226.284 131.55 226.712 131.744 227.1C131.932 227.519 132.247 227.869 132.644 228.1L133.044 227.9C132.932 228.082 132.864 228.287 132.844 228.5C132.795 229.103 132.909 229.709 133.172 230.254C133.436 230.799 133.841 231.264 134.344 231.6C135.075 232 135.905 232.185 136.737 232.132C137.57 232.079 138.369 231.79 139.044 231.3C139.049 231.716 139.14 232.126 139.313 232.505C139.485 232.884 139.734 233.223 140.044 233.5C142.244 235.7 146.544 232.3 155.144 231.4C161.944 230.8 163.444 231.4 168.944 230.4C172.918 229.768 176.808 228.695 180.544 227.2" fill="var(--cros-sys-illo-base)" /> +<path d="M174.444 210.8H167.344C158.444 210.6 156.844 209.9 153.344 209.9C143.444 210.1 134.044 216.2 131.844 220.1C131.445 220.648 131.266 221.326 131.344 222L131.644 222.5" stroke="var(--cros-sys-illo-color1)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" /> +<path d="M180.644 227.2C176.908 228.695 173.018 229.768 169.044 230.4C163.544 231.4 162.044 230.8 155.244 231.4C146.644 232.3 142.344 235.7 140.044 233.5C139.694 233.13 139.431 232.687 139.275 232.202C139.12 231.718 139.075 231.204 139.144 230.7C139.744 227.3 146.344 225.8 150.244 224.9C152.687 224.413 155.159 224.079 157.644 223.9" stroke="var(--cros-sys-illo-color1)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" /> +<path d="M154.644 218.9C151.179 219.392 147.765 220.195 144.444 221.3C139.444 223 133.244 225.1 132.944 228.5C132.884 229.094 132.983 229.693 133.228 230.238C133.474 230.782 133.859 231.252 134.344 231.6C135.115 232.004 135.984 232.18 136.852 232.11C137.719 232.039 138.549 231.723 139.244 231.2" stroke="var(--cros-sys-illo-color1)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" /> +<path d="M151.544 214.8C148.479 215.313 145.442 215.98 142.444 216.8C138.144 218 136.344 218.9 134.744 220.2C133.369 221.353 132.361 222.882 131.844 224.6C131.65 224.988 131.549 225.416 131.549 225.85C131.549 226.284 131.65 226.712 131.844 227.1C132.032 227.519 132.347 227.869 132.744 228.1" stroke="var(--cros-sys-illo-color1)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" /> +<path d="M191.644 185.5L190.944 196" stroke="var(--cros-sys-illo-color1)" stroke-width="2" stroke-miterlimit="10" stroke-linecap="round" /> +<path d="M155.844 92.4L154.644 98.6L158.344 97.6L157.944 95.9C157.581 94.5616 156.854 93.3501 155.844 92.4Z" fill="var(--cros-sys-illo-color2)" /> +<path d="M159.544 103.2L158.644 98.9L155.044 99.9C154.824 99.9993 154.578 100.024 154.343 99.9696C153.903 99.8681 153.437 99.4806 153.327 99.0416C153.275 98.8302 153.28 98.6084 153.344 98.4L154.644 91.7C153.333 91.0911 151.861 90.916 150.444 91.2L143.144 92.8C141.527 93.1823 140.122 94.1787 139.226 95.5784C138.33 96.9781 138.014 98.6713 138.344 100.3L140.044 107.6C140.21 108.403 140.534 109.166 140.997 109.843C141.46 110.52 142.053 111.099 142.741 111.546C143.43 111.992 144.2 112.297 145.007 112.444C145.814 112.591 146.642 112.576 147.444 112.4L154.844 110.8C155.649 110.623 156.41 110.288 157.084 109.813C157.758 109.339 158.33 108.735 158.768 108.037C159.206 107.338 159.5 106.56 159.633 105.746C159.766 104.933 159.736 104.101 159.544 103.3V103.2Z" fill="var(--cros-sys-illo-color2)" /> +<path d="M157.744 82.6L170.544 94.2L158.344 97.6L158.644 98.9L170.944 95.5C171.295 95.3455 171.573 95.0626 171.722 94.7092C171.871 94.3559 171.879 93.959 171.744 93.6C171.641 93.4884 171.571 93.3496 171.544 93.2H171.444L158.644 81.7C158.446 81.5512 158.219 81.4472 157.977 81.3954C157.735 81.3436 157.485 81.3452 157.244 81.4C156.813 81.6364 156.49 82.0307 156.344 82.5L154.644 91.7L155.844 92.5L157.744 82.6Z" fill="var(--cros-sys-illo-color1)" /> +<path d="M241.444 103.8C243.653 103.8 245.444 102.009 245.444 99.8C245.444 97.5909 243.653 95.8 241.444 95.8C239.235 95.8 237.444 97.5909 237.444 99.8C237.444 102.009 239.235 103.8 241.444 103.8Z" fill="var(--cros-sys-illo-color5)" /> +<path d="M24.4439 202H94.6439" stroke="var(--cros-sys-illo-color1)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" /> +<path d="M158.044 206.7H172.244" stroke="var(--cros-sys-illo-color1)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" /> +<path d="M227.444 202H237.844" stroke="var(--cros-sys-illo-color1)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" /> +<path d="M171.944 85.3C171.654 84.5719 171.513 83.7934 171.527 83.0099C171.542 82.2265 171.713 81.4538 172.029 80.737C172.346 80.0202 172.802 79.3736 173.371 78.835C173.94 78.2964 174.611 77.8766 175.344 77.6H175.544L188.844 72.4C190.345 71.835 192.006 71.8735 193.479 72.5075C194.952 73.1415 196.122 74.3216 196.744 75.8C197.271 77.3273 197.192 78.9988 196.522 80.4691C195.852 81.9394 194.643 83.0961 193.144 83.7L179.844 88.8C179.099 89.1192 178.295 89.2813 177.485 89.2762C176.674 89.2711 175.873 89.099 175.132 88.7706C174.39 88.4422 173.725 87.9645 173.176 87.3674C172.628 86.7702 172.208 86.0665 171.944 85.3Z" fill="var(--cros-sys-illo-color3)" /> +<path d="M212.944 88C213.606 87.9753 214.255 87.8046 214.844 87.5L216.944 87.1C217.834 86.8552 218.766 86.7999 219.679 86.9377C220.592 87.0755 221.466 87.4034 222.244 87.9C223.046 88.584 223.959 89.1252 224.944 89.5C225.605 89.8939 226.339 90.1521 227.101 90.2597C227.863 90.3673 228.639 90.322 229.384 90.1266C230.129 89.9311 230.827 89.5893 231.438 89.1212C232.049 88.6531 232.561 88.068 232.944 87.4C233.336 86.7249 233.59 85.9787 233.692 85.2046C233.793 84.4305 233.74 83.6439 233.536 82.8905C233.331 82.1371 232.979 81.4318 232.5 80.8154C232.02 80.1991 231.424 79.684 230.744 79.3L229.044 78.6L224.444 78.2C222.826 78.0674 221.321 77.3151 220.244 76.1L218.844 74.5L217.444 73.1C216.339 72.2051 215.036 71.5879 213.644 71.3C211.674 70.8869 209.622 71.1947 207.86 72.1674C206.098 73.1401 204.744 74.713 204.044 76.6C203.663 77.6637 203.495 78.7921 203.55 79.9207C203.605 81.0493 203.881 82.156 204.364 83.1776C204.847 84.1991 205.527 85.1155 206.364 85.8743C207.201 86.6332 208.18 87.2196 209.244 87.6H209.544C210.644 87.936 211.796 88.0715 212.944 88Z" fill="var(--cros-sys-illo-color1-2)" /> +<path d="M162.344 122C164.127 120.855 166.288 120.455 168.363 120.885C170.438 121.315 172.262 122.541 173.444 124.3C174.04 125.223 174.444 126.256 174.633 127.338C174.822 128.421 174.792 129.53 174.544 130.6C174.935 130.092 175.409 129.653 175.944 129.3C177.671 128.146 179.776 127.699 181.823 128.053C183.871 128.406 185.704 129.533 186.944 131.2C187.401 131.801 188.075 132.2 188.822 132.312C189.569 132.425 190.33 132.241 190.944 131.8H191.044L191.544 131.5C193.086 130.571 194.891 130.176 196.68 130.375C198.469 130.573 200.143 131.355 201.444 132.6C201.999 133.2 202.47 133.873 202.844 134.6C202.993 134.923 203.206 135.212 203.471 135.45C203.736 135.687 204.046 135.868 204.384 135.98C204.721 136.093 205.078 136.135 205.433 136.104C205.787 136.073 206.131 135.969 206.444 135.8C206.644 135.8 206.744 135.7 206.944 135.5L211.644 132C212.891 131.096 214.437 130.706 215.964 130.911C217.49 131.115 218.879 131.899 219.844 133.1C220.424 133.872 220.833 134.758 221.044 135.7C221.273 136.721 221.222 137.784 220.896 138.778C220.57 139.772 219.981 140.66 219.192 141.346C218.403 142.033 217.443 142.494 216.413 142.679C215.384 142.865 214.323 142.768 213.344 142.4L206.244 140.1C205.606 139.896 204.915 139.937 204.305 140.214C203.695 140.491 203.21 140.985 202.944 141.6C202.356 142.85 201.451 143.925 200.318 144.716C199.185 145.507 197.865 145.987 196.489 146.109C195.113 146.23 193.728 145.988 192.475 145.408C191.221 144.827 190.142 143.928 189.344 142.8C188.905 142.205 188.248 141.809 187.518 141.696C186.787 141.584 186.042 141.765 185.444 142.2H185.344L185.044 142.4C183.329 143.621 181.202 144.116 179.124 143.779C177.046 143.442 175.185 142.3 173.944 140.6C173.299 139.624 172.867 138.522 172.677 137.368C172.488 136.213 172.545 135.031 172.844 133.9C172.429 134.386 171.959 134.822 171.444 135.2C170.591 135.792 169.629 136.209 168.614 136.429C167.599 136.649 166.551 136.666 165.529 136.481C164.508 136.295 163.533 135.909 162.66 135.347C161.787 134.784 161.034 134.054 160.444 133.2C159.816 132.346 159.366 131.375 159.121 130.343C158.876 129.312 158.841 128.242 159.019 127.197C159.196 126.152 159.582 125.153 160.153 124.26C160.724 123.368 161.469 122.599 162.344 122Z" fill="var(--cros-sys-illo-color1)" /> +<path d="M75.0439 55.1C73.6778 55.9699 72.5922 57.2162 71.918 58.6888C71.2439 60.1614 71.0097 61.7974 71.2439 63.4C71.2678 65.282 71.8224 67.1191 72.8439 68.7C73.3347 69.4938 73.9906 70.1726 74.7671 70.6903C75.5436 71.2079 76.4224 71.5523 77.3439 71.7C78.5133 71.8313 79.6968 71.6613 80.782 71.2062C81.8672 70.7511 82.8179 70.0261 83.5439 69.1C84.9788 67.1857 85.814 64.8889 85.9439 62.5C86.1373 60.5219 85.7184 58.5322 84.7439 56.8C83.7036 55.3047 82.1283 54.2664 80.3439 53.9C78.4918 53.6778 76.6197 54.1016 75.0439 55.1" stroke="var(--cros-sys-illo-base)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" /> +<path d="M71.7439 59.3C70.5765 62.082 68.9543 64.6504 66.9439 66.9C65.1439 68.6 62.1439 70.1 59.5439 69.9" stroke="var(--cros-sys-illo-base)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" /> +<path d="M89.2439 55.9C84.7439 64.1 85.2439 73.9 84.0439 83.1C83.6857 86.638 82.6322 90.0703 80.9439 93.2C78.6439 96.9 73.7439 100 69.3439 98.4C67.8196 97.8333 66.5581 96.7239 65.8015 95.2844C65.0449 93.845 64.8463 92.1769 65.2439 90.6C65.864 88.4305 66.9956 86.4414 68.5439 84.8C73.3439 79.6 80.4439 77.6 87.1439 75.8C93.8439 74 101.444 72.5 107.644 68.7" stroke="var(--cros-sys-illo-base)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" /> +<path d="M134.644 84.3H18.9439V87.3H134.644V84.3Z" fill="var(--cros-sys-illo-color1)" /> +<path d="M47.2439 110.4H110.744" stroke="var(--cros-sys-illo-base)" stroke-width="2" stroke-miterlimit="10" stroke-linecap="round" /> +<path d="M47.2439 136.1H110.744" stroke="var(--cros-sys-illo-base)" stroke-width="2" stroke-miterlimit="10" stroke-linecap="round" /> +<path d="M47.2439 123H110.744" stroke="var(--cros-sys-illo-base)" stroke-width="2" stroke-miterlimit="10" stroke-linecap="round" /> +</g> +<defs> +<clipPath id="clip0_3_31049"> +<rect width="256" height="256" fill="var(--cros-sys-illo-base)" transform="translate(0.243896)" /> +</clipPath> +</defs> +</svg> \ No newline at end of file
diff --git a/ash/webui/shortcut_customization_ui/resources/index.html b/ash/webui/shortcut_customization_ui/resources/index.html index b4bfd25..bb0730a 100644 --- a/ash/webui/shortcut_customization_ui/resources/index.html +++ b/ash/webui/shortcut_customization_ui/resources/index.html
@@ -9,6 +9,7 @@ <style> html { background-color: var(--cros-bg-color); + height: 100%; } html:has(body.jelly-enabled) { @@ -16,6 +17,7 @@ } body { + height: 100%; margin: 0; } </style>
diff --git a/ash/webui/shortcut_customization_ui/resources/js/accelerator_subsection.html b/ash/webui/shortcut_customization_ui/resources/js/accelerator_subsection.html index 4fe8b0c2..5f903df 100644 --- a/ash/webui/shortcut_customization_ui/resources/js/accelerator_subsection.html +++ b/ash/webui/shortcut_customization_ui/resources/js/accelerator_subsection.html
@@ -1,4 +1,8 @@ <style> + #container { + width: var(--cr-toolbar-field-width); + } + #title { align-items: center; color: var(--cros-text-color-primary); @@ -8,15 +12,6 @@ height: 48px; } - accelerator-row { - /** - * scroll-margin-top is used to position this element when it's scrolled - * to the top of the page by shortcuts-page when a search result is - * selected. Without this, the element would be hidden by the toolbar. - */ - scroll-margin-top: var(--navigation-view-panel-toolbar-height); - } - accelerator-row:not(:last-of-type) { border-bottom: var(--cr-separator-line); }
diff --git a/ash/webui/shortcut_customization_ui/resources/js/shortcut_customization_app.html b/ash/webui/shortcut_customization_ui/resources/js/shortcut_customization_app.html index 959d1cc..bff49735 100644 --- a/ash/webui/shortcut_customization_ui/resources/js/shortcut_customization_app.html +++ b/ash/webui/shortcut_customization_ui/resources/js/shortcut_customization_app.html
@@ -5,6 +5,7 @@ font-family: var(--shortcuts-font-family-default); font-size: var(--shortcuts-font-size-default); font-weight: var(--shortcuts-font-weight-regular); + height: 100%; } /** @@ -24,10 +25,6 @@ } } - #navigationPanel::part(nav-body) { - width: var(--cr-toolbar-field-width); - } - #navigationPanel::part(title) { color: var(--cros-text-color-secondary); padding-inline-start: 8px;
diff --git a/ash/webui/shortcut_customization_ui/resources/js/shortcuts_page.html b/ash/webui/shortcut_customization_ui/resources/js/shortcuts_page.html index 8ed3c32..bf9222c 100644 --- a/ash/webui/shortcut_customization_ui/resources/js/shortcuts_page.html +++ b/ash/webui/shortcut_customization_ui/resources/js/shortcuts_page.html
@@ -1,7 +1,10 @@ <style include="shortcut-customization-shared cr-shared-style"> #container { + align-items: center; + display: flex; + flex-direction: column; margin-top: 20px; - max-width: var(--cr-centered-card-max-width); + width: 100%; } #container accelerator-subsection:not(:first-child)::part(container) {
diff --git a/ash/wm/desks/templates/admin_template_launch_tracker.cc b/ash/wm/desks/templates/admin_template_launch_tracker.cc index 4f90995a..cb19ce0 100644 --- a/ash/wm/desks/templates/admin_template_launch_tracker.cc +++ b/ash/wm/desks/templates/admin_template_launch_tracker.cc
@@ -10,6 +10,7 @@ #include "ash/wm/desks/desk.h" #include "ash/wm/desks/desks_controller.h" #include "ash/wm/desks/templates/saved_desk_constants.h" +#include "ash/wm/work_area_insets.h" #include "base/containers/adapters.h" #include "base/logging.h" #include "base/scoped_observation.h" @@ -28,6 +29,10 @@ using ObserverDoneCallback = base::RepeatingCallback<void(base::CheckedObserver*)>; +// The distance a launched window is offset (down and to the right) in order to +// not exactly overlap an existing window. +constexpr int kWindowOffset = 10; + // The next activation index to assign to an admin template window. int32_t g_admin_template_next_activation_index = kAdminTemplateStartingActivationIndex; @@ -49,6 +54,30 @@ } } +// This function updates the window bounds of the windows identified by `rwids` +// in `saved_desk` such that none of them exactly overlap +// `existing_bounds`. +void UpdateWindowBounds(DeskTemplate& saved_desk, + const gfx::Rect& work_area, + std::vector<gfx::Rect> existing_bounds, + const std::vector<int32_t>& rwids) { + auto& app_id_to_launch_list = + saved_desk.mutable_desk_restore_data()->mutable_app_id_to_launch_list(); + + for (auto& [app_id, launch_list] : app_id_to_launch_list) { + for (auto& [window_id, app_restore_data] : base::Reversed(launch_list)) { + CHECK(app_restore_data->current_bounds.has_value()); + + AdjustAdminTemplateWindowBounds(work_area, existing_bounds, + *app_restore_data->current_bounds); + + // Append to existing bounds so that a later window doesn't end up exactly + // matching. + existing_bounds.push_back(*app_restore_data->current_bounds); + } + } +} + // Holds a pair of restore window identifiers. struct WindowIdPair { // The RWID as it occurs in the original template. @@ -195,6 +224,27 @@ return true; } +void AdjustAdminTemplateWindowBounds( + const gfx::Rect& work_area, + const std::vector<gfx::Rect>& existing_bounds, + gfx::Rect& bounds) { + bounds.AdjustToFit(work_area); + + while (base::Contains(existing_bounds, bounds)) { + // There's an exact match for bounds, so we need to adjust it. We move it + // down and to the right, while staying within the work area. + int xoffset = std::min(kWindowOffset, work_area.right() - bounds.right()); + int yoffset = std::min(kWindowOffset, work_area.bottom() - bounds.bottom()); + + // If we're unable to adjust further, then so be it. + if (xoffset == 0 && yoffset == 0) { + break; + } + + bounds.Offset(xoffset, yoffset); + } +} + AdminTemplateLaunchTracker::AdminTemplateLaunchTracker( std::unique_ptr<DeskTemplate> admin_template, base::RepeatingCallback<void(const DeskTemplate&)> template_update_cb) @@ -270,6 +320,24 @@ aura::Window* container = desks_controller->active_desk()->GetDeskContainerForRoot(root); + std::vector<gfx::Rect> existing_window_bounds; + for (aura::Window* child : container->children()) { + // This window has been launched from a template. + if (child->GetProperty(app_restore::kRestoreWindowIdKey) < -1) { + existing_window_bounds.push_back(child->bounds()); + } + } + + std::vector<int32_t> unique_rwids; + for (const auto& pair : rwids) { + unique_rwids.push_back(pair.unique_rwid); + } + + WorkAreaInsets* work_area_insets = WorkAreaInsets::ForWindow(root); + UpdateWindowBounds(*admin_template, + work_area_insets->user_work_area_bounds(), + std::move(existing_window_bounds), unique_rwids); + window_observers_.push_back(std::make_unique<AdminTemplateDeskObserver>( update_cb, created_cb, done_cb, container, std::move(rwids))); }
diff --git a/ash/wm/desks/templates/admin_template_launch_tracker.h b/ash/wm/desks/templates/admin_template_launch_tracker.h index c0851de..43c93ca6 100644 --- a/ash/wm/desks/templates/admin_template_launch_tracker.h +++ b/ash/wm/desks/templates/admin_template_launch_tracker.h
@@ -41,6 +41,15 @@ DeskTemplate& admin_template, const AdminTemplateWindowUpdate& update); +// Figures out where to place an admin template window. The passed `bounds` is +// first adjusted to fit inside `work_area` (note that this may change the +// size). It is then placed, if possible, so that it does not overlap exactly +// with any of the bounds in `existing_bounds`. +ASH_EXPORT void AdjustAdminTemplateWindowBounds( + const gfx::Rect& work_area, + const std::vector<gfx::Rect>& existing_bounds, + gfx::Rect& bounds); + // This class is used to launch an admin template and track the windows that // have been launched from it. class ASH_EXPORT AdminTemplateLaunchTracker {
diff --git a/ash/wm/desks/templates/admin_template_unittest.cc b/ash/wm/desks/templates/admin_template_unittest.cc index ac7855b..21848534 100644 --- a/ash/wm/desks/templates/admin_template_unittest.cc +++ b/ash/wm/desks/templates/admin_template_unittest.cc
@@ -138,6 +138,63 @@ EXPECT_THAT(app_restore_data->display_id, Optional(123456)); } +TEST_F(AdminTemplateTest, AdjustAdminTemplateWindowBounds) { + // Simulates 800x600, but with a 50 pixel inset at top. + const gfx::Rect work_area(0, 50, 800, 550); + + struct TestCase { + const char* name; + // The input bounds. + gfx::Rect bounds; + // Existing bounds. + std::vector<gfx::Rect> existing; + // Expected output bounds. + gfx::Rect expected; + }; + + const TestCase tests[] = { + {.name = "Not adjusted", + .bounds = gfx::Rect(100, 100, 640, 480), + .existing = {}, + .expected = gfx::Rect(100, 100, 640, 480)}, + {.name = "Adjusted to fit work area", + .bounds = gfx::Rect(0, 0, 640, 480), + .existing = {}, + .expected = gfx::Rect(0, 50, 640, 480)}, + {.name = "Existing, but no overlap", + .bounds = gfx::Rect(100, 100, 640, 480), + .existing = {gfx::Rect(20, 50, 640, 480)}, + .expected = gfx::Rect(100, 100, 640, 480)}, + {.name = "Existing, with exact overlap", + .bounds = gfx::Rect(100, 100, 640, 480), + .existing = {gfx::Rect(100, 100, 640, 480)}, + .expected = gfx::Rect(110, 110, 640, 480)}, + {.name = "Existing, adjusted multiple times", + .bounds = gfx::Rect(100, 100, 640, 480), + .existing = {gfx::Rect(100, 100, 640, 480), + gfx::Rect(110, 110, 640, 480)}, + .expected = gfx::Rect(120, 120, 640, 480)}, + {.name = "Existing, adjustment clamped in the x direction", + .bounds = gfx::Rect(155, 100, 640, 480), + .existing = {gfx::Rect(155, 100, 640, 480)}, + .expected = gfx::Rect(160, 110, 640, 480)}, + {.name = "Existing, adjustment clamped in the y direction", + .bounds = gfx::Rect(100, 115, 640, 480), + .existing = {gfx::Rect(100, 115, 640, 480)}, + .expected = gfx::Rect(110, 120, 640, 480)}, + {.name = "Existing, adjustment not possible", + .bounds = gfx::Rect(160, 120, 640, 480), + .existing = {gfx::Rect(160, 120, 640, 480)}, + .expected = gfx::Rect(160, 120, 640, 480)}}; + + for (const TestCase& test : tests) { + SCOPED_TRACE(test.name); + gfx::Rect bounds = test.bounds; + AdjustAdminTemplateWindowBounds(work_area, test.existing, bounds); + EXPECT_EQ(bounds, test.expected); + } +} + TEST_F(AdminTemplateTest, LaunchTemplate) { auto admin_template = CreateTemplateFromJson(kAdminTemplateJson); ASSERT_TRUE(admin_template);
diff --git a/ash/wm/float/float_controller_unittest.cc b/ash/wm/float/float_controller_unittest.cc index fb6fac4..e6055b2d 100644 --- a/ash/wm/float/float_controller_unittest.cc +++ b/ash/wm/float/float_controller_unittest.cc
@@ -173,7 +173,7 @@ std::unique_ptr<aura::Window> CreateFloatedWindow() { std::unique_ptr<aura::Window> floated_window = CreateAppWindow(); PressAndReleaseKey(ui::VKEY_F, ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN); - DCHECK(WindowState::Get(floated_window.get())->IsFloated()); + CHECK(WindowState::Get(floated_window.get())->IsFloated()); return floated_window; } @@ -849,6 +849,17 @@ EXPECT_TRUE(floated_window->IsVisible()); } +// Tests that there is no crash when trying to float an always on top window. +// Regression test for b/279366443. +TEST_F(WindowFloatTest, AlwaysOnTopWindow) { + std::unique_ptr<aura::Window> always_on_top_window = CreateAppWindow(); + always_on_top_window->SetProperty(aura::client::kZOrderingKey, + ui::ZOrderLevel::kFloatingWindow); + + PressAndReleaseKey(ui::VKEY_F, ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN); + EXPECT_FALSE(WindowState::Get(always_on_top_window.get())->IsFloated()); +} + // A test class that uses a mock time test environment. class WindowFloatMetricsTest : public WindowFloatTest { public:
diff --git a/ash/wm/tablet_mode/tablet_mode_multitask_menu.cc b/ash/wm/tablet_mode/tablet_mode_multitask_menu.cc index fb83207..250de65 100644 --- a/ash/wm/tablet_mode/tablet_mode_multitask_menu.cc +++ b/ash/wm/tablet_mode/tablet_mode_multitask_menu.cc
@@ -203,10 +203,8 @@ TabletModeMultitaskMenu::TabletModeMultitaskMenu( TabletModeMultitaskMenuEventHandler* event_handler, aura::Window* window) - : event_handler_(event_handler), window_(window) { - // Start observing the window. - DCHECK(window); - observed_window_.Observe(window); + : event_handler_(event_handler) { + CHECK(window); views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP); params.opacity = views::Widget::InitParams::WindowOpacity::kTranslucent; @@ -233,12 +231,12 @@ menu_view_ = widget_->SetContentsView(std::make_unique<TabletModeMultitaskMenuView>( - window_, base::BindRepeating(&TabletModeMultitaskMenu::AnimateFadeOut, - weak_factory_.GetWeakPtr()))); + window, base::BindRepeating(&TabletModeMultitaskMenu::AnimateFadeOut, + weak_factory_.GetWeakPtr()))); // Set the widget on the top center of the window. const gfx::Size menu_size(menu_view_->GetPreferredSize()); - const gfx::Rect window_bounds(window_->GetBoundsInScreen()); + const gfx::Rect window_bounds(window->GetBoundsInScreen()); // The invisible widget needs to be big enough to include both the menu and // shadow otherwise it would mask parts out. Explicitly set the widget size @@ -278,10 +276,12 @@ if (view_layer->GetAnimator()->is_animating()) { return; } + if (show) { RecordMultitaskMenuEntryType( chromeos::MultitaskMenuEntryType::kGestureScroll); } + views::AnimationBuilder() .OnEnded(show ? base::DoNothing() : base::BindRepeating(&TabletModeMultitaskMenu::Reset, @@ -300,8 +300,14 @@ void TabletModeMultitaskMenu::AnimateFadeOut() { ui::Layer* view_layer = menu_view_->layer(); - if (view_layer->GetAnimator()->is_animating()) + // If the fade out animation is already underway, no need to start another + // one. This can happen for example if buttons are clicked rapidly while fade + // out has started. + if (view_layer->GetAnimator()->is_animating() && + view_layer->GetTargetOpacity() == 0.0f) { return; + } + views::AnimationBuilder() .OnEnded(base::BindRepeating(&TabletModeMultitaskMenu::Reset, weak_factory_.GetWeakPtr())) @@ -353,16 +359,6 @@ event_handler_->ResetMultitaskMenu(); } -void TabletModeMultitaskMenu::OnWindowDestroying(aura::Window* window) { - DCHECK(observed_window_.IsObservingSource(window)); - - observed_window_.Reset(); - window_ = nullptr; - - // Destroys `this`. - Reset(); -} - void TabletModeMultitaskMenu::OnNativeFocusChanged( gfx::NativeView focused_now) { if (widget_->GetNativeView() != focused_now) {
diff --git a/ash/wm/tablet_mode/tablet_mode_multitask_menu.h b/ash/wm/tablet_mode/tablet_mode_multitask_menu.h index aac16ae..9ab29b27 100644 --- a/ash/wm/tablet_mode/tablet_mode_multitask_menu.h +++ b/ash/wm/tablet_mode/tablet_mode_multitask_menu.h
@@ -8,7 +8,6 @@ #include "ash/ash_export.h" #include "ash/wm/tablet_mode/tablet_mode_multitask_menu_event_handler.h" #include "base/memory/raw_ptr.h" -#include "base/scoped_observation.h" #include "ui/aura/window.h" #include "ui/display/display_observer.h" #include "ui/views/focus/widget_focus_manager.h" @@ -26,8 +25,7 @@ // Creates and maintains the multitask menu. Responsible for showing, // hiding, and animating the menu. class ASH_EXPORT TabletModeMultitaskMenu - : public aura::WindowObserver, - public views::WidgetFocusChangeListener, + : public views::WidgetFocusChangeListener, public display::DisplayObserver { public: TabletModeMultitaskMenu(TabletModeMultitaskMenuEventHandler* event_handler, @@ -38,8 +36,6 @@ ~TabletModeMultitaskMenu() override; - aura::Window* window() { return window_; } - views::Widget* widget() { return widget_.get(); } // Performs a slide down animation on the menu if `show` is true, otherwise @@ -60,9 +56,6 @@ // Calls the event handler to destroy `this`. void Reset(); - // aura::WindowObserver: - void OnWindowDestroying(aura::Window* window) override; - // views::WidgetFocusChangeListener: void OnNativeFocusChanged(gfx::NativeView focused_now) override; @@ -77,9 +70,6 @@ // `this`. raw_ptr<TabletModeMultitaskMenuEventHandler, ExperimentalAsh> event_handler_; - // The window that opened this multitask menu. - raw_ptr<aura::Window, ExperimentalAsh> window_ = nullptr; - // Widget implementation that is created and maintained by `this`. views::UniqueWidgetPtr widget_ = std::make_unique<views::Widget>(); @@ -89,10 +79,6 @@ // Initial y location in `window_` coordinates. Only relevant for drags. float initial_y_; - // Window observer for `window_`. - base::ScopedObservation<aura::Window, aura::WindowObserver> observed_window_{ - this}; - display::ScopedOptionalDisplayObserver display_observer_{this}; base::WeakPtrFactory<TabletModeMultitaskMenu> weak_factory_{this};
diff --git a/ash/wm/tablet_mode/tablet_mode_multitask_menu_event_handler_unittest.cc b/ash/wm/tablet_mode/tablet_mode_multitask_menu_event_handler_unittest.cc index e3e18e97..387539f 100644 --- a/ash/wm/tablet_mode/tablet_mode_multitask_menu_event_handler_unittest.cc +++ b/ash/wm/tablet_mode/tablet_mode_multitask_menu_event_handler_unittest.cc
@@ -6,6 +6,7 @@ #include <memory> +#include "ash/accelerators/accelerator_controller_impl.h" #include "ash/display/screen_orientation_controller_test_api.h" #include "ash/shell.h" #include "ash/test/ash_test_base.h" @@ -696,4 +697,14 @@ TabletModeControllerTestApi().LeaveTabletMode(); } +TEST_F(TabletModeMultitaskMenuEventHandlerTest, HidesWhenMinimized) { + auto window = CreateAppWindow(); + ShowMultitaskMenu(*window); + + Shell::Get()->accelerator_controller()->PerformActionIfEnabled( + WINDOW_MINIMIZE, {}); + ASSERT_TRUE(WindowState::Get(window.get())->IsMinimized()); + EXPECT_FALSE(GetMultitaskMenu()); +} + } // namespace ash
diff --git a/base/critical_closure.h b/base/critical_closure.h index d2673de3..7e3369e 100644 --- a/base/critical_closure.h +++ b/base/critical_closure.h
@@ -82,6 +82,10 @@ inline OnceClosure MakeCriticalClosure(StringPiece task_name, OnceClosure closure, bool is_immediate) { + // Wrapping a null closure in a critical closure has unclear semantics and + // most likely indicates a bug. CHECK-ing early allows detecting and + // investigating these cases more easily. + CHECK(!closure.is_null()); if (is_immediate) { return base::BindOnce(&internal::ImmediateCriticalClosure::Run, Owned(new internal::ImmediateCriticalClosure(
diff --git a/base/critical_closure_internal_ios.mm b/base/critical_closure_internal_ios.mm index 736caca8..859a3a63 100644 --- a/base/critical_closure_internal_ios.mm +++ b/base/critical_closure_internal_ios.mm
@@ -11,21 +11,27 @@ ImmediateCriticalClosure::ImmediateCriticalClosure(StringPiece task_name, OnceClosure closure) - : critical_action_(task_name), closure_(std::move(closure)) {} + : critical_action_(task_name), closure_(std::move(closure)) { + CHECK(!closure_.is_null()); +} ImmediateCriticalClosure::~ImmediateCriticalClosure() {} void ImmediateCriticalClosure::Run() { + CHECK(!closure_.is_null()); std::move(closure_).Run(); } PendingCriticalClosure::PendingCriticalClosure(StringPiece task_name, OnceClosure closure) - : task_name_(task_name), closure_(std::move(closure)) {} + : task_name_(task_name), closure_(std::move(closure)) { + CHECK(!closure_.is_null()); +} PendingCriticalClosure::~PendingCriticalClosure() {} void PendingCriticalClosure::Run() { + CHECK(!closure_.is_null()); critical_action_.emplace(task_name_); std::move(closure_).Run(); }
diff --git a/base/functional/callback.h b/base/functional/callback.h index 189259f..773662e 100644 --- a/base/functional/callback.h +++ b/base/functional/callback.h
@@ -165,7 +165,7 @@ template <typename ThenR, typename... ThenArgs> OnceCallback<ThenR(Args...)> Then(OnceCallback<ThenR(ThenArgs...)> then) && { CHECK(then); - return BindOnce( + return base::BindOnce( internal::ThenHelper< OnceCallback, OnceCallback<ThenR(ThenArgs...)>>::CreateTrampoline(), std::move(*this), std::move(then)); @@ -178,7 +178,7 @@ OnceCallback<ThenR(Args...)> Then( RepeatingCallback<ThenR(ThenArgs...)> then) && { CHECK(then); - return BindOnce( + return base::BindOnce( internal::ThenHelper< OnceCallback, RepeatingCallback<ThenR(ThenArgs...)>>::CreateTrampoline(),
diff --git a/build/android/gyp/compile_java.py b/build/android/gyp/compile_java.py index 69b8909..5fee0d7 100755 --- a/build/android/gyp/compile_java.py +++ b/build/android/gyp/compile_java.py
@@ -461,15 +461,23 @@ # Compiles with Error Prone take twice as long to run as pure javac. Thus GN # rules run both in parallel, with Error Prone only used for checks. - _RunCompiler(changes, - options, - javac_cmd + javac_args, - java_files, - options.jar_path, - kt_files=kt_files, - jar_info_path=jar_info_path, - intermediates_out_dir=intermediates_out_dir, - enable_partial_javac=True) + try: + _RunCompiler(changes, + options, + javac_cmd + javac_args, + java_files, + options.jar_path, + kt_files=kt_files, + jar_info_path=jar_info_path, + intermediates_out_dir=intermediates_out_dir, + enable_partial_javac=True) + except build_utils.CalledProcessError as e: + # Do not output stacktrace as it takes up space on gerrit UI, forcing + # you to click though to find the actual compilation error. It's never + # interesting to see the Python stacktrace for a Java compilation error. + sys.stderr.write(e.output) + sys.exit(1) + logging.info('Completed all steps in _OnStaleMd5')
diff --git a/build/android/gyp/turbine.py b/build/android/gyp/turbine.py index 00aa310..2de92f47 100755 --- a/build/android/gyp/turbine.py +++ b/build/android/gyp/turbine.py
@@ -135,11 +135,18 @@ logging.debug('Command: %s', cmd) start = time.time() - build_utils.CheckOutput(cmd, - print_stdout=True, - stdout_filter=process_javac_output_partial, - stderr_filter=process_javac_output_partial, - fail_on_output=options.warnings_as_errors) + try: + build_utils.CheckOutput(cmd, + print_stdout=True, + stdout_filter=process_javac_output_partial, + stderr_filter=process_javac_output_partial, + fail_on_output=options.warnings_as_errors) + except build_utils.CalledProcessError as e: + # Do not output stacktrace as it takes up space on gerrit UI, forcing + # you to click though to find the actual compilation error. It's never + # interesting to see the Python stacktrace for a Java compilation error. + sys.stderr.write(e.output) + sys.exit(1) end = time.time() - start logging.info('Header compilation took %ss', end) if options.kotlin_jar_path:
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni index 66ac5f96..a3eccbf 100644 --- a/build/config/android/rules.gni +++ b/build/config/android/rules.gni
@@ -1651,7 +1651,7 @@ "//third_party/robolectric:robolectric_runtime_jars", ] if (defined(invoker.shared_libraries)) { - deps += invoker.shared_libraries + data_deps = invoker.shared_libraries } # Add non-libary deps, since the __host target does not depend on them.
diff --git a/build/fuchsia/linux_internal.sdk.sha1 b/build/fuchsia/linux_internal.sdk.sha1 index 567ea3fd..c9e790a 100644 --- a/build/fuchsia/linux_internal.sdk.sha1 +++ b/build/fuchsia/linux_internal.sdk.sha1
@@ -1 +1 @@ -12.20230423.3.1 +12.20230424.2.1
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 209dd22..4303452 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -517,6 +517,7 @@ "//mojo/public/java/system:system_impl_java", "//mojo/public/mojom/base:base_java", "//net/android:net_java", + "//services/audio/public/java:audio_feature_list_java", "//services/data_decoder/public/cpp/android:safe_json_java", "//services/device/public/java:device_feature_list_java", "//services/device/public/mojom:mojom_java", @@ -793,8 +794,6 @@ # This target OOMs with the default 1G (also OOMS with 2G). max_heap_size = "4G" - data_deps = [ "//testing/buildbot/filters:chrome_junit_tests_filters" ] - package_name = chrome_public_manifest_package # From java_sources.gni. @@ -1504,6 +1503,8 @@ "//chrome/browser/touch_to_fill/payments/android/internal:java_resources", "//chrome/browser/ui/android/appmenu:java", "//chrome/browser/ui/android/appmenu/test:test_support_java", + "//chrome/browser/ui/android/device_lock:java", + "//chrome/browser/ui/android/device_lock:java_resources", "//chrome/browser/ui/android/device_lock:javatests", "//chrome/browser/ui/android/favicon:java", "//chrome/browser/ui/android/layouts:java",
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkBridge.java index 87a4bad..d7face60 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkBridge.java
@@ -205,19 +205,19 @@ /*isManaged=*/false, /*dateAdded=*/0L, /*read=*/false); } - return BookmarkBridgeJni.get().getBookmarkByID( + return BookmarkBridgeJni.get().getBookmarkById( mNativeBookmarkBridge, BookmarkBridge.this, id.getId(), id.getType()); } /** * @return The top level folder's parents. */ - public List<BookmarkId> getTopLevelFolderParentIDs() { + public List<BookmarkId> getTopLevelFolderParentIds() { ThreadUtils.assertOnUiThread(); if (mNativeBookmarkBridge == 0) return new ArrayList<>(); assert mIsNativeBookmarkModelLoaded; List<BookmarkId> result = new ArrayList<>(); - BookmarkBridgeJni.get().getTopLevelFolderParentIDs( + BookmarkBridgeJni.get().getTopLevelFolderParentIds( mNativeBookmarkBridge, BookmarkBridge.this, result); return result; } @@ -228,12 +228,12 @@ * @return The top level folders. Note that special folders come first and normal top folders * will be in the alphabetical order. */ - public List<BookmarkId> getTopLevelFolderIDs(boolean getSpecial, boolean getNormal) { + public List<BookmarkId> getTopLevelFolderIds(boolean getSpecial, boolean getNormal) { ThreadUtils.assertOnUiThread(); if (mNativeBookmarkBridge == 0) return new ArrayList<>(); assert mIsNativeBookmarkModelLoaded; List<BookmarkId> result = new ArrayList<>(); - BookmarkBridgeJni.get().getTopLevelFolderIDs( + BookmarkBridgeJni.get().getTopLevelFolderIds( mNativeBookmarkBridge, BookmarkBridge.this, getSpecial, getNormal, result); return result; } @@ -380,12 +380,17 @@ mNativeBookmarkBridge, BookmarkBridge.this, id.getId(), id.getType()); } + /** TODO(https://crbug.com/1435552): Delete this method. */ + public List<BookmarkId> getChildIDs(BookmarkId id) { + return getChildIds(id); + } + /** * Reads sub-folder IDs, sub-bookmark IDs, or both of the given folder. * * @return Child IDs of the given folder, with the specified type. */ - public List<BookmarkId> getChildIDs(BookmarkId id) { + public List<BookmarkId> getChildIds(BookmarkId id) { ThreadUtils.assertOnUiThread(); if (mNativeBookmarkBridge == 0) return new ArrayList<>(); assert mIsNativeBookmarkModelLoaded; @@ -393,7 +398,7 @@ return searchBookmarks("", null, PowerBookmarkType.SHOPPING, -1); } List<BookmarkId> result = new ArrayList<>(); - BookmarkBridgeJni.get().getChildIDs( + BookmarkBridgeJni.get().getChildIds( mNativeBookmarkBridge, BookmarkBridge.this, id.getId(), id.getType(), result); return result; } @@ -924,11 +929,11 @@ BookmarkModel getForProfile(Profile profile); BookmarkId getBookmarkIdForWebContents(long nativeBookmarkBridge, BookmarkBridge caller, WebContents webContents, boolean onlyEditable); - BookmarkItem getBookmarkByID( + BookmarkItem getBookmarkById( long nativeBookmarkBridge, BookmarkBridge caller, long id, int type); - void getTopLevelFolderParentIDs( + void getTopLevelFolderParentIds( long nativeBookmarkBridge, BookmarkBridge caller, List<BookmarkId> bookmarksList); - void getTopLevelFolderIDs(long nativeBookmarkBridge, BookmarkBridge caller, + void getTopLevelFolderIds(long nativeBookmarkBridge, BookmarkBridge caller, boolean getSpecial, boolean getNormal, List<BookmarkId> bookmarksList); BookmarkId getReadingListFolder(long nativeBookmarkBridge, BookmarkBridge caller); void getAllFoldersWithDepths(long nativeBookmarkBridge, BookmarkBridge caller, @@ -941,7 +946,7 @@ String getBookmarkGuidByIdForTesting( long nativeBookmarkBridge, BookmarkBridge caller, long id, int type); int getChildCount(long nativeBookmarkBridge, BookmarkBridge caller, long id, int type); - void getChildIDs(long nativeBookmarkBridge, BookmarkBridge caller, long id, int type, + void getChildIds(long nativeBookmarkBridge, BookmarkBridge caller, long id, int type, List<BookmarkId> bookmarksList); BookmarkId getChildAt( long nativeBookmarkBridge, BookmarkBridge caller, long id, int type, int index);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerMediator.java index bb2e1c3..f1be2d2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerMediator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerMediator.java
@@ -125,7 +125,7 @@ // bookmarks mode. if (getCurrentUiMode() == BookmarkUiMode.FOLDER && node.getId().equals(mStateStack.peek().mFolder)) { - if (mBookmarkModel.getTopLevelFolderIDs(true, true).contains(node.getId())) { + if (mBookmarkModel.getTopLevelFolderIds(true, true).contains(node.getId())) { openFolder(mBookmarkModel.getDefaultFolderViewLocation()); } else { openFolder(parent.getId()); @@ -819,7 +819,7 @@ if (parentId.equals(mBookmarkModel.getRootFolderId())) { childIdList = mTopLevelFolders; } else { - childIdList = mBookmarkModel.getChildIDs(parentId); + childIdList = mBookmarkModel.getChildIds(parentId); } final List<BookmarkListEntry> bookmarkListEntries = new ArrayList<>();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkModel.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkModel.java index 4724605..8d6e860 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkModel.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkModel.java
@@ -136,7 +136,7 @@ */ public int getUnreadCount(@NonNull BookmarkId bookmarkId) { assert bookmarkId.getType() == BookmarkType.READING_LIST; - List<BookmarkId> children = getChildIDs(bookmarkId); + List<BookmarkId> children = getChildIds(bookmarkId); int unreadCount = 0; for (BookmarkId child : children) { BookmarkItem childItem = getBookmarkById(child);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkToolbarMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkToolbarMediator.java index 1b12e91c..25356e5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkToolbarMediator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkToolbarMediator.java
@@ -235,7 +235,7 @@ } else if (folder.equals(BookmarkId.SHOPPING_FOLDER)) { title = res.getString(R.string.price_tracking_bookmarks_filter_title); navigationButton = NavigationButton.BACK; - } else if (mBookmarkModel.getTopLevelFolderParentIDs().contains(folderItem.getParentId()) + } else if (mBookmarkModel.getTopLevelFolderParentIds().contains(folderItem.getParentId()) && TextUtils.isEmpty(folderItem.getTitle())) { title = res.getString(R.string.bookmarks); navigationButton = NavigationButton.BACK;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUtils.java index c4cc70b..6d0f190 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUtils.java
@@ -572,7 +572,7 @@ BookmarkId othersNodeId = bookmarkModel.getOtherFolderId(); List<BookmarkId> specialFoldersIds = - bookmarkModel.getTopLevelFolderIDs(/*getSpecial=*/true, /*getNormal=*/false); + bookmarkModel.getTopLevelFolderIds(/*getSpecial=*/true, /*getNormal=*/false); BookmarkId rootFolder = bookmarkModel.getRootFolderId(); // managed and partner bookmark folders will be put to the bottom.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkTagChipList.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkTagChipList.java index dd5092d..8b649537 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkTagChipList.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkTagChipList.java
@@ -86,7 +86,7 @@ private void populateChipsForCurrentFolder() { mTagMap.clear(); mChipList.clear(); - for (BookmarkId id : mBookmarkModel.getChildIDs(mCurrentFolder)) { + for (BookmarkId id : mBookmarkModel.getChildIds(mCurrentFolder)) { BookmarkItem item = mBookmarkModel.getBookmarkById(id); // TODO(crbug.com/1247825): Call #populateChipsForPowerBookmarkMeta will bookmark // metadata once available.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java index 6644b49..f37831e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java
@@ -33,6 +33,7 @@ import org.chromium.chrome.browser.signin.services.FREMobileIdentityConsistencyFieldTrial; import org.chromium.components.browser_ui.modaldialog.AppModalPresenter; import org.chromium.components.metrics.LowEntropySource; +import org.chromium.ui.base.ActivityWindowAndroid; import org.chromium.ui.base.LocalizationUtils; import org.chromium.ui.modaldialog.ModalDialogManager; import org.chromium.ui.modaldialog.ModalDialogManager.ModalDialogType; @@ -601,4 +602,10 @@ assert sObserver == null; sObserver = observer; } + + @Override + protected ActivityWindowAndroid createWindowAndroid() { + return new ActivityWindowAndroid( + this, /* listenToActivityState= */ true, getIntentRequestTracker()); + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunPageDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunPageDelegate.java index 617b8dca..7af5a94 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunPageDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunPageDelegate.java
@@ -8,6 +8,7 @@ import org.chromium.base.Promise; import org.chromium.base.supplier.OneshotSupplier; +import org.chromium.ui.base.WindowAndroid; /** * Defines the host interface for First Run Experience pages. @@ -106,4 +107,9 @@ * FRE is shown in a dialog. */ boolean canUseLandscapeLayout(); + + /** + * Return the {@link WindowAndroid} for the FirstRunActivity. + */ + WindowAndroid getWindowAndroid(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFirstRunFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFirstRunFragment.java index 4d25f18..bdabf78 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFirstRunFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFirstRunFragment.java
@@ -32,6 +32,7 @@ import org.chromium.chrome.browser.firstrun.MobileFreProgress; import org.chromium.chrome.browser.firstrun.SkipTosDialogPolicyListener; import org.chromium.chrome.browser.privacy.settings.PrivacyPreferencesManagerImpl; +import org.chromium.chrome.browser.ui.device_lock.DeviceLockCoordinator; import org.chromium.chrome.browser.ui.signin.SigninUtils; import org.chromium.chrome.browser.ui.signin.fre.SigninFirstRunCoordinator; import org.chromium.chrome.browser.ui.signin.fre.SigninFirstRunView; @@ -42,16 +43,19 @@ /** * This fragment handles the sign-in without sync consent during the FRE. */ -public class SigninFirstRunFragment - extends Fragment implements FirstRunFragment, SigninFirstRunCoordinator.Delegate { +public class SigninFirstRunFragment extends Fragment implements FirstRunFragment, + SigninFirstRunCoordinator.Delegate, + DeviceLockCoordinator.Delegate { @VisibleForTesting static final int ADD_ACCOUNT_REQUEST_CODE = 1; // Used as a view holder for the current orientation of the device. private FrameLayout mFragmentView; + private View mMainView; private ModalDialogManager mModalDialogManager; private SkipTosDialogPolicyListener mSkipTosDialogPolicyListener; private SigninFirstRunCoordinator mSigninFirstRunCoordinator; + private DeviceLockCoordinator mDeviceLockCoordinator; private boolean mExitFirstRunCalled; public SigninFirstRunFragment() {} @@ -88,16 +92,18 @@ super.onConfigurationChanged(newConfig); // Inflate the view required for the current configuration and set it as the fragment view. mFragmentView.removeAllViews(); - mFragmentView.addView(inflateFragmentView( + mMainView = inflateFragmentView( (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE), - newConfig)); + newConfig); + mFragmentView.addView(mMainView); } @Override public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { mFragmentView = new FrameLayout(getActivity()); - mFragmentView.addView(inflateFragmentView(inflater, getResources().getConfiguration())); + mMainView = inflateFragmentView(inflater, getResources().getConfiguration()); + mFragmentView.addView(mMainView); return mFragmentView; } @@ -226,4 +232,33 @@ mSigninFirstRunCoordinator.setView(view); return view; } + + @Override + public void displayDeviceLockPage() { + mDeviceLockCoordinator = new DeviceLockCoordinator( + true, this, getPageDelegate().getWindowAndroid(), requireContext()); + } + + @Override + public void setView(View view) { + mFragmentView.removeAllViews(); + mFragmentView.addView(view); + } + + @Override + public void onDeviceLockReady() { + restoreMainView(); + mDeviceLockCoordinator = null; + mSigninFirstRunCoordinator.continueSignIn(); + } + + @Override + public void onDeviceLockRefused() { + mSigninFirstRunCoordinator.cancelSignInAndDismiss(); + } + + private void restoreMainView() { + mFragmentView.removeAllViews(); + mFragmentView.addView(mMainView); + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java index e1bcba82..49f1c94 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
@@ -768,6 +768,7 @@ @Override public void onCrash(Tab tab) { + mLocationBarModel.notifyOnCrash(); updateTabLoadingState(false); updateButtonStatus(); } @@ -786,6 +787,7 @@ @Override public void onContentChanged(Tab tab) { + mLocationBarModel.notifyContentChanged(); checkIfNtpLoaded(); mToolbar.onTabContentViewChanged(); maybeShowCursorInLocationBar(); @@ -797,6 +799,7 @@ @Override public void onWebContentsSwapped(Tab tab, boolean didStartLoad, boolean didFinishLoad) { if (!didStartLoad) return; + mLocationBarModel.notifyWebContentsSwapped(); mLocationBarModel.notifyUrlChanged(); onBackPressStateChanged(); mLocationBarModel.notifySecurityStateChanged(); @@ -842,6 +845,14 @@ ntp.setUrlFocusAnimationsDisabled(false); onTabOrModelChanged(); } + + mLocationBarModel.notifyDidFinishNavigation(navigation.isSameDocument()); + } + + @Override + public void onDidStartNavigationInPrimaryMainFrame( + Tab tab, NavigationHandle navigationHandle) { + mLocationBarModel.notifyDidStartNavigation(navigationHandle.isSameDocument()); } @Override @@ -1919,6 +1930,10 @@ * inheriting classes the chance to update the button visuals as well. */ private void updateButtonStatus() { + if (mLocationBarModel.shouldDoSameDocOptimzations()) { + return; + } + Tab currentTab = mLocationBarModel.getTab(); boolean tabCrashed = currentTab != null && SadTab.isShowing(currentTab);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/app/bookmarks/BookmarkTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/app/bookmarks/BookmarkTest.java index 515dc43b..f3b0ecf 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/app/bookmarks/BookmarkTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/app/bookmarks/BookmarkTest.java
@@ -10,11 +10,17 @@ import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist; import static androidx.test.espresso.matcher.ViewMatchers.withText; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.verify; import static org.chromium.components.browser_ui.widget.highlight.ViewHighlighterTestUtils.checkHighlightOff; import static org.chromium.components.browser_ui.widget.highlight.ViewHighlighterTestUtils.checkHighlightPulse; +import static org.chromium.content_public.browser.test.util.TestThreadUtils.runOnUiThreadBlocking; import android.text.TextUtils; import android.view.View; @@ -32,7 +38,6 @@ import org.hamcrest.Matchers; import org.junit.After; import org.junit.AfterClass; -import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Rule; @@ -179,7 +184,7 @@ @Before public void setUp() { mActivityTestRule.startMainActivityOnBlankPage(); - TestThreadUtils.runOnUiThreadBlocking(() -> { + runOnUiThreadBlocking(() -> { mBookmarkModel = mActivityTestRule.getActivity().getBookmarkModelForTesting(); SyncService.overrideForTests(mSyncService); }); @@ -206,22 +211,22 @@ public void testAddBookmark() throws Exception { mActivityTestRule.loadUrl(mTestPage); // Check partner bookmarks are lazily loaded. - Assert.assertFalse(mBookmarkModel.isBookmarkModelLoaded()); + assertFalse(mBookmarkModel.isBookmarkModelLoaded()); // Click star button to bookmark the current tab. MenuUtils.invokeCustomMenuActionSync(InstrumentationRegistry.getInstrumentation(), mActivityTestRule.getActivity(), R.id.bookmark_this_page_id); BookmarkTestUtil.waitForBookmarkModelLoaded(); // All actions with BookmarkModel needs to run on UI thread. - TestThreadUtils.runOnUiThreadBlocking(() -> { + runOnUiThreadBlocking(() -> { BookmarkId id = mBookmarkModel.getUserBookmarkIdForTab( mActivityTestRule.getActivity().getActivityTabProvider().get()); - Assert.assertTrue("The test page is not added as bookmark: ", + assertTrue("The test page is not added as bookmark: ", mBookmarkModel.doesBookmarkExist(id)); BookmarkItem item = mBookmarkModel.getBookmarkById(id); - Assert.assertEquals(mBookmarkModel.getDefaultFolder(), item.getParentId()); - Assert.assertEquals(mTestPage, item.getUrl()); - Assert.assertEquals(TEST_PAGE_TITLE_GOOGLE, item.getTitle()); + assertEquals(mBookmarkModel.getDefaultFolder(), item.getParentId()); + assertEquals(mTestPage, item.getUrl()); + assertEquals(TEST_PAGE_TITLE_GOOGLE, item.getTitle()); }); BookmarkTestUtil.waitForOfflinePageSaved(mTestPage); @@ -238,7 +243,7 @@ mActivityTestRule.loadUrl(mTestPage); BookmarkTestUtil.readPartnerBookmarks(mActivityTestRule); // Set default folder as "Other Folder". - TestThreadUtils.runOnUiThreadBlocking(() -> { + runOnUiThreadBlocking(() -> { SharedPreferencesManager.getInstance().writeString( ChromePreferenceKeys.BOOKMARKS_LAST_USED_PARENT, mBookmarkModel.getOtherFolderId().toString()); @@ -248,13 +253,13 @@ mActivityTestRule.getActivity(), R.id.bookmark_this_page_id); BookmarkTestUtil.waitForBookmarkModelLoaded(); // All actions with BookmarkModel needs to run on UI thread. - TestThreadUtils.runOnUiThreadBlocking(() -> { + runOnUiThreadBlocking(() -> { BookmarkId id = mBookmarkModel.getUserBookmarkIdForTab( mActivityTestRule.getActivity().getActivityTabProvider().get()); - Assert.assertTrue("The test page is not added as bookmark: ", + assertTrue("The test page is not added as bookmark: ", mBookmarkModel.doesBookmarkExist(id)); BookmarkItem item = mBookmarkModel.getBookmarkById(id); - Assert.assertEquals("Bookmark added in a wrong default folder.", + assertEquals("Bookmark added in a wrong default folder.", mBookmarkModel.getOtherFolderId(), item.getParentId()); }); } @@ -267,10 +272,10 @@ BookmarkTestUtil.openMobileBookmarks( mItemsContainer, getBookmarkDelegate(), mBookmarkModel); - Assert.assertTrue("Grid view does not contain added bookmark: ", + assertTrue("Grid view does not contain added bookmark: ", isItemPresentInBookmarkList(TEST_PAGE_TITLE_GOOGLE)); final View title = getViewWithText(mItemsContainer, TEST_PAGE_TITLE_GOOGLE); - TestThreadUtils.runOnUiThreadBlocking(() -> TouchCommon.singleClickView(title)); + runOnUiThreadBlocking(() -> TouchCommon.singleClickView(title)); ChromeTabbedActivity activity = BookmarkTestUtil.waitForTabbedActivity(); CriteriaHelper.pollUiThread(() -> { Tab activityTab = activity.getActivityTab(); @@ -284,15 +289,15 @@ @SmallTest public void testUrlComposition() { BookmarkTestUtil.readPartnerBookmarks(mActivityTestRule); - TestThreadUtils.runOnUiThreadBlocking(() -> { + runOnUiThreadBlocking(() -> { BookmarkId mobileId = mBookmarkModel.getMobileFolderId(); BookmarkId bookmarkBarId = mBookmarkModel.getDesktopFolderId(); BookmarkId otherId = mBookmarkModel.getOtherFolderId(); - Assert.assertEquals("chrome-native://bookmarks/folder/" + mobileId, + assertEquals("chrome-native://bookmarks/folder/" + mobileId, BookmarkUiState.createFolderUrl(mobileId).toString()); - Assert.assertEquals("chrome-native://bookmarks/folder/" + bookmarkBarId, + assertEquals("chrome-native://bookmarks/folder/" + bookmarkBarId, BookmarkUiState.createFolderUrl(bookmarkBarId).toString()); - Assert.assertEquals("chrome-native://bookmarks/folder/" + otherId, + assertEquals("chrome-native://bookmarks/folder/" + otherId, BookmarkUiState.createFolderUrl(otherId).toString()); }); } @@ -304,7 +309,7 @@ BookmarkTestUtil.loadEmptyPartnerBookmarksForTesting(mBookmarkModel); BookmarkTestUtil.waitForBookmarkModelLoaded(); - TestThreadUtils.runOnUiThreadBlocking(() -> { + runOnUiThreadBlocking(() -> { BookmarkUtils.showBookmarkManager(mActivityTestRule.getActivity(), mBookmarkModel.getMobileFolderId(), /*isIncognito=*/false); }); @@ -324,8 +329,8 @@ BookmarkTestUtil.waitForBookmarkModelLoaded(); - Assert.assertEquals(BookmarkUiMode.FOLDER, getBookmarkDelegate().getCurrentUiMode()); - Assert.assertEquals("chrome-native://bookmarks/folder/3", + assertEquals(BookmarkUiMode.FOLDER, getBookmarkDelegate().getCurrentUiMode()); + assertEquals("chrome-native://bookmarks/folder/3", BookmarkUtils.getLastUsedUrl(mActivityTestRule.getActivity())); } @@ -342,43 +347,43 @@ final BookmarkToolbar toolbar = mBookmarkManagerCoordinator.getToolbarForTesting(); // Check that we are in the mobile bookmarks folder. - Assert.assertEquals("Mobile bookmarks", toolbar.getTitle()); - Assert.assertEquals( + assertEquals("Mobile bookmarks", toolbar.getTitle()); + assertEquals( SelectableListToolbar.NavigationButton.BACK, toolbar.getNavigationButtonForTests()); - Assert.assertFalse(toolbar.getMenu().findItem(R.id.edit_menu_id).isVisible()); + assertFalse(toolbar.getMenu().findItem(R.id.edit_menu_id).isVisible()); // Open the new test folder. - TestThreadUtils.runOnUiThreadBlocking(() -> delegate.openFolder(testFolder)); + runOnUiThreadBlocking(() -> delegate.openFolder(testFolder)); // Check that we are in the editable test folder. - Assert.assertEquals(TEST_FOLDER_TITLE, toolbar.getTitle()); - Assert.assertEquals( + assertEquals(TEST_FOLDER_TITLE, toolbar.getTitle()); + assertEquals( SelectableListToolbar.NavigationButton.BACK, toolbar.getNavigationButtonForTests()); - Assert.assertTrue(toolbar.getMenu().findItem(R.id.edit_menu_id).isVisible()); + assertTrue(toolbar.getMenu().findItem(R.id.edit_menu_id).isVisible()); - TestThreadUtils.runOnUiThreadBlocking( + runOnUiThreadBlocking( () -> mBookmarkModel.setBookmarkTitle(testFolder, TEST_FOLDER_TITLE2)); // Check that the test folder reflects name changes. - Assert.assertEquals(TEST_FOLDER_TITLE2, toolbar.getTitle()); + assertEquals(TEST_FOLDER_TITLE2, toolbar.getTitle()); // Call BookmarkToolbar#onClick() to activate the navigation button. - TestThreadUtils.runOnUiThreadBlocking(() -> toolbar.onClick(toolbar)); + runOnUiThreadBlocking(() -> toolbar.onClick(toolbar)); // Check that we are back in the mobile folder - Assert.assertEquals("Mobile bookmarks", toolbar.getTitle()); - Assert.assertEquals( + assertEquals("Mobile bookmarks", toolbar.getTitle()); + assertEquals( SelectableListToolbar.NavigationButton.BACK, toolbar.getNavigationButtonForTests()); - Assert.assertFalse(toolbar.getMenu().findItem(R.id.edit_menu_id).isVisible()); + assertFalse(toolbar.getMenu().findItem(R.id.edit_menu_id).isVisible()); // Call BookmarkToolbar#onClick() to activate the navigation button. - TestThreadUtils.runOnUiThreadBlocking(() -> toolbar.onClick(toolbar)); + runOnUiThreadBlocking(() -> toolbar.onClick(toolbar)); // Check that we are in the root folder. - Assert.assertEquals("Bookmarks", toolbar.getTitle()); - Assert.assertEquals( + assertEquals("Bookmarks", toolbar.getTitle()); + assertEquals( SelectableListToolbar.NavigationButton.NONE, toolbar.getNavigationButtonForTests()); - Assert.assertFalse(toolbar.getMenu().findItem(R.id.edit_menu_id).isVisible()); + assertFalse(toolbar.getMenu().findItem(R.id.edit_menu_id).isVisible()); } // TODO(twellington): Write a folder navigation test for tablets that waits for the Tab hosting @@ -400,39 +405,37 @@ // Open the new folder where these bookmarks were created. openFolder(folder); - Assert.assertEquals(BookmarkUiMode.FOLDER, delegate.getCurrentUiMode()); - Assert.assertEquals( - "Wrong number of items before starting search.", 3, adapter.getItemCount()); + assertEquals(BookmarkUiMode.FOLDER, delegate.getCurrentUiMode()); + assertEquals("Wrong number of items before starting search.", 3, adapter.getItemCount()); - TestThreadUtils.runOnUiThreadBlocking(delegate::openSearchUi); + runOnUiThreadBlocking(delegate::openSearchUi); - Assert.assertEquals(BookmarkUiMode.SEARCHING, delegate.getCurrentUiMode()); - Assert.assertEquals( - "Wrong number of items after showing search UI. The promo should be hidden.", 2, - adapter.getItemCount()); + assertEquals(BookmarkUiMode.SEARCHING, delegate.getCurrentUiMode()); + assertEquals("Wrong number of items after showing search UI. The promo should be hidden.", + 2, adapter.getItemCount()); searchBookmarks("Google"); - Assert.assertEquals("Wrong number of items after searching.", 1, + assertEquals("Wrong number of items after searching.", 1, mItemsContainer.getAdapter().getItemCount()); BookmarkId newBookmark = addBookmark(TEST_PAGE_TITLE_GOOGLE2, mTestPage); - Assert.assertEquals("Wrong number of items after bookmark added while searching.", 2, + assertEquals("Wrong number of items after bookmark added while searching.", 2, mItemsContainer.getAdapter().getItemCount()); removeBookmark(newBookmark); - Assert.assertEquals("Wrong number of items after bookmark removed while searching.", 1, + assertEquals("Wrong number of items after bookmark removed while searching.", 1, mItemsContainer.getAdapter().getItemCount()); searchBookmarks("Non-existent page"); - Assert.assertEquals("Wrong number of items after searching for non-existent item.", 0, + assertEquals("Wrong number of items after searching for non-existent item.", 0, mItemsContainer.getAdapter().getItemCount()); - TestThreadUtils.runOnUiThreadBlocking( + runOnUiThreadBlocking( () -> mBookmarkManagerCoordinator.getToolbarForTesting().hideSearchView()); - Assert.assertEquals("Wrong number of items after closing search UI.", 3, + assertEquals("Wrong number of items after closing search UI.", 3, mItemsContainer.getAdapter().getItemCount()); - Assert.assertEquals(BookmarkUiMode.FOLDER, delegate.getCurrentUiMode()); - Assert.assertEquals( + assertEquals(BookmarkUiMode.FOLDER, delegate.getCurrentUiMode()); + assertEquals( TEST_FOLDER_TITLE, mBookmarkManagerCoordinator.getToolbarForTesting().getTitle()); } @@ -453,30 +456,28 @@ // Open the new folder where these bookmarks were created. openFolder(folder); - Assert.assertEquals(Boolean.TRUE, + assertEquals(Boolean.TRUE, mBookmarkManagerCoordinator.getHandleBackPressChangedSupplier().get()); - TestThreadUtils.runOnUiThreadBlocking(delegate::openSearchUi); + runOnUiThreadBlocking(delegate::openSearchUi); - Assert.assertEquals(BookmarkUiMode.SEARCHING, delegate.getCurrentUiMode()); - Assert.assertEquals( - "Wrong number of items after showing search UI. The promo should be hidden.", 2, - adapter.getItemCount()); + assertEquals(BookmarkUiMode.SEARCHING, delegate.getCurrentUiMode()); + assertEquals("Wrong number of items after showing search UI. The promo should be hidden.", + 2, adapter.getItemCount()); - Assert.assertEquals(Boolean.TRUE, + assertEquals(Boolean.TRUE, mBookmarkManagerCoordinator.getHandleBackPressChangedSupplier().get()); // Exit search UI. - TestThreadUtils.runOnUiThreadBlocking( - mBookmarkActivity.getOnBackPressedDispatcher()::onBackPressed); - Assert.assertNotEquals(BookmarkUiMode.SEARCHING, delegate.getCurrentUiMode()); + runOnUiThreadBlocking(mBookmarkActivity.getOnBackPressedDispatcher()::onBackPressed); + assertNotEquals(BookmarkUiMode.SEARCHING, delegate.getCurrentUiMode()); // Enter search UI again. - TestThreadUtils.runOnUiThreadBlocking(delegate::openSearchUi); + runOnUiThreadBlocking(delegate::openSearchUi); searchBookmarks("Google"); RecyclerViewTestUtils.waitForStableRecyclerView(mItemsContainer); - Assert.assertEquals("Wrong number of items after searching.", 1, + assertEquals("Wrong number of items after searching.", 1, mItemsContainer.getAdapter().getItemCount()); BookmarkRow itemView = @@ -488,33 +489,29 @@ CriteriaHelper.pollUiThread( itemView::isChecked, "Expected item \"test\" to become selected"); - TestThreadUtils.runOnUiThreadBlocking( - mBookmarkActivity.getOnBackPressedDispatcher()::onBackPressed); + runOnUiThreadBlocking(mBookmarkActivity.getOnBackPressedDispatcher()::onBackPressed); // Clear selection but still in search UI. CriteriaHelper.pollUiThread( () -> !itemView.isChecked(), "Expected item \"test\" to become not selected"); - Assert.assertEquals(BookmarkUiMode.SEARCHING, delegate.getCurrentUiMode()); - Assert.assertEquals(Boolean.TRUE, + assertEquals(BookmarkUiMode.SEARCHING, delegate.getCurrentUiMode()); + assertEquals(Boolean.TRUE, mBookmarkManagerCoordinator.getHandleBackPressChangedSupplier().get()); // Exit search UI. - TestThreadUtils.runOnUiThreadBlocking( - mBookmarkActivity.getOnBackPressedDispatcher()::onBackPressed); - Assert.assertEquals(BookmarkUiMode.FOLDER, delegate.getCurrentUiMode()); + runOnUiThreadBlocking(mBookmarkActivity.getOnBackPressedDispatcher()::onBackPressed); + assertEquals(BookmarkUiMode.FOLDER, delegate.getCurrentUiMode()); // Exit folder. - Assert.assertEquals(Boolean.TRUE, + assertEquals(Boolean.TRUE, mBookmarkManagerCoordinator.getHandleBackPressChangedSupplier().get()); - TestThreadUtils.runOnUiThreadBlocking( - mBookmarkActivity.getOnBackPressedDispatcher()::onBackPressed); - Assert.assertEquals(BookmarkUiMode.FOLDER, delegate.getCurrentUiMode()); + runOnUiThreadBlocking(mBookmarkActivity.getOnBackPressedDispatcher()::onBackPressed); + assertEquals(BookmarkUiMode.FOLDER, delegate.getCurrentUiMode()); // Exit bookmark activity. - Assert.assertEquals(Boolean.FALSE, + assertEquals(Boolean.FALSE, mBookmarkManagerCoordinator.getHandleBackPressChangedSupplier().get()); - TestThreadUtils.runOnUiThreadBlocking( - mBookmarkActivity.getOnBackPressedDispatcher()::onBackPressed); + runOnUiThreadBlocking(mBookmarkActivity.getOnBackPressedDispatcher()::onBackPressed); ApplicationTestUtils.waitForActivityState(mBookmarkActivity, Stage.DESTROYED); } @@ -536,13 +533,13 @@ BookmarkToolbar toolbar = mBookmarkManagerCoordinator.getToolbarForTesting(); View search_view = toolbar.findViewById(R.id.search_view); - TestThreadUtils.runOnUiThreadBlocking( + runOnUiThreadBlocking( () -> toolbar.onMenuItemClick(toolbar.getMenu().findItem(R.id.search_menu_id))); // Despite being in search mode, this is the initial query state, and the previous 1 // bookmark inside of testFolder should be shown. - Assert.assertEquals(search_view.getVisibility(), View.VISIBLE); - Assert.assertEquals(1, adapter.getItemCount()); + assertEquals(search_view.getVisibility(), View.VISIBLE); + assertEquals(1, adapter.getItemCount()); BookmarkRow itemView = (BookmarkRow) mBookmarkManagerCoordinator.getRecyclerViewForTesting() .findViewHolderForAdapterPosition(0) @@ -551,16 +548,16 @@ // Selecting an item should cause the search view to be hidden, replaced with menu items // that operate on the selected rows. - Assert.assertNotEquals(search_view.getVisibility(), View.VISIBLE); + assertNotEquals(search_view.getVisibility(), View.VISIBLE); - TestThreadUtils.runOnUiThreadBlocking(() -> { + runOnUiThreadBlocking(() -> { toolbar.onMenuItemClick(toolbar.getMenu().findItem(R.id.selection_mode_delete_menu_id)); }); // Should now be kicked back into an empty search string query, not the initial query. This // is why 3 items should now be visible, the two folders and the other url bookmark. - Assert.assertEquals(search_view.getVisibility(), View.VISIBLE); - Assert.assertEquals(3, adapter.getItemCount()); + assertEquals(search_view.getVisibility(), View.VISIBLE); + assertEquals(3, adapter.getItemCount()); } @Test @@ -578,25 +575,23 @@ // Open the new folder where these bookmarks were created. openFolder(testFolder); - Assert.assertEquals("Wrong state, should be in folder", BookmarkUiMode.FOLDER, + assertEquals("Wrong state, should be in folder", BookmarkUiMode.FOLDER, getBookmarkDelegate().getCurrentUiMode()); - Assert.assertEquals( - "Wrong number of items before starting search.", 3, adapter.getItemCount()); + assertEquals("Wrong number of items before starting search.", 3, adapter.getItemCount()); // Start searching without entering a query. This won't change the items displayed which // are currently testFolder's children (3). - TestThreadUtils.runOnUiThreadBlocking(getBookmarkDelegate()::openSearchUi); + runOnUiThreadBlocking(getBookmarkDelegate()::openSearchUi); RecyclerViewTestUtils.waitForStableRecyclerView(mItemsContainer); - Assert.assertEquals("Wrong state, should be searching", BookmarkUiMode.SEARCHING, + assertEquals("Wrong state, should be searching", BookmarkUiMode.SEARCHING, getBookmarkDelegate().getCurrentUiMode()); - Assert.assertEquals( - "Wrong number of items before starting search.", 3, adapter.getItemCount()); + assertEquals("Wrong number of items before starting search.", 3, adapter.getItemCount()); // Select testFolder2 and delete it. This deletion will refresh the current search, which // right now is the empty string. This will return all bookmarks (3). toggleSelectionAndEndAnimation(testFolder2, (BookmarkRow) mItemsContainer.findViewHolderForLayoutPosition(2).itemView); - TestThreadUtils.runOnUiThreadBlocking( + runOnUiThreadBlocking( () -> mBookmarkManagerCoordinator.getToolbarForTesting().onMenuItemClick( mBookmarkManagerCoordinator.getToolbarForTesting() @@ -604,12 +599,11 @@ .findItem(R.id.selection_mode_delete_menu_id))); // Should still be searching with the folder gone. - Assert.assertEquals( - "Wrong number of items.", 3, mItemsContainer.getAdapter().getItemCount()); + assertEquals("Wrong number of items.", 3, mItemsContainer.getAdapter().getItemCount()); // Start searching, enter a query. This query will match all remaining bookmarks (1). searchBookmarks("Google"); - Assert.assertEquals("Wrong number of items after searching.", 1, + assertEquals("Wrong number of items after searching.", 1, mItemsContainer.getAdapter().getItemCount()); // Remove the bookmark. @@ -617,20 +611,20 @@ // The user should still be searching, and the bookmark should be gone. We're refreshing // the search query again here, but in this case it's now "Google". - Assert.assertEquals("Wrong state, should be searching", BookmarkUiMode.SEARCHING, + assertEquals("Wrong state, should be searching", BookmarkUiMode.SEARCHING, getBookmarkDelegate().getCurrentUiMode()); - Assert.assertEquals("Wrong number of items after searching.", 0, + assertEquals("Wrong number of items after searching.", 0, mItemsContainer.getAdapter().getItemCount()); // Undo the deletion. - TestThreadUtils.runOnUiThreadBlocking( + runOnUiThreadBlocking( () -> mBookmarkManagerCoordinator.getUndoControllerForTesting().onAction(null)); // The user should still be searching, and the bookmark should reappear. Refreshing the // search yet again, now with the "Google" search matching returning 1 result. - Assert.assertEquals("Wrong state, should be searching", BookmarkUiMode.SEARCHING, + assertEquals("Wrong state, should be searching", BookmarkUiMode.SEARCHING, getBookmarkDelegate().getCurrentUiMode()); - Assert.assertEquals("Wrong number of items after searching.", 1, + assertEquals("Wrong number of items after searching.", 1, mItemsContainer.getAdapter().getItemCount()); } @@ -644,30 +638,30 @@ openBookmarkManager(); // Start searching, enter a query. - TestThreadUtils.runOnUiThreadBlocking(getBookmarkDelegate()::openSearchUi); - Assert.assertEquals("Wrong state, should be searching", BookmarkUiMode.SEARCHING, + runOnUiThreadBlocking(getBookmarkDelegate()::openSearchUi); + assertEquals("Wrong state, should be searching", BookmarkUiMode.SEARCHING, getBookmarkDelegate().getCurrentUiMode()); searchBookmarks("test"); - Assert.assertEquals("Wrong number of items after searching.", 2, + assertEquals("Wrong number of items after searching.", 2, mItemsContainer.getAdapter().getItemCount()); // Remove the bookmark. removeBookmark(testFolder); // The user should still be searching, and the bookmark should be gone. - Assert.assertEquals("Wrong state, should be searching", BookmarkUiMode.SEARCHING, + assertEquals("Wrong state, should be searching", BookmarkUiMode.SEARCHING, getBookmarkDelegate().getCurrentUiMode()); - Assert.assertEquals("Wrong number of items after searching.", 0, + assertEquals("Wrong number of items after searching.", 0, mItemsContainer.getAdapter().getItemCount()); // Undo the deletion. - TestThreadUtils.runOnUiThreadBlocking( + runOnUiThreadBlocking( () -> mBookmarkManagerCoordinator.getUndoControllerForTesting().onAction(null)); // The user should still be searching, and the bookmark should reappear. - Assert.assertEquals("Wrong state, should be searching", BookmarkUiMode.SEARCHING, + assertEquals("Wrong state, should be searching", BookmarkUiMode.SEARCHING, getBookmarkDelegate().getCurrentUiMode()); - Assert.assertEquals("Wrong number of items after searching.", 2, + assertEquals("Wrong number of items after searching.", 2, mItemsContainer.getAdapter().getItemCount()); } @@ -709,7 +703,7 @@ final BookmarkToolbar toolbar = mBookmarkManagerCoordinator.getToolbarForTesting(); - TestThreadUtils.runOnUiThreadBlocking( + runOnUiThreadBlocking( () -> toolbar.onMenuItemClick(toolbar.getMenu().findItem(R.id.close_menu_id))); ApplicationTestUtils.waitForActivityState(mBookmarkActivity, Stage.DESTROYED); @@ -726,7 +720,7 @@ openBookmarkManager(); BookmarkToolbar toolbar = mBookmarkManagerCoordinator.getToolbarForTesting(); - Assert.assertFalse(toolbar.getMenu().findItem(R.id.edit_menu_id).isVisible()); + assertFalse(toolbar.getMenu().findItem(R.id.edit_menu_id).isVisible()); BookmarkManagerCoordinator.preventLoadingForTesting(false); } @@ -758,25 +752,21 @@ // Callback occurs when Item "test" is selected. CriteriaHelper.pollUiThread(test::isChecked, "Expected item \"test\" to become selected"); - Assert.assertEquals("Expected bookmark toolbar to be selection mode", + assertEquals("Expected bookmark toolbar to be selection mode", mBookmarkManagerCoordinator.getToolbarForTesting().getCurrentViewType(), ViewType.SELECTION_VIEW); - Assert.assertEquals("Expected more button of selected item to be gone when drag is active.", + assertEquals("Expected more button of selected item to be gone when drag is active.", View.GONE, testMoreButton.getVisibility()); - Assert.assertEquals( - "Expected drag handle of selected item to be visible when drag is active.", + assertEquals("Expected drag handle of selected item to be visible when drag is active.", View.VISIBLE, testDragHandle.getVisibility()); - Assert.assertTrue("Expected drag handle to be enabled when drag is active.", + assertTrue("Expected drag handle to be enabled when drag is active.", testDragHandle.isEnabled()); - Assert.assertEquals( - "Expected more button of unselected item to be gone when drag is active.", + assertEquals("Expected more button of unselected item to be gone when drag is active.", View.GONE, aMoreButton.getVisibility()); - Assert.assertEquals( - "Expected drag handle of unselected item to be visible when drag is active.", + assertEquals("Expected drag handle of unselected item to be visible when drag is active.", View.VISIBLE, aDragHandle.getVisibility()); - Assert.assertFalse( - "Expected drag handle of unselected item to be disabled when drag is active.", + assertFalse("Expected drag handle of unselected item to be disabled when drag is active.", aDragHandle.isEnabled()); } @@ -804,7 +794,7 @@ View aMoreButton = a.findViewById(R.id.more); View aDragHandle = a.getDragHandleViewForTesting(); - TestThreadUtils.runOnUiThreadBlocking(searchButton::performClick); + runOnUiThreadBlocking(searchButton::performClick); // Callback occurs when Item "test" is selected. CriteriaHelper.pollUiThread( @@ -817,23 +807,23 @@ // Callback occurs when Item "test" is selected. CriteriaHelper.pollUiThread(test::isChecked, "Expected item \"test\" to become selected"); - Assert.assertEquals("Expected drag handle of selected item to be gone " + assertEquals("Expected drag handle of selected item to be gone " + "when selection mode is activated from search.", View.GONE, testDragHandle.getVisibility()); - Assert.assertEquals("Expected more button of selected item to be visible " + assertEquals("Expected more button of selected item to be visible " + "when selection mode is activated from search.", View.VISIBLE, testMoreButton.getVisibility()); - Assert.assertFalse("Expected more button of selected item to be disabled " + assertFalse("Expected more button of selected item to be disabled " + "when selection mode is activated from search.", testMoreButton.isEnabled()); - Assert.assertEquals("Expected drag handle of unselected item to be gone " + assertEquals("Expected drag handle of unselected item to be gone " + "when selection mode is activated from search.", View.GONE, aDragHandle.getVisibility()); - Assert.assertEquals("Expected more button of unselected item to be visible " + assertEquals("Expected more button of unselected item to be visible " + "when selection mode is activated from search.", View.VISIBLE, aMoreButton.getVisibility()); - Assert.assertFalse("Expected more button of unselected item to be disabled " + assertFalse("Expected more button of unselected item to be disabled " + "when selection mode is activated from search.", aMoreButton.isEnabled()); } @@ -853,9 +843,9 @@ initial.add(googleId); initial.add(fooId); - TestThreadUtils.runOnUiThreadBlocking(() -> { - Assert.assertEquals("Bookmarks were not added in the expected order.", initial, - mBookmarkModel.getChildIDs(mBookmarkModel.getDefaultFolder()).subList(0, 3)); + runOnUiThreadBlocking(() -> { + assertEquals("Bookmarks were not added in the expected order.", initial, + mBookmarkModel.getChildIds(mBookmarkModel.getDefaultFolder()).subList(0, 3)); }); expected.add(fooId); @@ -879,12 +869,11 @@ }; // Perform registration to make callbacks work. - TestThreadUtils.runOnUiThreadBlocking( - () -> { mBookmarkModel.addObserver(bookmarkModelObserver); }); + runOnUiThreadBlocking(() -> { mBookmarkModel.addObserver(bookmarkModelObserver); }); BookmarkRow foo = (BookmarkRow) mItemsContainer.findViewHolderForAdapterPosition(3).itemView; - Assert.assertEquals("Wrong bookmark item selected.", TEST_PAGE_TITLE_FOO, foo.getTitle()); + assertEquals("Wrong bookmark item selected.", TEST_PAGE_TITLE_FOO, foo.getTitle()); toggleSelectionAndEndAnimation(fooId, foo); // Starts as last bookmark (2nd index) and ends as 0th bookmark (promo header not included). @@ -893,25 +882,22 @@ modelReorderHelper.waitForCallback(0, 1); RecyclerViewTestUtils.waitForStableRecyclerView(mItemsContainer); - TestThreadUtils.runOnUiThreadBlocking(() -> { + runOnUiThreadBlocking(() -> { List<BookmarkId> observed = - mBookmarkModel.getChildIDs(mBookmarkModel.getDefaultFolder()); + mBookmarkModel.getChildIds(mBookmarkModel.getDefaultFolder()); // Exclude partner bookmarks folder - Assert.assertEquals(expected, observed.subList(0, 3)); - Assert.assertTrue("The selected item should stay selected", foo.isItemSelected()); + assertEquals(expected, observed.subList(0, 3)); + assertTrue("The selected item should stay selected", foo.isItemSelected()); }); // After a drag is finished, the toolbar menu items should still reflect the selected state. // Check inspired by https://crbug.com/1434566. BookmarkToolbar toolbar = mBookmarkManagerCoordinator.getToolbarForTesting(); - Assert.assertTrue(toolbar.getMenu().findItem(R.id.selection_mode_edit_menu_id).isVisible()); - Assert.assertTrue(toolbar.getMenu().findItem(R.id.selection_mode_move_menu_id).isVisible()); - Assert.assertTrue( - toolbar.getMenu().findItem(R.id.selection_mode_delete_menu_id).isVisible()); - Assert.assertTrue( - toolbar.getMenu().findItem(R.id.selection_open_in_new_tab_id).isVisible()); - Assert.assertTrue( - toolbar.getMenu().findItem(R.id.selection_open_in_incognito_tab_id).isVisible()); + assertTrue(toolbar.getMenu().findItem(R.id.selection_mode_edit_menu_id).isVisible()); + assertTrue(toolbar.getMenu().findItem(R.id.selection_mode_move_menu_id).isVisible()); + assertTrue(toolbar.getMenu().findItem(R.id.selection_mode_delete_menu_id).isVisible()); + assertTrue(toolbar.getMenu().findItem(R.id.selection_open_in_new_tab_id).isVisible()); + assertTrue(toolbar.getMenu().findItem(R.id.selection_open_in_incognito_tab_id).isVisible()); } @Test @@ -929,9 +915,9 @@ initial.add(bId); initial.add(aId); - TestThreadUtils.runOnUiThreadBlocking(() -> { - Assert.assertEquals("Bookmarks were not added in the expected order.", initial, - mBookmarkModel.getChildIDs(mBookmarkModel.getDefaultFolder()).subList(0, 4)); + runOnUiThreadBlocking(() -> { + assertEquals("Bookmarks were not added in the expected order.", initial, + mBookmarkModel.getChildIds(mBookmarkModel.getDefaultFolder()).subList(0, 4)); }); expected.add(cId); @@ -956,12 +942,11 @@ }; // Perform registration to make callbacks work. - TestThreadUtils.runOnUiThreadBlocking( - () -> { mBookmarkModel.addObserver(bookmarkModelObserver); }); + runOnUiThreadBlocking(() -> { mBookmarkModel.addObserver(bookmarkModelObserver); }); BookmarkFolderRow test = (BookmarkFolderRow) mItemsContainer.findViewHolderForAdapterPosition(1).itemView; - Assert.assertEquals("Wrong bookmark item selected.", TEST_FOLDER_TITLE, test.getTitle()); + assertEquals("Wrong bookmark item selected.", TEST_FOLDER_TITLE, test.getTitle()); toggleSelectionAndEndAnimation(testId, test); @@ -971,12 +956,12 @@ modelReorderHelper.waitForCallback(0, 1); RecyclerViewTestUtils.waitForStableRecyclerView(mItemsContainer); - TestThreadUtils.runOnUiThreadBlocking(() -> { + runOnUiThreadBlocking(() -> { List<BookmarkId> observed = - mBookmarkModel.getChildIDs(mBookmarkModel.getDefaultFolder()); + mBookmarkModel.getChildIds(mBookmarkModel.getDefaultFolder()); // Exclude partner bookmarks folder - Assert.assertEquals(expected, observed.subList(0, 4)); - Assert.assertTrue("The selected item should stay selected", test.isItemSelected()); + assertEquals(expected, observed.subList(0, 4)); + assertTrue("The selected item should stay selected", test.isItemSelected()); }); } @@ -993,9 +978,9 @@ initial.add(bId); initial.add(aId); - TestThreadUtils.runOnUiThreadBlocking(() -> { - Assert.assertEquals("Bookmarks were not added in the expected order.", initial, - mBookmarkModel.getChildIDs(mBookmarkModel.getDefaultFolder()).subList(0, 3)); + runOnUiThreadBlocking(() -> { + assertEquals("Bookmarks were not added in the expected order.", initial, + mBookmarkModel.getChildIds(mBookmarkModel.getDefaultFolder()).subList(0, 3)); }); expected.add(bId); @@ -1018,12 +1003,11 @@ } }; // Perform registration to make callbacks work. - TestThreadUtils.runOnUiThreadBlocking( - () -> { mBookmarkModel.addObserver(bookmarkModelObserver); }); + runOnUiThreadBlocking(() -> { mBookmarkModel.addObserver(bookmarkModelObserver); }); BookmarkFolderRow test = (BookmarkFolderRow) mItemsContainer.findViewHolderForAdapterPosition(1).itemView; - Assert.assertEquals("Wrong bookmark item selected.", TEST_FOLDER_TITLE, test.getTitle()); + assertEquals("Wrong bookmark item selected.", TEST_FOLDER_TITLE, test.getTitle()); toggleSelectionAndEndAnimation(testId, test); @@ -1033,12 +1017,12 @@ modelReorderHelper.waitForCallback(0, 1); RecyclerViewTestUtils.waitForStableRecyclerView(mItemsContainer); - TestThreadUtils.runOnUiThreadBlocking(() -> { + runOnUiThreadBlocking(() -> { List<BookmarkId> observed = - mBookmarkModel.getChildIDs(mBookmarkModel.getDefaultFolder()); + mBookmarkModel.getChildIds(mBookmarkModel.getDefaultFolder()); // Exclude partner bookmarks folder - Assert.assertEquals(expected, observed.subList(0, 3)); - Assert.assertTrue("The selected item should stay selected", test.isItemSelected()); + assertEquals(expected, observed.subList(0, 3)); + assertTrue("The selected item should stay selected", test.isItemSelected()); }); } @@ -1058,9 +1042,9 @@ toggleSelectionAndEndAnimation( testId, (BookmarkRow) mItemsContainer.findViewHolderForAdapterPosition(1).itemView); - Assert.assertFalse("Promo header should not be passively draggable", + assertFalse("Promo header should not be passively draggable", isViewHolderPassivelyDraggable(promo)); - Assert.assertFalse("Promo header should not be actively draggable", + assertFalse("Promo header should not be actively draggable", isViewHoldersActivelyDraggable(promo)); } @@ -1079,9 +1063,9 @@ toggleSelectionAndEndAnimation( testId, (BookmarkRow) mItemsContainer.findViewHolderForAdapterPosition(1).itemView); - Assert.assertFalse("Partner bookmarks folder should not be passively draggable", + assertFalse("Partner bookmarks folder should not be passively draggable", isViewHolderPassivelyDraggable(partner)); - Assert.assertFalse("Partner bookmarks folder should not be actively draggable", + assertFalse("Partner bookmarks folder should not be actively draggable", isViewHoldersActivelyDraggable(partner)); } @@ -1098,15 +1082,15 @@ mItemsContainer, getBookmarkDelegate(), mBookmarkModel); ViewHolder test = mItemsContainer.findViewHolderForAdapterPosition(1); - Assert.assertEquals("Wrong bookmark item selected.", TEST_FOLDER_TITLE, + assertEquals("Wrong bookmark item selected.", TEST_FOLDER_TITLE, ((BookmarkFolderRow) test.itemView).getTitle()); toggleSelectionAndEndAnimation( aId, (BookmarkRow) mItemsContainer.findViewHolderForAdapterPosition(2).itemView); - Assert.assertTrue("Unselected rows should be passively draggable", + assertTrue("Unselected rows should be passively draggable", isViewHolderPassivelyDraggable(test)); - Assert.assertFalse("Unselected rows should not be actively draggable", + assertFalse("Unselected rows should not be actively draggable", isViewHoldersActivelyDraggable(test)); } @@ -1123,7 +1107,7 @@ View promo = mItemsContainer.findViewHolderForAdapterPosition(0).itemView; TouchCommon.longPressView(promo); RecyclerViewTestUtils.waitForStableRecyclerView(mItemsContainer); - Assert.assertFalse("Expected that we would not be in selection mode " + assertFalse("Expected that we would not be in selection mode " + "after long pressing on promo view.", getBookmarkDelegate().getSelectionDelegate().isSelectionEnabled()); } @@ -1139,7 +1123,7 @@ View partner = mItemsContainer.findViewHolderForAdapterPosition(2).itemView; TouchCommon.longPressView(partner); RecyclerViewTestUtils.waitForStableRecyclerView(mItemsContainer); - Assert.assertFalse("Expected that we would not be in selection mode " + assertFalse("Expected that we would not be in selection mode " + "after long pressing on partner bookmark.", getBookmarkDelegate().getSelectionDelegate().isSelectionEnabled()); } @@ -1157,21 +1141,19 @@ mItemsContainer, getBookmarkDelegate(), mBookmarkModel); View google = mItemsContainer.findViewHolderForAdapterPosition(2).itemView; - Assert.assertEquals("Wrong bookmark item selected.", TEST_PAGE_TITLE_GOOGLE, + assertEquals("Wrong bookmark item selected.", TEST_PAGE_TITLE_GOOGLE, ((BookmarkItemRow) google).getTitle()); View more = google.findViewById(R.id.more); - TestThreadUtils.runOnUiThreadBlocking(more::callOnClick); + runOnUiThreadBlocking(more::callOnClick); onView(withText("Move up")).perform(click()); // Confirm that the "Google" bookmark is now on top, and that the "test" folder is 2nd - Assert.assertTrue( - ((BookmarkRow) mItemsContainer.findViewHolderForAdapterPosition(1).itemView) - .getTitle() - .equals(TEST_PAGE_TITLE_GOOGLE)); - Assert.assertTrue( - ((BookmarkRow) mItemsContainer.findViewHolderForAdapterPosition(2).itemView) - .getTitle() - .equals(TEST_FOLDER_TITLE)); + assertTrue(((BookmarkRow) mItemsContainer.findViewHolderForAdapterPosition(1).itemView) + .getTitle() + .equals(TEST_PAGE_TITLE_GOOGLE)); + assertTrue(((BookmarkRow) mItemsContainer.findViewHolderForAdapterPosition(2).itemView) + .getTitle() + .equals(TEST_FOLDER_TITLE)); } @Test @@ -1186,21 +1168,19 @@ mItemsContainer, getBookmarkDelegate(), mBookmarkModel); View testFolder = mItemsContainer.findViewHolderForAdapterPosition(1).itemView; - Assert.assertEquals("Wrong bookmark item selected.", TEST_FOLDER_TITLE, + assertEquals("Wrong bookmark item selected.", TEST_FOLDER_TITLE, ((BookmarkFolderRow) testFolder).getTitle()); ListMenuButton more = testFolder.findViewById(R.id.more); - TestThreadUtils.runOnUiThreadBlocking(more::callOnClick); + runOnUiThreadBlocking(more::callOnClick); onView(withText("Move down")).perform(click()); // Confirm that the "Google" bookmark is now on top, and that the "test" folder is 2nd - Assert.assertTrue( - ((BookmarkRow) mItemsContainer.findViewHolderForAdapterPosition(1).itemView) - .getTitle() - .equals(TEST_PAGE_TITLE_GOOGLE)); - Assert.assertTrue( - ((BookmarkRow) mItemsContainer.findViewHolderForAdapterPosition(2).itemView) - .getTitle() - .equals(TEST_FOLDER_TITLE)); + assertTrue(((BookmarkRow) mItemsContainer.findViewHolderForAdapterPosition(1).itemView) + .getTitle() + .equals(TEST_PAGE_TITLE_GOOGLE)); + assertTrue(((BookmarkRow) mItemsContainer.findViewHolderForAdapterPosition(2).itemView) + .getTitle() + .equals(TEST_FOLDER_TITLE)); } @Test @@ -1215,10 +1195,10 @@ mItemsContainer, getBookmarkDelegate(), mBookmarkModel); View google = mItemsContainer.findViewHolderForAdapterPosition(2).itemView; - Assert.assertEquals("Wrong bookmark item selected.", TEST_PAGE_TITLE_GOOGLE, + assertEquals("Wrong bookmark item selected.", TEST_PAGE_TITLE_GOOGLE, ((BookmarkItemRow) google).getTitle()); View more = google.findViewById(R.id.more); - TestThreadUtils.runOnUiThreadBlocking(more::callOnClick); + runOnUiThreadBlocking(more::callOnClick); onView(withText("Move down")).check(doesNotExist()); } @@ -1234,10 +1214,10 @@ mItemsContainer, getBookmarkDelegate(), mBookmarkModel); View testFolder = mItemsContainer.findViewHolderForAdapterPosition(1).itemView; - Assert.assertEquals("Wrong bookmark item selected.", TEST_FOLDER_TITLE, + assertEquals("Wrong bookmark item selected.", TEST_FOLDER_TITLE, ((BookmarkFolderRow) testFolder).getTitle()); ListMenuButton more = testFolder.findViewById(R.id.more); - TestThreadUtils.runOnUiThreadBlocking(more::callOnClick); + runOnUiThreadBlocking(more::callOnClick); onView(withText("Move up")).check(doesNotExist()); } @@ -1250,7 +1230,7 @@ View searchButton = mBookmarkManagerCoordinator.getToolbarForTesting().findViewById( R.id.search_menu_id); - TestThreadUtils.runOnUiThreadBlocking(searchButton::performClick); + runOnUiThreadBlocking(searchButton::performClick); // Callback occurs when Item "test" is selected. CriteriaHelper.pollUiThread( @@ -1259,10 +1239,10 @@ "Expected to enter search mode"); View testFolder = mItemsContainer.findViewHolderForAdapterPosition(0).itemView; - Assert.assertEquals("Wrong bookmark item selected.", TEST_FOLDER_TITLE, + assertEquals("Wrong bookmark item selected.", TEST_FOLDER_TITLE, ((BookmarkFolderRow) testFolder).getTitle()); View more = testFolder.findViewById(R.id.more); - TestThreadUtils.runOnUiThreadBlocking(more::callOnClick); + runOnUiThreadBlocking(more::callOnClick); onView(withText("Move up")).check(doesNotExist()); onView(withText("Move down")).check(doesNotExist()); @@ -1279,10 +1259,10 @@ mItemsContainer, getBookmarkDelegate(), mBookmarkModel); View testFolder = mItemsContainer.findViewHolderForAdapterPosition(1).itemView; - Assert.assertEquals("Wrong bookmark item selected.", TEST_FOLDER_TITLE, + assertEquals("Wrong bookmark item selected.", TEST_FOLDER_TITLE, ((BookmarkFolderRow) testFolder).getTitle()); View more = testFolder.findViewById(R.id.more); - TestThreadUtils.runOnUiThreadBlocking(more::callOnClick); + runOnUiThreadBlocking(more::callOnClick); onView(withText("Move up")).check(doesNotExist()); onView(withText("Move down")).check(doesNotExist()); @@ -1296,50 +1276,48 @@ openBookmarkManager(); // Open partner bookmarks folder. - TestThreadUtils.runOnUiThreadBlocking( + runOnUiThreadBlocking( () -> getBookmarkDelegate().openFolder(mBookmarkModel.getPartnerFolderId())); RecyclerViewTestUtils.waitForStableRecyclerView(mItemsContainer); - Assert.assertEquals("Wrong number of items in partner bookmark folder.", 2, + assertEquals("Wrong number of items in partner bookmark folder.", 2, getAdapter().getItemCount()); // Verify that bookmark 1 is editable (so more button can be triggered) but not movable. BookmarkId partnerBookmarkId1 = getIdByPosition(0); - TestThreadUtils.runOnUiThreadBlocking(() -> { + runOnUiThreadBlocking(() -> { BookmarkItem partnerBookmarkItem1 = mBookmarkModel.getBookmarkById(partnerBookmarkId1); partnerBookmarkItem1.forceEditableForTesting(); - Assert.assertEquals("Incorrect bookmark type for item 1", BookmarkType.PARTNER, + assertEquals("Incorrect bookmark type for item 1", BookmarkType.PARTNER, partnerBookmarkId1.getType()); - Assert.assertFalse("Partner item 1 should not be movable", + assertFalse("Partner item 1 should not be movable", BookmarkUtils.isMovable(partnerBookmarkItem1)); - Assert.assertTrue( - "Partner item 1 should be editable", partnerBookmarkItem1.isEditable()); + assertTrue("Partner item 1 should be editable", partnerBookmarkItem1.isEditable()); }); // Verify that bookmark 2 is editable (so more button can be triggered) but not movable. View partnerBookmarkView1 = mItemsContainer.findViewHolderForAdapterPosition(0).itemView; View more1 = partnerBookmarkView1.findViewById(R.id.more); - TestThreadUtils.runOnUiThreadBlocking(more1::callOnClick); + runOnUiThreadBlocking(more1::callOnClick); onView(withText("Move up")).check(doesNotExist()); onView(withText("Move down")).check(doesNotExist()); // Verify that bookmark 2 is not movable. BookmarkId partnerBookmarkId2 = getIdByPosition(1); - TestThreadUtils.runOnUiThreadBlocking(() -> { + runOnUiThreadBlocking(() -> { BookmarkItem partnerBookmarkItem2 = mBookmarkModel.getBookmarkById(partnerBookmarkId2); partnerBookmarkItem2.forceEditableForTesting(); - Assert.assertEquals("Incorrect bookmark type for item 2", BookmarkType.PARTNER, + assertEquals("Incorrect bookmark type for item 2", BookmarkType.PARTNER, partnerBookmarkId2.getType()); - Assert.assertFalse("Partner item 2 should not be movable", + assertFalse("Partner item 2 should not be movable", BookmarkUtils.isMovable(partnerBookmarkItem2)); - Assert.assertTrue( - "Partner item 2 should be editable", partnerBookmarkItem2.isEditable()); + assertTrue("Partner item 2 should be editable", partnerBookmarkItem2.isEditable()); }); // Verify that bookmark 2 does not have move up/down items. View partnerBookmarkView2 = mItemsContainer.findViewHolderForAdapterPosition(1).itemView; View more2 = partnerBookmarkView2.findViewById(R.id.more); - TestThreadUtils.runOnUiThreadBlocking(more2::callOnClick); + runOnUiThreadBlocking(more2::callOnClick); onView(withText("Move up")).check(doesNotExist()); onView(withText("Move down")).check(doesNotExist()); } @@ -1353,8 +1331,8 @@ openBookmarkManager(); // Add a bookmark to the Other Bookmarks folder. - TestThreadUtils.runOnUiThreadBlocking(() -> { - Assert.assertNotNull(mBookmarkModel.addBookmark( + runOnUiThreadBlocking(() -> { + assertNotNull(mBookmarkModel.addBookmark( mBookmarkModel.getOtherFolderId(), 0, TEST_TITLE_A, mTestUrlA)); }); @@ -1362,11 +1340,11 @@ .addSyncStateChangedListener(mSyncStateChangedListenerCaptor.capture()); for (SyncStateChangedListener syncStateChangedListener : mSyncStateChangedListenerCaptor.getAllValues()) { - TestThreadUtils.runOnUiThreadBlocking(syncStateChangedListener::syncStateChanged); + runOnUiThreadBlocking(syncStateChangedListener::syncStateChanged); } - TestThreadUtils.runOnUiThreadBlocking(getTestingDelegate()::simulateSignInForTesting); + runOnUiThreadBlocking(getTestingDelegate()::simulateSignInForTesting); - Assert.assertEquals( + assertEquals( "Expected promo, \"Reading List\", \"Mobile Bookmarks\" and \"Other Bookmarks\" folder to appear!", 4, getAdapter().getItemCount()); } @@ -1391,21 +1369,20 @@ onView(withText("Show in folder")).perform(click()); // Assert that the view pulses. - Assert.assertTrue("Expected bookmark row to pulse after clicking \"show in folder\"!", + assertTrue("Expected bookmark row to pulse after clicking \"show in folder\"!", checkHighlightPulse(testFolder)); // Enter search mode again. enterSearch(); - Assert.assertTrue("Expected bookmark row to not be highlighted " + assertTrue("Expected bookmark row to not be highlighted " + "after entering search mode", checkHighlightOff(testFolder)); // Click "Show in folder" again. clickMoreButtonOnFirstItem(TEST_FOLDER_TITLE); onView(withText("Show in folder")).perform(click()); - Assert.assertTrue( - "Expected bookmark row to pulse after clicking \"show in folder\" a 2nd time!", + assertTrue("Expected bookmark row to pulse after clicking \"show in folder\" a 2nd time!", checkHighlightPulse(testFolder)); } @@ -1428,7 +1405,7 @@ // Enter search mode. enterSearch(); - TestThreadUtils.runOnUiThreadBlocking( + runOnUiThreadBlocking( () -> mBookmarkManagerCoordinator.onSearchTextChanged(TEST_FOLDER_TITLE)); RecyclerViewTestUtils.waitForStableRecyclerView(mItemsContainer); @@ -1440,11 +1417,10 @@ // This should be in the 8th position now. ViewHolder testFolderInList = mItemsContainer.findViewHolderForAdapterPosition(8); - Assert.assertFalse( - "Expected list to scroll bookmark item into view", testFolderInList == null); - Assert.assertEquals("Wrong bookmark item selected.", TEST_FOLDER_TITLE, + assertFalse("Expected list to scroll bookmark item into view", testFolderInList == null); + assertEquals("Wrong bookmark item selected.", TEST_FOLDER_TITLE, ((BookmarkFolderRow) testFolderInList.itemView).getTitle()); - Assert.assertTrue("Expected highlight to pulse on after scrolling to the item!", + assertTrue("Expected highlight to pulse on after scrolling to the item!", checkHighlightPulse(testFolderInList.itemView)); } @@ -1453,15 +1429,14 @@ @DisabledTest(message = "crbug.com/1434777") public void testShowInFolder_OpenOtherFolder() throws Exception { BookmarkId testId = addFolder(TEST_FOLDER_TITLE); - TestThreadUtils.runOnUiThreadBlocking( - () -> mBookmarkModel.addBookmark(testId, 0, TEST_TITLE_A, mTestUrlA)); + runOnUiThreadBlocking(() -> mBookmarkModel.addBookmark(testId, 0, TEST_TITLE_A, mTestUrlA)); BookmarkPromoHeader.forcePromoStateForTesting( SyncPromoState.PROMO_FOR_SYNC_TURNED_OFF_STATE); openBookmarkManager(); // Enter search mode. enterSearch(); - TestThreadUtils.runOnUiThreadBlocking( + runOnUiThreadBlocking( () -> mBookmarkManagerCoordinator.onSearchTextChanged(mTestUrlA.getSpec())); RecyclerViewTestUtils.waitForStableRecyclerView(mItemsContainer); @@ -1474,24 +1449,23 @@ // Make sure that we're in the right folder (index 1 because of promo). View itemA = mItemsContainer.findViewHolderForAdapterPosition(1).itemView; - Assert.assertEquals("Wrong bookmark item selected.", TEST_TITLE_A, + assertEquals("Wrong bookmark item selected.", TEST_TITLE_A, ((BookmarkItemRow) itemA).getTitle()); - Assert.assertTrue("Expected highlight to pulse after opening an item in another folder!", + assertTrue("Expected highlight to pulse after opening an item in another folder!", checkHighlightPulse(itemA)); // Open mobile bookmarks folder, then go back to the subfolder. - TestThreadUtils.runOnUiThreadBlocking(() -> { + runOnUiThreadBlocking(() -> { getBookmarkDelegate().openFolder(mBookmarkModel.getMobileFolderId()); getBookmarkDelegate().openFolder(testId); }); RecyclerViewTestUtils.waitForStableRecyclerView(mItemsContainer); View itemASecondView = mItemsContainer.findViewHolderForAdapterPosition(1).itemView; - Assert.assertEquals("Wrong bookmark item selected.", TEST_TITLE_A, + assertEquals("Wrong bookmark item selected.", TEST_TITLE_A, ((BookmarkItemRow) itemASecondView).getTitle()); - Assert.assertTrue( - "Expected highlight to not be highlighted after exiting and re-entering folder!", + assertTrue("Expected highlight to not be highlighted after exiting and re-entering folder!", checkHighlightOff(itemASecondView)); } @@ -1506,21 +1480,21 @@ // Open the new folder where these bookmarks were created. openFolder(folder); - Assert.assertEquals(1, getAdapter().getItemCount()); + assertEquals(1, getAdapter().getItemCount()); BookmarkRow row = (BookmarkRow) mItemsContainer.findViewHolderForAdapterPosition(0).itemView; toggleSelectionAndEndAnimation(id, row); - TestThreadUtils.runOnUiThreadBlocking(() -> { + runOnUiThreadBlocking(() -> { mBookmarkModel.addBookmark(folder, 1, TEST_PAGE_TITLE_GOOGLE, mTestPage); }); RecyclerViewTestUtils.waitForStableRecyclerView(mItemsContainer); - TestThreadUtils.runOnUiThreadBlocking(() -> { - Assert.assertTrue(isItemPresentInBookmarkList(TEST_PAGE_TITLE_FOO)); - Assert.assertTrue(isItemPresentInBookmarkList(TEST_PAGE_TITLE_GOOGLE)); - Assert.assertEquals(2, getAdapter().getItemCount()); - Assert.assertTrue("The selected row should be kept selected", row.isItemSelected()); + runOnUiThreadBlocking(() -> { + assertTrue(isItemPresentInBookmarkList(TEST_PAGE_TITLE_FOO)); + assertTrue(isItemPresentInBookmarkList(TEST_PAGE_TITLE_GOOGLE)); + assertEquals(2, getAdapter().getItemCount()); + assertTrue("The selected row should be kept selected", row.isItemSelected()); }); } @@ -1539,12 +1513,12 @@ // Open the new folder where these bookmarks were created. openFolder(folder); - Assert.assertEquals(3, getAdapter().getItemCount()); + assertEquals(3, getAdapter().getItemCount()); BookmarkRow row = (BookmarkRow) mItemsContainer.findViewHolderForAdapterPosition(1).itemView; toggleSelectionAndEndAnimation(googleId, row); CallbackHelper helper = new CallbackHelper(); - TestThreadUtils.runOnUiThreadBlocking(() -> { + runOnUiThreadBlocking(() -> { getBookmarkDelegate().getSelectionDelegate().addObserver((x) -> helper.notifyCalled()); }); @@ -1552,11 +1526,10 @@ RecyclerViewTestUtils.waitForStableRecyclerView(mItemsContainer); helper.waitForCallback(0, 1); - TestThreadUtils.runOnUiThreadBlocking(() -> { - Assert.assertFalse( - "Item is not deleted", isItemPresentInBookmarkList(TEST_PAGE_TITLE_GOOGLE)); - Assert.assertEquals(2, getAdapter().getItemCount()); - Assert.assertEquals("Bookmark View should be back to normal view", + runOnUiThreadBlocking(() -> { + assertFalse("Item is not deleted", isItemPresentInBookmarkList(TEST_PAGE_TITLE_GOOGLE)); + assertEquals(2, getAdapter().getItemCount()); + assertEquals("Bookmark View should be back to normal view", mBookmarkManagerCoordinator.getToolbarForTesting().getCurrentViewType(), ViewType.NORMAL_VIEW); }); @@ -1577,7 +1550,7 @@ // Open the new folder where these bookmarks were created. openFolder(folder); - Assert.assertEquals(3, getAdapter().getItemCount()); + assertEquals(3, getAdapter().getItemCount()); BookmarkRow row = (BookmarkRow) mItemsContainer.findViewHolderForAdapterPosition(1).itemView; toggleSelectionAndEndAnimation(googleId, row); @@ -1586,7 +1559,7 @@ toggleSelectionAndEndAnimation(aId, aRow); CallbackHelper helper = new CallbackHelper(); - TestThreadUtils.runOnUiThreadBlocking(() -> { + runOnUiThreadBlocking(() -> { getBookmarkDelegate().getSelectionDelegate().addObserver((x) -> helper.notifyCalled()); }); @@ -1594,12 +1567,11 @@ RecyclerViewTestUtils.waitForStableRecyclerView(mItemsContainer); helper.waitForCallback(0, 1); - TestThreadUtils.runOnUiThreadBlocking(() -> { - Assert.assertFalse( - "Item is not deleted", isItemPresentInBookmarkList(TEST_PAGE_TITLE_GOOGLE)); - Assert.assertEquals(2, getAdapter().getItemCount()); - Assert.assertTrue("Item selected should not be cleared", aRow.isItemSelected()); - Assert.assertEquals("Should stay in selection mode because there is one selected", + runOnUiThreadBlocking(() -> { + assertFalse("Item is not deleted", isItemPresentInBookmarkList(TEST_PAGE_TITLE_GOOGLE)); + assertEquals(2, getAdapter().getItemCount()); + assertTrue("Item selected should not be cleared", aRow.isItemSelected()); + assertEquals("Should stay in selection mode because there is one selected", mBookmarkManagerCoordinator.getToolbarForTesting().getCurrentViewType(), ViewType.SELECTION_VIEW); }); @@ -1616,36 +1588,34 @@ // Open the new folder where these bookmarks were created. openFolder(folder); - Assert.assertEquals(1, getAdapter().getItemCount()); + assertEquals(1, getAdapter().getItemCount()); BookmarkRow row = (BookmarkRow) mItemsContainer.findViewHolderForAdapterPosition(0).itemView; toggleSelectionAndEndAnimation(id, row); CallbackHelper helper = new CallbackHelper(); - TestThreadUtils.runOnUiThreadBlocking( - () -> mBookmarkModel.addObserver(new BookmarkModelObserver() { - @Override - public void bookmarkModelChanged() { - helper.notifyCalled(); - } - })); + runOnUiThreadBlocking(() -> mBookmarkModel.addObserver(new BookmarkModelObserver() { + @Override + public void bookmarkModelChanged() { + helper.notifyCalled(); + } + })); - TestThreadUtils.runOnUiThreadBlocking( - () -> mBookmarkModel.setBookmarkTitle(id, TEST_PAGE_TITLE_GOOGLE)); + runOnUiThreadBlocking(() -> mBookmarkModel.setBookmarkTitle(id, TEST_PAGE_TITLE_GOOGLE)); helper.waitForCallback(0, 1); RecyclerViewTestUtils.waitForStableRecyclerView(mItemsContainer); - TestThreadUtils.runOnUiThreadBlocking(() -> { - Assert.assertFalse(isItemPresentInBookmarkList(TEST_PAGE_TITLE_FOO)); - Assert.assertTrue(isItemPresentInBookmarkList(TEST_PAGE_TITLE_GOOGLE)); - Assert.assertEquals(1, getAdapter().getItemCount()); - Assert.assertTrue("The selected row should stay selected", row.isItemSelected()); + runOnUiThreadBlocking(() -> { + assertFalse(isItemPresentInBookmarkList(TEST_PAGE_TITLE_FOO)); + assertTrue(isItemPresentInBookmarkList(TEST_PAGE_TITLE_GOOGLE)); + assertEquals(1, getAdapter().getItemCount()); + assertTrue("The selected row should stay selected", row.isItemSelected()); }); } @Test @MediumTest public void testBookmarksDoesNotRecordLaunchMetrics() throws Throwable { - Assert.assertEquals(1, + assertEquals(1, RecordHistogram.getHistogramTotalCountForTesting( LaunchCauseMetrics.LAUNCH_CAUSE_HISTOGRAM)); @@ -1654,7 +1624,7 @@ pressBack(); BookmarkTestUtil.waitForTabbedActivity(); - Assert.assertEquals(1, + assertEquals(1, RecordHistogram.getHistogramTotalCountForTesting( LaunchCauseMetrics.LAUNCH_CAUSE_HISTOGRAM)); @@ -1664,7 +1634,7 @@ onView(withText(TEST_PAGE_TITLE_GOOGLE)).perform(click()); BookmarkTestUtil.waitForTabbedActivity(); - Assert.assertEquals(1, + assertEquals(1, RecordHistogram.getHistogramTotalCountForTesting( LaunchCauseMetrics.LAUNCH_CAUSE_HISTOGRAM)); } @@ -1682,7 +1652,7 @@ @MediumTest @Restriction({UiRestriction.RESTRICTION_TYPE_PHONE}) public void testRecordsHistogramWhenBookmarkManagerOpened_InRegular() throws Throwable { - Assert.assertEquals(0, + assertEquals(0, RecordHistogram.getHistogramTotalCountForTesting( "Bookmarks.OpenBookmarkManager.PerProfileType")); @@ -1690,11 +1660,11 @@ pressBack(); BookmarkTestUtil.waitForTabbedActivity(); - Assert.assertEquals(1, + assertEquals(1, RecordHistogram.getHistogramTotalCountForTesting( "Bookmarks.OpenBookmarkManager.PerProfileType")); - Assert.assertEquals(1, + assertEquals(1, RecordHistogram.getHistogramValueCountForTesting( "Bookmarks.OpenBookmarkManager.PerProfileType", BrowserProfileType.REGULAR)); @@ -1713,7 +1683,7 @@ @MediumTest @Restriction({UiRestriction.RESTRICTION_TYPE_PHONE}) public void testRecordsHistogramWhenBookmarkManagerOpened_InIncognito() throws Throwable { - Assert.assertEquals(0, + assertEquals(0, RecordHistogram.getHistogramTotalCountForTesting( "Bookmarks.OpenBookmarkManager.PerProfileType")); @@ -1722,11 +1692,11 @@ pressBack(); BookmarkTestUtil.waitForTabbedActivity(); - Assert.assertEquals(1, + assertEquals(1, RecordHistogram.getHistogramTotalCountForTesting( "Bookmarks.OpenBookmarkManager.PerProfileType")); - Assert.assertEquals(1, + assertEquals(1, RecordHistogram.getHistogramValueCountForTesting( "Bookmarks.OpenBookmarkManager.PerProfileType", BrowserProfileType.INCOGNITO)); @@ -1806,7 +1776,7 @@ BookmarkPromoHeader.forcePromoStateForTesting(SyncPromoState.NO_PROMO); openBookmarkManager(); BookmarkTestUtil.waitForBookmarkModelLoaded(); - TestThreadUtils.runOnUiThreadBlocking( + runOnUiThreadBlocking( () -> { getBookmarkDelegate().openFolder(mBookmarkModel.getRootFolderId()); }); onView(withText("Tracked products")).perform(click()); @@ -1814,8 +1784,8 @@ final BookmarkToolbar toolbar = mBookmarkManagerCoordinator.getToolbarForTesting(); // Check that we are in the mobile bookmarks folder. - Assert.assertEquals("Tracked products", toolbar.getTitle()); - Assert.assertEquals( + assertEquals("Tracked products", toolbar.getTitle()); + assertEquals( SelectableListToolbar.NavigationButton.BACK, toolbar.getNavigationButtonForTests()); } @@ -1828,8 +1798,7 @@ BookmarkId id = addBookmark(TEST_PAGE_TITLE_GOOGLE, mTestPage); PowerBookmarkMeta.Builder meta = PowerBookmarkMeta.newBuilder().setShoppingSpecifics( ShoppingSpecifics.newBuilder().setProductClusterId(1234L).build()); - TestThreadUtils.runOnUiThreadBlocking( - () -> { mBookmarkModel.setPowerBookmarkMeta(id, meta.build()); }); + runOnUiThreadBlocking(() -> { mBookmarkModel.setPowerBookmarkMeta(id, meta.build()); }); BookmarkPromoHeader.forcePromoStateForTesting(SyncPromoState.NO_PROMO); openBookmarkManager(); BookmarkTestUtil.waitForBookmarkModelLoaded(); @@ -1839,7 +1808,7 @@ BookmarkRow itemView = (BookmarkRow) mBookmarkManagerCoordinator.getRecyclerViewForTesting() .findViewHolderForAdapterPosition(0) .itemView; - Assert.assertNotEquals(PowerBookmarkShoppingItemRow.class, itemView.getClass()); + assertNotEquals(PowerBookmarkShoppingItemRow.class, itemView.getClass()); } /** @@ -1847,8 +1816,7 @@ * appear in the mobile bookmarks folder. */ private void loadFakePartnerBookmarkShimForTesting() { - TestThreadUtils.runOnUiThreadBlocking( - () -> { mBookmarkModel.loadFakePartnerBookmarkShimForTesting(); }); + runOnUiThreadBlocking(() -> { mBookmarkModel.loadFakePartnerBookmarkShimForTesting(); }); BookmarkTestUtil.waitForBookmarkModelLoaded(); } @@ -1873,7 +1841,7 @@ mBookmarkManagerCoordinator = mBookmarkActivity.getManagerForTesting(); } - TestThreadUtils.runOnUiThreadBlocking( + runOnUiThreadBlocking( () -> getBookmarkDelegate().getDragStateDelegate().setA11yStateForTesting(false)); } @@ -1906,7 +1874,7 @@ */ private BookmarkId addBookmarkWithPartner(String title, GURL url) throws ExecutionException { BookmarkTestUtil.loadEmptyPartnerBookmarksForTesting(mBookmarkModel); - return TestThreadUtils.runOnUiThreadBlocking( + return runOnUiThreadBlocking( () -> mBookmarkModel.addBookmark(mBookmarkModel.getDefaultFolder(), 0, title, url)); } @@ -1919,12 +1887,12 @@ */ private BookmarkId addFolderWithPartner(String title) throws ExecutionException { BookmarkTestUtil.loadEmptyPartnerBookmarksForTesting(mBookmarkModel); - return TestThreadUtils.runOnUiThreadBlocking( + return runOnUiThreadBlocking( () -> mBookmarkModel.addFolder(mBookmarkModel.getDefaultFolder(), 0, title)); } private void simulateDragForTestsOnUiThread(int start, int end) { - TestThreadUtils.runOnUiThreadBlocking(() -> { + runOnUiThreadBlocking(() -> { DragReorderableRecyclerViewAdapter dragReorderableRecyclerViewAdapter = getDragReorderableRecyclerViewAdapter(); dragReorderableRecyclerViewAdapter.simulateDragForTests(start, end); @@ -1956,7 +1924,7 @@ private void enterSearch() throws Exception { View searchButton = mBookmarkManagerCoordinator.getToolbarForTesting().findViewById( R.id.search_menu_id); - TestThreadUtils.runOnUiThreadBlocking(searchButton::performClick); + runOnUiThreadBlocking(searchButton::performClick); CriteriaHelper.pollUiThread( () -> mBookmarkManagerCoordinator.getToolbarForTesting().isSearching(), @@ -1965,11 +1933,11 @@ private void clickMoreButtonOnFirstItem(String expectedBookmarkItemTitle) throws Exception { View firstItem = mItemsContainer.findViewHolderForAdapterPosition(0).itemView; - Assert.assertEquals("Wrong bookmark item selected.", expectedBookmarkItemTitle, + assertEquals("Wrong bookmark item selected.", expectedBookmarkItemTitle, firstItem instanceof BookmarkItemRow ? ((BookmarkItemRow) firstItem).getTitle() : ((BookmarkFolderRow) firstItem).getTitle()); View more = firstItem.findViewById(R.id.more); - TestThreadUtils.runOnUiThreadBlocking(more::performClick); + runOnUiThreadBlocking(more::performClick); } /** @@ -1993,14 +1961,14 @@ matchingViews.add(v); } } - Assert.assertEquals("Exactly one item should be present.", 1, matchingViews.size()); + assertEquals("Exactly one item should be present.", 1, matchingViews.size()); return matchingViews.get(0); } }); } private void toggleSelectionAndEndAnimation(BookmarkId id, BookmarkRow view) { - TestThreadUtils.runOnUiThreadBlocking(() -> { + runOnUiThreadBlocking(() -> { getBookmarkDelegate().getSelectionDelegate().toggleSelectionForItem(id); view.endAnimationsForTests(); mBookmarkManagerCoordinator.getToolbarForTesting().endAnimationsForTesting(); @@ -2011,30 +1979,28 @@ private BookmarkId addBookmark(final String title, GURL url, BookmarkId parent) throws ExecutionException { BookmarkTestUtil.readPartnerBookmarks(mActivityTestRule); - return TestThreadUtils.runOnUiThreadBlocking( - () -> mBookmarkModel.addBookmark(parent, 0, title, url)); + return runOnUiThreadBlocking(() -> mBookmarkModel.addBookmark(parent, 0, title, url)); } private BookmarkId addBookmark(final String title, final GURL url) throws ExecutionException { BookmarkTestUtil.readPartnerBookmarks(mActivityTestRule); - return TestThreadUtils.runOnUiThreadBlocking( + return runOnUiThreadBlocking( () -> mBookmarkModel.addBookmark(mBookmarkModel.getDefaultFolder(), 0, title, url)); } private BookmarkId addFolder(final String title) throws ExecutionException { BookmarkTestUtil.readPartnerBookmarks(mActivityTestRule); - return TestThreadUtils.runOnUiThreadBlocking( + return runOnUiThreadBlocking( () -> mBookmarkModel.addFolder(mBookmarkModel.getDefaultFolder(), 0, title)); } private BookmarkId addFolder(final String title, BookmarkId parent) throws ExecutionException { BookmarkTestUtil.readPartnerBookmarks(mActivityTestRule); - return TestThreadUtils.runOnUiThreadBlocking( - () -> mBookmarkModel.addFolder(parent, 0, title)); + return runOnUiThreadBlocking(() -> mBookmarkModel.addFolder(parent, 0, title)); } private void removeBookmark(final BookmarkId bookmarkId) { - TestThreadUtils.runOnUiThreadBlocking(() -> mBookmarkModel.deleteBookmark(bookmarkId)); + runOnUiThreadBlocking(() -> mBookmarkModel.deleteBookmark(bookmarkId)); } private RecyclerView.Adapter getAdapter() { @@ -2046,12 +2012,12 @@ } private void searchBookmarks(final String query) { - TestThreadUtils.runOnUiThreadBlocking(() -> getTestingDelegate().searchForTesting(query)); + runOnUiThreadBlocking(() -> getTestingDelegate().searchForTesting(query)); } private void openFolder(BookmarkId folder) { final BookmarkDelegate delegate = getBookmarkDelegate(); - TestThreadUtils.runOnUiThreadBlocking(() -> delegate.openFolder(folder)); + runOnUiThreadBlocking(() -> delegate.openFolder(folder)); RecyclerViewTestUtils.waitForStableRecyclerView(mItemsContainer); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkBridgeTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkBridgeTest.java index 4daaf724..c917fbd 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkBridgeTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkBridgeTest.java
@@ -254,14 +254,14 @@ long[] startingIdsArray = new long[] {kBUrl, kAUrl, kBFolder, kAFolder, kPartnerBookmarks}; Assert.assertArrayEquals( - startingIdsArray, getIdArray(mBookmarkBridge.getChildIDs(mMobileNode))); + startingIdsArray, getIdArray(mBookmarkBridge.getChildIds(mMobileNode))); long[] reorderedIdsArray = new long[] {kAUrl, kBFolder, kBUrl, kAFolder}; mBookmarkBridge.reorderBookmarks(mMobileNode, reorderedIdsArray); long[] endingIdsArray = new long[] {kAUrl, kBFolder, kBUrl, kAFolder, kPartnerBookmarks}; Assert.assertArrayEquals( - endingIdsArray, getIdArray(mBookmarkBridge.getChildIDs(mMobileNode))); + endingIdsArray, getIdArray(mBookmarkBridge.getChildIds(mMobileNode))); } /**
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkModelTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkModelTest.java index 16001ce..db161003 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkModelTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkModelTest.java
@@ -129,7 +129,7 @@ mBookmarkModel.moveBookmarks(new ArrayList<>(movedBookmarks), folderAA); // Order of the moved bookmarks is not tested. - verifyBookmarkListNoOrder(mBookmarkModel.getChildIDs(folderAA), movedBookmarks); + verifyBookmarkListNoOrder(mBookmarkModel.getChildIds(folderAA), movedBookmarks); } @Test @@ -147,7 +147,7 @@ mBookmarkModel.moveBookmarks(new ArrayList<>(movedBookmarks), folder); // Order of the moved bookmarks is not tested. - verifyBookmarkListNoOrder(mBookmarkModel.getChildIDs(folder), movedBookmarks); + verifyBookmarkListNoOrder(mBookmarkModel.getChildIds(folder), movedBookmarks); } @Test @@ -222,7 +222,7 @@ BookmarkId folderAA = mBookmarkModel.addFolder(folderA, 0, "faa"); // folders and urls expectedChildren.add(folderAA); - verifyBookmarkListNoOrder(mBookmarkModel.getChildIDs(folderA), expectedChildren); + verifyBookmarkListNoOrder(mBookmarkModel.getChildIds(folderA), expectedChildren); } // Moved from BookmarkBridgeTest
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkToolbarTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkToolbarTest.java index 2592921..b6c0135 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkToolbarTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkToolbarTest.java
@@ -120,7 +120,7 @@ .findViewById(R.id.bookmark_toolbar); when(mBookmarkModel.getRootFolderId()).thenReturn(BOOKMARK_ID_ROOT); - when(mBookmarkModel.getTopLevelFolderParentIDs()) + when(mBookmarkModel.getTopLevelFolderParentIds()) .thenReturn(Collections.singletonList(BOOKMARK_ID_ROOT)); BookmarkItem rootBookmarkItem = new BookmarkItem(
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninFirstRunFragmentTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninFirstRunFragmentTest.java index d6a8893..52269f6 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninFirstRunFragmentTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninFirstRunFragmentTest.java
@@ -17,6 +17,7 @@ import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.not; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.notNull; @@ -65,6 +66,7 @@ import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.DoNotBatch; import org.chromium.base.test.util.HistogramWatcher; +import org.chromium.base.test.util.Restriction; import org.chromium.chrome.browser.enterprise.util.EnterpriseInfo; import org.chromium.chrome.browser.enterprise.util.EnterpriseInfo.OwnedState; import org.chromium.chrome.browser.enterprise.util.FakeEnterpriseInfo; @@ -84,6 +86,7 @@ import org.chromium.chrome.browser.signin.services.SigninChecker; import org.chromium.chrome.browser.signin.services.SigninManager; import org.chromium.chrome.browser.ui.signin.fre.SigninFirstRunMediator.LoadPoint; +import org.chromium.chrome.test.AutomotiveContextWrapperTestRule; import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate; import org.chromium.chrome.test.R; import org.chromium.chrome.test.util.ActivityTestUtils; @@ -99,6 +102,7 @@ import org.chromium.content_public.browser.test.NativeLibraryTestUtils; import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.ui.test.util.BlankUiTestActivity; +import org.chromium.ui.test.util.DeviceRestriction; import org.chromium.ui.test.util.NightModeTestUtils; import org.chromium.ui.test.util.ViewUtils; @@ -139,6 +143,9 @@ public final SigninTestRule mSigninTestRule = new SigninTestRule(); @Rule + public AutomotiveContextWrapperTestRule mAutoTestRule = new AutomotiveContextWrapperTestRule(); + + @Rule public final BaseActivityTestRule<BlankUiTestActivity> mActivityTestRule = new BaseActivityTestRule(BlankUiTestActivity.class); @@ -489,6 +496,7 @@ @Test @MediumTest + @Restriction({DeviceRestriction.RESTRICTION_TYPE_NON_AUTO}) public void testSigninWithDefaultAccount() { mSigninTestRule.addAccount(TEST_EMAIL1, FULL_NAME1, GIVEN_NAME1, null); launchActivityWithFragment(); @@ -515,6 +523,80 @@ @Test @MediumTest + public void testContinueButton_automotiveDevice_signInWithDefaultAccount() { + mAutoTestRule.setIsAutomotive(true); + + mSigninTestRule.addAccount(TEST_EMAIL1, FULL_NAME1, GIVEN_NAME1, null); + launchActivityWithFragment(); + final String continueAsText = mActivityTestRule.getActivity().getString( + R.string.sync_promo_continue_as, GIVEN_NAME1); + + // Click and continue to the device lock page + onView(withText(continueAsText)).perform(click()); + CriteriaHelper.pollUiThread(() -> { + return mFragment.getView().findViewById(R.id.device_lock_title).isShown(); + }); + + // Verify that sign-in has not proceeded + verify(mFirstRunPageDelegateMock, never()).acceptTermsOfService(anyBoolean()); + Assert.assertNull(mSigninTestRule.getPrimaryAccount(ConsentLevel.SIGNIN)); + + // Continue past the device lock page + TestThreadUtils.runOnUiThreadBlocking(() -> mFragment.onDeviceLockReady()); + + // ToS should be accepted right away, without waiting for the sign-in to complete. + verify(mFirstRunPageDelegateMock).acceptTermsOfService(true); + + CriteriaHelper.pollUiThread(() -> { + return IdentityServicesProvider.get() + .getIdentityManager(Profile.getLastUsedRegularProfile()) + .hasPrimaryAccount(ConsentLevel.SIGNIN); + }); + final CoreAccountInfo primaryAccount = + mSigninTestRule.getPrimaryAccount(ConsentLevel.SIGNIN); + Assert.assertEquals(TEST_EMAIL1, primaryAccount.getEmail()); + // Sign-in has completed, so the FRE should advance to the next page. + verify(mFirstRunPageDelegateMock).advanceToNextPage(); + verify(mFirstRunPageDelegateMock) + .recordFreProgressHistogram(MobileFreProgress.WELCOME_SIGNIN_WITH_DEFAULT_ACCOUNT); + } + + @Test + @MediumTest + public void testContinueButton_automotiveDevice_dismissSignInFromDeviceLockPage() { + mAutoTestRule.setIsAutomotive(true); + + mSigninTestRule.addAccount(TEST_EMAIL1, FULL_NAME1, GIVEN_NAME1, null); + launchActivityWithFragment(); + final String continueAsText = mActivityTestRule.getActivity().getString( + R.string.sync_promo_continue_as, GIVEN_NAME1); + + // Click and continue to the device lock page + onView(withText(continueAsText)).perform(click()); + CriteriaHelper.pollUiThread(() -> { + return mFragment.getView().findViewById(R.id.device_lock_title).isShown(); + }); + + // Verify that sign-in has not proceeded + verify(mFirstRunPageDelegateMock, never()).acceptTermsOfService(anyBoolean()); + Assert.assertNull(mSigninTestRule.getPrimaryAccount(ConsentLevel.SIGNIN)); + + // Continue past the device lock page + TestThreadUtils.runOnUiThreadBlocking(() -> mFragment.onDeviceLockRefused()); + + CriteriaHelper.pollUiThread(() -> { + return !IdentityServicesProvider.get() + .getIdentityManager(Profile.getLastUsedRegularProfile()) + .hasPrimaryAccount(ConsentLevel.SIGNIN); + }); + verify(mFirstRunPageDelegateMock).acceptTermsOfService(true); + verify(mFirstRunPageDelegateMock).advanceToNextPage(); + verify(mFirstRunPageDelegateMock) + .recordFreProgressHistogram(MobileFreProgress.WELCOME_DISMISS); + } + + @Test + @MediumTest @DisableIf.Build(sdk_is_less_than = VERSION_CODES.Q, message = "https://crbug.com/1434098") public void testSigninWithNonDefaultAccount() { mSigninTestRule.addAccount(TEST_EMAIL1, FULL_NAME1, GIVEN_NAME1, /*avatar=*/null);
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerMediatorTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerMediatorTest.java index b9f4b33..8710d180 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerMediatorTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerMediatorTest.java
@@ -152,7 +152,7 @@ doReturn(true).when(mBookmarkModel).doesBookmarkExist(any()); doReturn(Arrays.asList(mFolderId2, mFolderId3)) .when(mBookmarkModel) - .getChildIDs(mFolderId1); + .getChildIds(mFolderId1); doReturn(mFolderItem1).when(mBookmarkModel).getBookmarkById(mFolderId1); doReturn(mFolderItem2).when(mBookmarkModel).getBookmarkById(mFolderId2); doReturn(mFolderItem3).when(mBookmarkModel).getBookmarkById(mFolderId3); @@ -231,13 +231,13 @@ verify(mBookmarkModel, times(0)).getDesktopFolderId(); verify(mBookmarkModel, times(0)).getMobileFolderId(); verify(mBookmarkModel, times(0)).getOtherFolderId(); - verify(mBookmarkModel, times(0)).getTopLevelFolderIDs(true, false); + verify(mBookmarkModel, times(0)).getTopLevelFolderIds(true, false); finishLoading(); verify(mBookmarkModel, times(1)).getDesktopFolderId(); verify(mBookmarkModel, times(1)).getMobileFolderId(); verify(mBookmarkModel, times(1)).getOtherFolderId(); - verify(mBookmarkModel, times(1)).getTopLevelFolderIDs(true, false); + verify(mBookmarkModel, times(1)).getTopLevelFolderIds(true, false); } @Test @@ -338,7 +338,7 @@ mMediator.openFolder(mFolderId1); assertEquals(2, mModelList.size()); - doReturn(Arrays.asList(mFolderId3)).when(mBookmarkModel).getChildIDs(mFolderId1); + doReturn(Arrays.asList(mFolderId3)).when(mBookmarkModel).getChildIds(mFolderId1); verify(mBookmarkModel, times(2)) .addObserver(mBookmarkModelObserverArgumentCaptor.capture()); for (BookmarkModelObserver bookmarkModelObserver :
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkToolbarMediatorTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkToolbarMediatorTest.java index 751ff8c..2af82b2 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkToolbarMediatorTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkToolbarMediatorTest.java
@@ -211,7 +211,7 @@ public void onFolderStateSet_EmptyTitleWhenChildOfRoot() { ArrayList<BookmarkId> topLevelFolders = new ArrayList<>(); topLevelFolders.add(mBookmarkId); - doReturn(topLevelFolders).when(mBookmarkModel).getTopLevelFolderParentIDs(); + doReturn(topLevelFolders).when(mBookmarkModel).getTopLevelFolderParentIds(); doReturn(mBookmarkId).when(mBookmarkItem).getParentId(); doReturn(true).when(mBookmarkItem).isEditable(); doReturn("").when(mBookmarkItem).getTitle();
diff --git a/chrome/app/os_settings_strings.grdp b/chrome/app/os_settings_strings.grdp index a1151e7..046cba0 100644 --- a/chrome/app/os_settings_strings.grdp +++ b/chrome/app/os_settings_strings.grdp
@@ -2930,6 +2930,9 @@ <message name="IDS_SETTINGS_TOUCHPAD_HAPTIC_FIRM_CLICK_LABEL" desc="In Device Settings, the text under the right (more sensitive) side of the slider for the touchpad haptic click sensitivity."> Firm </message> + <message name="IDS_SETTINGS_LEARN_MORE_LABEL" translateable="false" desc="In Device Settings, the learn more label for the cr toggle button."> + Learn more + </message> <!-- Printing Page (OS Settings)--> <message name="IDS_SETTINGS_PRINT_AND_SCAN" desc="Title of the printing and scanning page and navigation item to get there.">
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp index f71c0261..5250bf6a 100644 --- a/chrome/app/settings_strings.grdp +++ b/chrome/app/settings_strings.grdp
@@ -4123,6 +4123,18 @@ <message name="IDS_SETTINGS_NO_HID_DEVICES_FOUND" desc="Explanation for not showing HID devices in site settings."> No HID devices found </message> + <message name="IDS_SETTINGS_RESET_BLUETOOTH_CONFIRMATION" desc="Text for the dialog that warns about resetting all permissions for all Bluetooth devices."> + Reset all Bluetooth device permissions? + </message> + <message name="IDS_SETTINGS_RESET_HID_CONFIRMATION" desc="Text for the dialog that warns about resetting all permissions for all HID devices."> + Reset all HID device permissions? + </message> + <message name="IDS_SETTINGS_RESET_SERIAL_PORTS_CONFIRMATION" desc="Text for the dialog that warns about resetting all permissions for all serial ports."> + Reset all Serial port permisions? + </message> + <message name="IDS_SETTINGS_RESET_USB_CONFIRMATION" desc="Text for the dialog that warns about resetting all permissions for all USB devices."> + Reset all USB device permissions? + </message> <message name="IDS_SETTINGS_ADD_SITE_TITLE" desc="Title for the Add Site dialog"> Add a site </message>
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_RESET_BLUETOOTH_CONFIRMATION.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_RESET_BLUETOOTH_CONFIRMATION.png.sha1 new file mode 100644 index 0000000..f530e47ed --- /dev/null +++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_RESET_BLUETOOTH_CONFIRMATION.png.sha1
@@ -0,0 +1 @@ +0728ea4b78862bab9ebbb1d10e4244a993bdd3d8 \ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_RESET_HID_CONFIRMATION.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_RESET_HID_CONFIRMATION.png.sha1 new file mode 100644 index 0000000..f530e47ed --- /dev/null +++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_RESET_HID_CONFIRMATION.png.sha1
@@ -0,0 +1 @@ +0728ea4b78862bab9ebbb1d10e4244a993bdd3d8 \ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_RESET_SERIAL_PORTS_CONFIRMATION.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_RESET_SERIAL_PORTS_CONFIRMATION.png.sha1 new file mode 100644 index 0000000..f530e47ed --- /dev/null +++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_RESET_SERIAL_PORTS_CONFIRMATION.png.sha1
@@ -0,0 +1 @@ +0728ea4b78862bab9ebbb1d10e4244a993bdd3d8 \ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_RESET_USB_CONFIRMATION.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_RESET_USB_CONFIRMATION.png.sha1 new file mode 100644 index 0000000..f530e47ed --- /dev/null +++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_RESET_USB_CONFIRMATION.png.sha1
@@ -0,0 +1 @@ +0728ea4b78862bab9ebbb1d10e4244a993bdd3d8 \ No newline at end of file
diff --git a/chrome/browser/ash/accessibility/spoken_feedback_browsertest.cc b/chrome/browser/ash/accessibility/spoken_feedback_browsertest.cc index e3954247..812385f 100644 --- a/chrome/browser/ash/accessibility/spoken_feedback_browsertest.cc +++ b/chrome/browser/ash/accessibility/spoken_feedback_browsertest.cc
@@ -969,13 +969,15 @@ sm_.Call([this]() { SendKeyPressWithShift(ui::VKEY_TAB); }); sm_.ExpectSpeech("Battery"); + // Guest mode sign out button. + if (GetParam() == kTestAsGuestUser) { + sm_.Call([this]() { SendKeyPressWithShift(ui::VKEY_TAB); }); + sm_.ExpectSpeech("Exit guest"); + } + // Shutdown button. sm_.Call([this]() { SendKeyPressWithShift(ui::VKEY_TAB); }); - if (base::FeatureList::IsEnabled(features::kQsRevamp)) { - sm_.ExpectSpeech("Power menu"); - } else { - sm_.ExpectSpeech("Shut down"); - } + sm_.ExpectSpeech("Power menu"); sm_.ExpectSpeech("Button"); sm_.Replay(); @@ -994,11 +996,7 @@ // Shutdown button. sm_.Call([this]() { SendKeyPressWithSearch(ui::VKEY_B); }); - if (base::FeatureList::IsEnabled(features::kQsRevamp)) { - sm_.ExpectSpeech("Power menu"); - } else { - sm_.ExpectSpeech("Shut down"); - } + sm_.ExpectSpeech("Shut down"); sm_.ExpectSpeech("Button"); sm_.Replay();
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/connection.cc b/chrome/browser/ash/login/oobe_quick_start/connectivity/connection.cc index 34b0bfd..b5db71f6 100644 --- a/chrome/browser/ash/login/oobe_quick_start/connectivity/connection.cc +++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/connection.cc
@@ -31,7 +31,7 @@ RandomSessionId session_id, SharedSecret shared_secret, SharedSecret secondary_shared_secret, - base::OnceClosure on_connection_closed, + ConnectionClosedCallback on_connection_closed, ConnectionAuthenticatedCallback on_connection_authenticated) { auto nonce_generator = std::make_unique<NonceGenerator>(); return std::make_unique<Connection>( @@ -52,7 +52,7 @@ SharedSecret shared_secret, SharedSecret secondary_shared_secret, std::unique_ptr<NonceGenerator> nonce_generator, - base::OnceClosure on_connection_closed, + ConnectionClosedCallback on_connection_closed, ConnectionAuthenticatedCallback on_connection_authenticated) : nearby_connection_(nearby_connection), random_session_id_(session_id), @@ -226,7 +226,9 @@ } void Connection::OnConnectionClosed() { - std::move(on_connection_closed_).Run(); + // TODO (b/278898402): Handle other connection closed reasons. + std::move(on_connection_closed_) + .Run(TargetDeviceConnectionBroker::ConnectionClosedReason::kComplete); } } // namespace ash::quick_start
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/connection.h b/chrome/browser/ash/login/oobe_quick_start/connectivity/connection.h index 82760bba0..6b50a0e 100644 --- a/chrome/browser/ash/login/oobe_quick_start/connectivity/connection.h +++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/connection.h
@@ -37,6 +37,8 @@ using ConnectionAuthenticatedCallback = base::OnceCallback<void( base::WeakPtr<TargetDeviceConnectionBroker::AuthenticatedConnection>)>; + using ConnectionClosedCallback = base::OnceCallback<void( + TargetDeviceConnectionBroker::ConnectionClosedReason)>; class Factory { public: Factory() = default; @@ -49,7 +51,7 @@ RandomSessionId session_id, SharedSecret shared_secret, SharedSecret secondary_shared_secret, - base::OnceClosure on_connection_closed, + ConnectionClosedCallback on_connection_closed, ConnectionAuthenticatedCallback on_connection_authenticated); }; @@ -68,7 +70,7 @@ SharedSecret shared_secret, SharedSecret secondary_shared_secret, std::unique_ptr<NonceGenerator> nonce_generator, - base::OnceClosure on_connection_closed, + ConnectionClosedCallback on_connection_closed, ConnectionAuthenticatedCallback on_connection_authenticated); Connection(const Connection&) = delete; @@ -140,7 +142,7 @@ SharedSecret shared_secret_; SharedSecret secondary_shared_secret_; std::unique_ptr<NonceGenerator> nonce_generator_; - base::OnceClosure on_connection_closed_; + ConnectionClosedCallback on_connection_closed_; bool authenticated_ = false; ConnectionAuthenticatedCallback on_connection_authenticated_; std::string challenge_b64url_;
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/connection_unittest.cc b/chrome/browser/ash/login/oobe_quick_start/connectivity/connection_unittest.cc index a9700d99..0681aa5 100644 --- a/chrome/browser/ash/login/oobe_quick_start/connectivity/connection_unittest.cc +++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/connection_unittest.cc
@@ -396,7 +396,8 @@ } TEST_F(ConnectionTest, TestDisconnectionTriggersListener) { - base::test::TestFuture<void> future; + base::test::TestFuture<TargetDeviceConnectionBroker::ConnectionClosedReason> + future; std::unique_ptr<Connection> connection_under_test = std::make_unique<Connection>( fake_nearby_connection_.get(), session_id_, kSharedSecret, @@ -409,6 +410,8 @@ fake_nearby_connection_->Close(); ASSERT_TRUE(future.IsReady()); + ASSERT_EQ(future.Get(), + TargetDeviceConnectionBroker::ConnectionClosedReason::kComplete); } TEST_F(ConnectionTest, InitiateHandshake) {
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_impl_unittest.cc b/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_impl_unittest.cc index 785a090..e84eb59 100644 --- a/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_impl_unittest.cc +++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_impl_unittest.cc
@@ -291,7 +291,7 @@ RandomSessionId session_id, SharedSecret shared_secret, SharedSecret secondary_shared_secret, - base::OnceClosure on_connection_closed, + ConnectionClosedCallback on_connection_closed, ConnectionAuthenticatedCallback on_connection_authenticated) override { auto connection = std::make_unique<FakeConnection>( nearby_connection, session_id, shared_secret, secondary_shared_secret, @@ -308,7 +308,7 @@ RandomSessionId session_id, SharedSecret shared_secret, SharedSecret secondary_shared_secret, - base::OnceClosure on_connection_closed, + ConnectionClosedCallback on_connection_closed, ConnectionAuthenticatedCallback on_connection_authenticated) : Connection(nearby_connection, session_id,
diff --git a/chrome/browser/bookmarks/android/bookmark_bridge.cc b/chrome/browser/bookmarks/android/bookmark_bridge.cc index 3db1322..5079d723 100644 --- a/chrome/browser/bookmarks/android/bookmark_bridge.cc +++ b/chrome/browser/bookmarks/android/bookmark_bridge.cc
@@ -272,7 +272,7 @@ DCHECK(partner_bookmarks_shim_->IsLoaded()); } -ScopedJavaLocalRef<jobject> BookmarkBridge::GetBookmarkByID( +ScopedJavaLocalRef<jobject> BookmarkBridge::GetBookmarkById( JNIEnv* env, const JavaParamRef<jobject>& obj, jlong id, @@ -289,7 +289,7 @@ return bookmark_model_->IsDoingExtensiveChanges(); } -void BookmarkBridge::GetTopLevelFolderParentIDs( +void BookmarkBridge::GetTopLevelFolderParentIds( JNIEnv* env, const JavaParamRef<jobject>& obj, const JavaParamRef<jobject>& j_result_obj) { @@ -299,7 +299,7 @@ GetBookmarkType(bookmark_model_->root_node())); } -void BookmarkBridge::GetTopLevelFolderIDs( +void BookmarkBridge::GetTopLevelFolderIds( JNIEnv* env, const JavaParamRef<jobject>& obj, jboolean get_special, @@ -488,7 +488,7 @@ return static_cast<jint>(node->children().size()); } -void BookmarkBridge::GetChildIDs(JNIEnv* env, +void BookmarkBridge::GetChildIds(JNIEnv* env, const JavaParamRef<jobject>& obj, jlong id, jint type,
diff --git a/chrome/browser/bookmarks/android/bookmark_bridge.h b/chrome/browser/bookmarks/android/bookmark_bridge.h index 91d903e..5c06a98 100644 --- a/chrome/browser/bookmarks/android/bookmark_bridge.h +++ b/chrome/browser/bookmarks/android/bookmark_bridge.h
@@ -78,18 +78,18 @@ JNIEnv* env, const base::android::JavaParamRef<jobject>& obj); - base::android::ScopedJavaLocalRef<jobject> GetBookmarkByID( + base::android::ScopedJavaLocalRef<jobject> GetBookmarkById( JNIEnv* env, const base::android::JavaParamRef<jobject>& obj, jlong id, jint type); - void GetTopLevelFolderParentIDs( + void GetTopLevelFolderParentIds( JNIEnv* env, const base::android::JavaParamRef<jobject>& obj, const base::android::JavaParamRef<jobject>& j_result_obj); - void GetTopLevelFolderIDs( + void GetTopLevelFolderIds( JNIEnv* env, const base::android::JavaParamRef<jobject>& obj, jboolean get_special, @@ -132,7 +132,7 @@ jlong id, jint type); - void GetChildIDs(JNIEnv* env, + void GetChildIds(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj, jlong id, jint type,
diff --git a/chrome/browser/devtools/devtools_browsertest.cc b/chrome/browser/devtools/devtools_browsertest.cc index 77c22ca7..8e1630d 100644 --- a/chrome/browser/devtools/devtools_browsertest.cc +++ b/chrome/browser/devtools/devtools_browsertest.cc
@@ -180,24 +180,20 @@ const char* method, T... args) { WebContents* wc = DevToolsWindowTesting::Get(window)->main_web_contents(); - std::string result; const char* args_array[] = {method, args...}; std::ostringstream script; script << "uiTests.dispatchOnTestSuite(["; for (size_t i = 0; i < std::size(args_array); ++i) script << (i ? "," : "") << '\"' << args_array[i] << '\"'; script << "])"; - ASSERT_TRUE( - content::ExecuteScriptAndExtractString(wc, script.str(), &result)); - EXPECT_EQ("[OK]", result); + EXPECT_EQ("[OK]", content::EvalJs(wc, script.str(), + content::EXECUTE_SCRIPT_USE_MANUAL_REPLY)); } void LoadLegacyFilesInFrontend(DevToolsWindow* window) { - std::string result; WebContents* wc = DevToolsWindowTesting::Get(window)->main_web_contents(); - ASSERT_TRUE(content::ExecuteScriptAndExtractString( - wc, "uiTests.setupLegacyFilesForTest();", &result)); - ASSERT_EQ("[OK]", result); + ASSERT_EQ("[OK]", content::EvalJs(wc, "uiTests.setupLegacyFilesForTest();", + content::EXECUTE_SCRIPT_USE_MANUAL_REPLY)); } template <typename... T> @@ -3093,14 +3089,11 @@ class DevToolsLocalizationTest : public DevToolsTest { public: bool NavigatorLanguageMatches(const std::string& expected_locale) { - bool result = false; - const bool execute_result = content::ExecuteScriptAndExtractBool( - main_web_contents(), - "window.domAutomationController.send(window.navigator.language === " - "'" + - expected_locale + "')", - &result); - return execute_result && result; + return content::EvalJs(main_web_contents(), + "window.navigator.language === " + "'" + + expected_locale + "'") + .ExtractBool(); } };
diff --git a/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.cc b/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.cc index 215c183..0859b06b 100644 --- a/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.cc +++ b/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.cc
@@ -312,9 +312,16 @@ delegate->RunCallback(); } - // Upload service callback will delete the delegate. - if (work_being_done) + // If all requests are already done, just let `delegate` go out of scope. + if (delegate->all_work_done_) { + return; + } + + // ... otherwise, let the last response from the upload service callback + // delete the delegate when there is no more work. + if (work_being_done) { delegate.release(); + } } // static @@ -721,6 +728,15 @@ AckAllRequests(); + if (run_callback_called_ && !dialog_ && *UIEnabledStorage()) { + // This code path implies that RunCallback has already been called, + // and that we are racing against a non-blocking scan. In such a + // case, we let the other caller handle deletion of `this`, and let + // them know no more work is needed. + all_work_done_ = true; + return; + } + if (!UpdateDialog() && data_uploaded_) { // No UI was shown. Delete |this| to cleanup, unless UploadData isn't done // yet. @@ -729,8 +745,10 @@ } void ContentAnalysisDelegate::RunCallback() { - if (callback_.is_null()) + if (callback_.is_null() || run_callback_called_) { return; + } + run_callback_called_ = true; std::move(callback_).Run(data_, result_);
diff --git a/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.h b/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.h index 9382e196..3236937 100644 --- a/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.h +++ b/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.h
@@ -432,6 +432,16 @@ // Result updated in ImageRequestCallback(). RequestHandlerResult image_request_result_; + // Indicates that RunCallback has already been called. This is used to + // prevent race conditions when a UI thread task blocked on a user interaction + // is racing against a scanning request. + bool run_callback_called_ = false; + + // Indicates that `this` can be deleted right away. This is used with + // `run_callback_called_` to handle race conditions where non-blocking scans + // should wait before deleting `this`. + bool all_work_done_ = false; + base::TimeTicks upload_start_time_; base::WeakPtrFactory<ContentAnalysisDelegate> weak_ptr_factory_{this};
diff --git a/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.cc b/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.cc index 4507e319..43ab33f 100644 --- a/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.cc +++ b/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.cc
@@ -796,6 +796,10 @@ DCHECK(browser); web_app::CreateWebAppFromCurrentWebContents( browser, web_app::WebAppInstallFlow::kInstallSite); + base::UmaHistogramEnumeration( + "PasswordManager.ShortcutMetric", + password_manager::metrics_util::PasswordManagerShortcutMetric:: + kAddShortcutClicked); } void PasswordsPrivateDelegateImpl::ShowExportedFileInShell( @@ -964,6 +968,10 @@ base::SequencedTaskRunner::GetCurrentDefault()->PostDelayedTask( FROM_HERE, base::BindOnce(&MaybeShowProfileSwitchIPH, profile_), base::Seconds(1)); + base::UmaHistogramEnumeration( + "PasswordManager.ShortcutMetric", + password_manager::metrics_util::PasswordManagerShortcutMetric:: + kShortcutInstalled); } void PasswordsPrivateDelegateImpl::OnWebAppInstallManagerDestroyed() {
diff --git a/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl_unittest.cc b/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl_unittest.cc index ef9e834d2..9060a6b 100644 --- a/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl_unittest.cc +++ b/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl_unittest.cc
@@ -35,6 +35,7 @@ #include "chrome/browser/web_applications/test/fake_web_app_provider.h" #include "chrome/browser/web_applications/test/web_app_test.h" #include "chrome/browser/web_applications/web_app_command_manager.h" +#include "chrome/browser/web_applications/web_app_id_constants.h" #include "chrome/browser/webapps/chrome_webapps_client.h" #include "chrome/common/extensions/api/passwords_private.h" #include "chrome/test/base/test_browser_window.h" @@ -1365,6 +1366,7 @@ #endif TEST_F(PasswordsPrivateDelegateImplTest, ShowAddShortcutDialog) { + base::HistogramTester histogram_tester; // Set up a browser instance and simulate a navigation. Browser::CreateParams params(profile(), /*user_gesture=*/true); params.type = Browser::TYPE_NORMAL; @@ -1403,6 +1405,8 @@ // Close the browser prior to TearDown. browser->tab_strip_model()->CloseAllTabs(); + + histogram_tester.ExpectUniqueSample("PasswordManager.ShortcutMetric", 0, 1); } TEST_F(PasswordsPrivateDelegateImplTest, GetCredentialGroups) { @@ -1439,4 +1443,20 @@ PasswordUiEntryDataEquals(testing::ByRef(expected_entry2)))); } +TEST_F(PasswordsPrivateDelegateImplTest, PasswordManagerAppInstalled) { + base::HistogramTester histogram_tester; + auto delegate = CreateDelegate(); + static_cast<web_app::WebAppInstallManagerObserver*>(delegate.get()) + ->OnWebAppInstalledWithOsHooks(web_app::kPasswordManagerAppId); + + EXPECT_THAT(histogram_tester.GetAllSamples("PasswordManager.ShortcutMetric"), + base::BucketsAre(base::Bucket(1, 1))); + + // Check that installing other app doesn't get recorded. + static_cast<web_app::WebAppInstallManagerObserver*>(delegate.get()) + ->OnWebAppInstalledWithOsHooks(web_app::kYoutubeMusicAppId); + + histogram_tester.ExpectUniqueSample("PasswordManager.ShortcutMetric", 1, 1); +} + } // namespace extensions
diff --git a/chrome/browser/extensions/api/runtime/runtime_apitest.cc b/chrome/browser/extensions/api/runtime/runtime_apitest.cc index 713dfba..b6539a3 100644 --- a/chrome/browser/extensions/api/runtime/runtime_apitest.cc +++ b/chrome/browser/extensions/api/runtime/runtime_apitest.cc
@@ -36,7 +36,6 @@ #include "extensions/browser/offscreen_document_host.h" #include "extensions/browser/process_manager.h" #include "extensions/browser/test_extension_registry_observer.h" -#include "extensions/common/extension_features.h" #include "extensions/common/features/feature_channel.h" #include "extensions/test/extension_test_message_listener.h" #include "extensions/test/result_catcher.h" @@ -612,10 +611,7 @@ class RuntimeGetContextsApiTest : public ExtensionApiTest { public: - RuntimeGetContextsApiTest() { - feature_list_.InitAndEnableFeature( - extensions_features::kApiRuntimeGetContexts); - } + RuntimeGetContextsApiTest() = default; RuntimeGetContextsApiTest(const RuntimeGetContextsApiTest&) = delete; RuntimeGetContextsApiTest& operator=(const RuntimeGetContextsApiTest&) = delete; @@ -727,7 +723,6 @@ raw_ptr<const Extension, DanglingUntriaged> extension_ = nullptr; TestExtensionDir test_dir_; ScopedCurrentChannel channel_override_{version_info::Channel::UNKNOWN}; - base::test::ScopedFeatureList feature_list_; }; // Tests retrieving the background service worker context using
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc index af27bf4..5362fb7 100644 --- a/chrome/browser/flags/android/chrome_feature_list.cc +++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -274,6 +274,7 @@ &kReachedCodeProfiler, &kReaderModeInCCT, &kRecordSuppressionMetrics, + &kReduceToolbarUpdatesForSameDocNavigations, &kReengagementNotification, &kRelatedSearches, &kReportParentalControlSitesChild, @@ -892,6 +893,10 @@ "RecordSuppressionMetrics", base::FEATURE_ENABLED_BY_DEFAULT); +BASE_FEATURE(kReduceToolbarUpdatesForSameDocNavigations, + "ReduceToolbarUpdatesForSameDocNavigations", + base::FEATURE_ENABLED_BY_DEFAULT); + BASE_FEATURE(kReengagementNotification, "ReengagementNotification", base::FEATURE_DISABLED_BY_DEFAULT);
diff --git a/chrome/browser/flags/android/chrome_feature_list.h b/chrome/browser/flags/android/chrome_feature_list.h index 9ac909b..f2773d8 100644 --- a/chrome/browser/flags/android/chrome_feature_list.h +++ b/chrome/browser/flags/android/chrome_feature_list.h
@@ -188,6 +188,7 @@ BASE_DECLARE_FEATURE(kTrustedWebActivityQualityEnforcementForced); BASE_DECLARE_FEATURE(kTrustedWebActivityQualityEnforcementWarning); BASE_DECLARE_FEATURE(kResizeOnlyActiveTab); +BASE_DECLARE_FEATURE(kReduceToolbarUpdatesForSameDocNavigations); BASE_DECLARE_FEATURE(kSpareTab); BASE_DECLARE_FEATURE(kStartSurfaceAndroid); BASE_DECLARE_FEATURE(kStartSurfaceOnTablet);
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java index 387b7ca5..261a76c 100644 --- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java +++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
@@ -440,6 +440,8 @@ public static final String READER_MODE_IN_CCT = "ReaderModeInCCT"; public static final String RECORD_SUPPRESSION_METRICS = "RecordSuppressionMetrics"; public static final String RECOVER_FROM_NEVER_SAVE_ANDROID = "RecoverFromNeverSaveAndroid"; + public static final String REDUCE_TOOLBAR_UPDATES_FOR_SAME_DOC_NAVIGATIONS = + "ReduceToolbarUpdatesForSameDocNavigations"; public static final String REENGAGEMENT_NOTIFICATION = "ReengagementNotification"; public static final String RELATED_SEARCHES = "RelatedSearches"; public static final String REQUEST_DESKTOP_SITE_DEFAULTS = "RequestDesktopSiteDefaults";
diff --git a/chrome/browser/new_tab_page/modules/history_clusters/cart/cart_processor.cc b/chrome/browser/new_tab_page/modules/history_clusters/cart/cart_processor.cc index bcbd5a0..13725c3 100644 --- a/chrome/browser/new_tab_page/modules/history_clusters/cart/cart_processor.cc +++ b/chrome/browser/new_tab_page/modules/history_clusters/cart/cart_processor.cc
@@ -32,6 +32,7 @@ cart_mojom->relative_date = base::UTF16ToUTF8(ui::TimeFormat::Simple( ui::TimeFormat::FORMAT_ELAPSED, ui::TimeFormat::LENGTH_SHORT, base::Time::Now() - base::Time::FromDoubleT(cart.second.timestamp()))); + cart_mojom->discount_text = cart.second.discount_info().discount_text(); return cart_mojom; }
diff --git a/chrome/browser/new_tab_page/modules/history_clusters/cart/cart_processor_unittest.cc b/chrome/browser/new_tab_page/modules/history_clusters/cart/cart_processor_unittest.cc index 89c934b..81e202a5 100644 --- a/chrome/browser/new_tab_page/modules/history_clusters/cart/cart_processor_unittest.cc +++ b/chrome/browser/new_tab_page/modules/history_clusters/cart/cart_processor_unittest.cc
@@ -25,6 +25,7 @@ const char kMockProductImageURLA[] = "https://www.foo.com/imageA"; const char kMockProductImageURLB[] = "https://www.foo.com/imageB"; const char kMockMerchantPageURL[] = "https://www.foo.com/test"; +const char kMockMerchantDiscountText[] = "15% off"; class MockCartService : public CartService { public: @@ -193,6 +194,8 @@ cart_proto.set_merchant_cart_url(kMockMerchantCartURL); cart_proto.add_product_image_urls(kMockProductImageURLA); cart_proto.add_product_image_urls(kMockProductImageURLB); + cart_proto.mutable_discount_info()->set_discount_text( + kMockMerchantDiscountText); std::vector<CartDB::KeyAndValue> carts = {{kMockMerchantDomain, cart_proto}}; EXPECT_CALL(cart_service, LoadAllActiveCarts(testing::_)) .Times(1) @@ -222,6 +225,7 @@ ASSERT_EQ(cart_mojom->product_image_urls.size(), 2u); ASSERT_EQ(cart_mojom->product_image_urls[0], GURL(kMockProductImageURLA)); ASSERT_EQ(cart_mojom->product_image_urls[1], GURL(kMockProductImageURLB)); + ASSERT_EQ(cart_mojom->discount_text, kMockMerchantDiscountText); } TEST_F(CartProcessorTest, TestFakeCart) {
diff --git a/chrome/browser/password_manager/web_app_profile_switcher.cc b/chrome/browser/password_manager/web_app_profile_switcher.cc index c0e1e78..3495a2d 100644 --- a/chrome/browser/password_manager/web_app_profile_switcher.cc +++ b/chrome/browser/password_manager/web_app_profile_switcher.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/password_manager/web_app_profile_switcher.h" +#include "base/metrics/histogram_macros.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/profiles/profile_window.h" #include "chrome/browser/ui/browser_finder.h" @@ -13,9 +14,11 @@ #include "chrome/browser/web_applications/web_app_command_scheduler.h" #include "chrome/browser/web_applications/web_app_helpers.h" #include "chrome/browser/web_applications/web_app_icon_manager.h" +#include "chrome/browser/web_applications/web_app_id_constants.h" #include "chrome/browser/web_applications/web_app_install_info.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/browser/web_applications/web_app_registrar.h" +#include "components/password_manager/core/browser/password_manager_metrics_util.h" #include "components/webapps/browser/install_result_code.h" #include "content/public/browser/browser_thread.h" @@ -55,6 +58,13 @@ &WebAppProfileSwitcher::QueryProfileWebAppRegistryToOpenWebApp, weak_factory_.GetWeakPtr()); profiles::LoadProfileAsync(profile_to_open, std::move(open_web_app_callback)); + + if (app_id_ == web_app::kPasswordManagerAppId) { + base::UmaHistogramEnumeration( + "PasswordManager.ShortcutMetric", + password_manager::metrics_util::PasswordManagerShortcutMetric:: + kProfileSwitched); + } } void WebAppProfileSwitcher::OnProfileWillBeDestroyed(Profile* profile) {
diff --git a/chrome/browser/password_manager/web_app_profile_switcher_interactive_uitest.cc b/chrome/browser/password_manager/web_app_profile_switcher_interactive_uitest.cc index 015ae6e..3adea83 100644 --- a/chrome/browser/password_manager/web_app_profile_switcher_interactive_uitest.cc +++ b/chrome/browser/password_manager/web_app_profile_switcher_interactive_uitest.cc
@@ -20,6 +20,7 @@ #include "chrome/browser/web_applications/test/web_app_install_test_utils.h" #include "chrome/browser/web_applications/test/web_app_test_utils.h" #include "chrome/browser/web_applications/web_app_helpers.h" +#include "chrome/browser/web_applications/web_app_id_constants.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/interactive_test_utils.h" @@ -143,14 +144,16 @@ IN_PROC_BROWSER_TEST_F(WebAppProfileSwitcherBrowserTest, SwitchWebAppProfileActivateWindowOnly) { + base::HistogramTester histogram_tester; Profile* first_profile = profile(); InstallAppForProfile(first_profile, GetTestWebAppInstallInfo()); // Launch the app for the first profile. - web_app::LaunchWebAppBrowserAndWait(first_profile, GetTestWebAppId()); + web_app::LaunchWebAppBrowserAndWait(first_profile, + web_app::kPasswordManagerAppId); Browser* first_profile_app_browser = - web_app::AppBrowserController::FindForWebApp(*first_profile, - GetTestWebAppId()); + web_app::AppBrowserController::FindForWebApp( + *first_profile, web_app::kPasswordManagerAppId); ASSERT_TRUE(first_profile_app_browser); ASSERT_EQ(chrome::FindAllTabbedBrowsersWithProfile(first_profile).size(), 1U); @@ -158,23 +161,28 @@ Profile* second_profile = CreateAdditionalProfile(); InstallAppForProfile(second_profile, GetTestWebAppInstallInfo()); // Launch the app. - web_app::LaunchWebAppBrowserAndWait(second_profile, GetTestWebAppId()); + web_app::LaunchWebAppBrowserAndWait(second_profile, + web_app::kPasswordManagerAppId); Browser* second_profile_app_browser = - web_app::AppBrowserController::FindForWebApp(*second_profile, - GetTestWebAppId()); + web_app::AppBrowserController::FindForWebApp( + *second_profile, web_app::kPasswordManagerAppId); ASSERT_TRUE(second_profile_app_browser); EXPECT_EQ(chrome::FindLastActive(), second_profile_app_browser); // Switch to the first profile from the second. base::test::TestFuture<void> profile_switch_complete; - WebAppProfileSwitcher profile_switcher(GetTestWebAppId(), *second_profile, + WebAppProfileSwitcher profile_switcher(web_app::kPasswordManagerAppId, + *second_profile, profile_switch_complete.GetCallback()); profile_switcher.SwitchToProfile(first_profile->GetPath()); ui_test_utils::BrowserActivationWaiter(first_profile_app_browser) .WaitForActivation(); EXPECT_TRUE(profile_switch_complete.Wait()); - // Check that there is only one browser for the first_profile and it's active. + // Check that there is only one browser for the first_profile and it's active. ASSERT_EQ(chrome::FindAllTabbedBrowsersWithProfile(first_profile).size(), 1U); EXPECT_EQ(chrome::FindBrowserWithActiveWindow(), first_profile_app_browser); + + EXPECT_THAT(histogram_tester.GetAllSamples("PasswordManager.ShortcutMetric"), + base::BucketsAre(base::Bucket(2, 1))); }
diff --git a/chrome/browser/renderer_host/chrome_render_widget_host_view_mac_delegate.h b/chrome/browser/renderer_host/chrome_render_widget_host_view_mac_delegate.h index 1f33ea5..ee322f3 100644 --- a/chrome/browser/renderer_host/chrome_render_widget_host_view_mac_delegate.h +++ b/chrome/browser/renderer_host/chrome_render_widget_host_view_mac_delegate.h
@@ -5,26 +5,16 @@ #ifndef CHROME_BROWSER_RENDERER_HOST_CHROME_RENDER_WIDGET_HOST_VIEW_MAC_DELEGATE_H_ #define CHROME_BROWSER_RENDERER_HOST_CHROME_RENDER_WIDGET_HOST_VIEW_MAC_DELEGATE_H_ -#include "base/memory/raw_ptr.h" - #import <Cocoa/Cocoa.h> -#include "base/mac/scoped_nsobject.h" #import "content/public/browser/render_widget_host_view_mac_delegate.h" namespace content { class RenderWidgetHost; } -@class HistorySwiper; @interface ChromeRenderWidgetHostViewMacDelegate - : NSObject<RenderWidgetHostViewMacDelegate> { - @private - raw_ptr<content::RenderWidgetHost> _renderWidgetHost; // weak - - // Responsible for 2-finger swipes history navigation. - base::scoped_nsobject<HistorySwiper> _historySwiper; -} + : NSObject <RenderWidgetHostViewMacDelegate> - (instancetype)initWithRenderWidgetHost: (content::RenderWidgetHost*)renderWidgetHost;
diff --git a/chrome/browser/renderer_host/chrome_render_widget_host_view_mac_delegate.mm b/chrome/browser/renderer_host/chrome_render_widget_host_view_mac_delegate.mm index 0610b7b..bfd77ff3 100644 --- a/chrome/browser/renderer_host/chrome_render_widget_host_view_mac_delegate.mm +++ b/chrome/browser/renderer_host/chrome_render_widget_host_view_mac_delegate.mm
@@ -7,6 +7,7 @@ #include <cmath> #include "base/auto_reset.h" +#include "base/mac/scoped_nsobject.h" #include "base/strings/sys_string_conversions.h" #include "chrome/browser/devtools/devtools_window.h" #include "chrome/browser/profiles/profile.h" @@ -30,12 +31,24 @@ #include "mojo/public/cpp/bindings/remote.h" #include "services/service_manager/public/cpp/interface_provider.h" -using content::RenderViewHost; - @interface ChromeRenderWidgetHostViewMacDelegate () <HistorySwiperDelegate> + +@property(readonly) content::WebContents* webContents; +@property(readonly) NSView* nsView; +@property(readonly) PrefService* prefService; + @end @implementation ChromeRenderWidgetHostViewMacDelegate { + // The widget host (process + routing IDs) that this delegate is managing. + int32_t _widgetProcessId; + int32_t _widgetRoutingId; + + // Responsible for 2-finger swipes history navigation. + base::scoped_nsobject<HistorySwiper> _historySwiper; + + // A boolean set to true while resigning first responder status, to avoid + // infinite recursion in the case of reentrance. BOOL _resigningFirstResponder; } @@ -43,7 +56,8 @@ (content::RenderWidgetHost*)renderWidgetHost { self = [super init]; if (self) { - _renderWidgetHost = renderWidgetHost; + _widgetProcessId = renderWidgetHost->GetProcess()->GetID(); + _widgetRoutingId = renderWidgetHost->GetRoutingID(); _historySwiper.reset([[HistorySwiper alloc] initWithDelegate:self]); } return self; @@ -54,6 +68,50 @@ [super dealloc]; } +- (content::WebContents*)webContents { + content::RenderWidgetHost* renderWidgetHost = + content::RenderWidgetHost::FromID(_widgetProcessId, _widgetRoutingId); + if (!renderWidgetHost) { + return nullptr; + } + + content::RenderViewHost* renderViewHost = + content::RenderViewHost::From(renderWidgetHost); + if (!renderViewHost) { + return nullptr; + } + + return content::WebContents::FromRenderViewHost(renderViewHost); +} + +- (NSView*)nsView { + content::RenderWidgetHost* renderWidgetHost = + content::RenderWidgetHost::FromID(_widgetProcessId, _widgetRoutingId); + if (!renderWidgetHost) { + return nil; + } + + content::RenderWidgetHostView* renderWidgetHostView = + renderWidgetHost->GetView(); + if (!renderWidgetHostView) { + return nil; + } + + return renderWidgetHostView->GetNativeView().GetNativeNSView(); +} + +- (PrefService*)prefService { + content::RenderWidgetHost* renderWidgetHost = + content::RenderWidgetHost::FromID(_widgetProcessId, _widgetRoutingId); + if (!renderWidgetHost) { + return nullptr; + } + + return Profile::FromBrowserContext( + renderWidgetHost->GetProcess()->GetBrowserContext()) + ->GetPrefs(); +} + // Handle an event. All incoming key and mouse events flow through this // delegate method if implemented. Return YES if the event is fully handled, or // NO if normal processing should take place. @@ -93,32 +151,20 @@ // HistorySwiperDelegate methods - (BOOL)shouldAllowHistorySwiping { - if (!_renderWidgetHost) - return NO; - RenderViewHost* renderViewHost = RenderViewHost::From(_renderWidgetHost); - if (!renderViewHost) - return NO; - content::WebContents* webContents = - content::WebContents::FromRenderViewHost(renderViewHost); - if (webContents && DevToolsWindow::IsDevToolsWindow(webContents)) { + content::WebContents* webContents = self.webContents; + if (!webContents) { return NO; } - - return YES; + return !DevToolsWindow::IsDevToolsWindow(webContents); } - (NSView*)viewThatWantsHistoryOverlay { - return _renderWidgetHost->GetView()->GetNativeView().GetNativeNSView(); + return self.nsView; } - (BOOL)canNavigateInDirection:(history_swiper::NavigationDirection)direction onWindow:(NSWindow*)window { - if (!_renderWidgetHost) { - return NO; - } - - content::WebContents* webContents = content::WebContents::FromRenderViewHost( - RenderViewHost::From(_renderWidgetHost)); + content::WebContents* webContents = self.webContents; if (!webContents) { return NO; } @@ -132,12 +178,7 @@ - (void)navigateInDirection:(history_swiper::NavigationDirection)direction onWindow:(NSWindow*)window { - if (!_renderWidgetHost) { - return; - } - - content::WebContents* webContents = content::WebContents::FromRenderViewHost( - RenderViewHost::From(_renderWidgetHost)); + content::WebContents* webContents = self.webContents; if (!webContents) { return; } @@ -150,12 +191,7 @@ } - (void)backwardsSwipeNavigationLikely { - if (!_renderWidgetHost) { - return; - } - - content::WebContents* webContents = content::WebContents::FromRenderViewHost( - RenderViewHost::From(_renderWidgetHost)); + content::WebContents* webContents = self.webContents; if (!webContents) { return; } @@ -167,24 +203,23 @@ - (BOOL)validateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)item isValidItem:(BOOL*)valid { - SEL action = [item action]; + PrefService* pref = self.prefService; + if (!pref) { + return NO; + } - Profile* profile = Profile::FromBrowserContext( - _renderWidgetHost->GetProcess()->GetBrowserContext()); - DCHECK(profile); - PrefService* pref = profile->GetPrefs(); const PrefService::Preference* spellCheckEnablePreference = pref->FindPreference(spellcheck::prefs::kSpellCheckEnable); DCHECK(spellCheckEnablePreference); const bool spellCheckUserModifiable = spellCheckEnablePreference->IsUserModifiable(); + SEL action = item.action; // For now, this action is always enabled for render view; // this is sub-optimal. // TODO(suzhe): Plumb the "can*" methods up from WebCore. if (action == @selector(checkSpelling:)) { - *valid = spellCheckUserModifiable && - (RenderViewHost::From(_renderWidgetHost) != nullptr); + *valid = spellCheckUserModifiable; return YES; } @@ -232,13 +267,15 @@ // This message is sent whenever the user specifies that a word should be // changed from the spellChecker. - (void)changeSpelling:(id)sender { + content::WebContents* webContents = self.webContents; + if (!webContents) { + return; + } + // Grab the currently selected word from the spell panel, as this is the word // that we want to replace the selected word in the text with. NSString* newWord = [[sender selectedCell] stringValue]; if (newWord != nil) { - content::WebContents* webContents = - content::WebContents::FromRenderViewHost( - RenderViewHost::From(_renderWidgetHost)); webContents->ReplaceMisspelling(base::SysNSStringToUTF16(newWord)); } } @@ -251,12 +288,15 @@ // catch this and advance to the next word for you. Thanks Apple. // This is also called from the Edit -> Spelling -> Check Spelling menu item. - (void)checkSpelling:(id)sender { - content::WebContents* webContents = content::WebContents::FromRenderViewHost( - RenderViewHost::From(_renderWidgetHost)); - if (webContents && webContents->GetFocusedFrame()) { + content::WebContents* webContents = self.webContents; + if (!webContents) { + return; + } + + if (content::RenderFrameHost* frame = webContents->GetFocusedFrame()) { mojo::Remote<spellcheck::mojom::SpellCheckPanel> focused_spell_check_panel_client; - webContents->GetFocusedFrame()->GetRemoteInterfaces()->GetInterface( + frame->GetRemoteInterfaces()->GetInterface( focused_spell_check_panel_client.BindNewPipeAndPassReceiver()); focused_spell_check_panel_client->AdvanceToNextMisspelling(); } @@ -275,24 +315,27 @@ } - (void)showGuessPanel:(id)sender { + content::WebContents* webContents = self.webContents; + if (!webContents) { + return; + } + const bool visible = spellcheck_platform::SpellingPanelVisible(); - content::WebContents* webContents = content::WebContents::FromRenderViewHost( - RenderViewHost::From(_renderWidgetHost)); - DCHECK(webContents && webContents->GetFocusedFrame()); - - mojo::Remote<spellcheck::mojom::SpellCheckPanel> - focused_spell_check_panel_client; - webContents->GetFocusedFrame()->GetRemoteInterfaces()->GetInterface( - focused_spell_check_panel_client.BindNewPipeAndPassReceiver()); - focused_spell_check_panel_client->ToggleSpellPanel(visible); + if (content::RenderFrameHost* frame = webContents->GetFocusedFrame()) { + mojo::Remote<spellcheck::mojom::SpellCheckPanel> + focused_spell_check_panel_client; + frame->GetRemoteInterfaces()->GetInterface( + focused_spell_check_panel_client.BindNewPipeAndPassReceiver()); + focused_spell_check_panel_client->ToggleSpellPanel(visible); + } } - (void)toggleContinuousSpellChecking:(id)sender { - content::RenderProcessHost* host = _renderWidgetHost->GetProcess(); - Profile* profile = Profile::FromBrowserContext(host->GetBrowserContext()); - DCHECK(profile); - PrefService* pref = profile->GetPrefs(); + PrefService* pref = self.prefService; + if (!pref) { + return; + } pref->SetBoolean(spellcheck::prefs::kSpellCheckEnable, !pref->GetBoolean(spellcheck::prefs::kSpellCheckEnable)); } @@ -301,16 +344,19 @@ // If a dialog is visible, make its window key. See becomeFirstResponder. - (void)makeAnyDialogKey { - if (const auto* contents = content::WebContents::FromRenderViewHost( - RenderViewHost::From(_renderWidgetHost))) { - if (const auto* manager = - web_modal::WebContentsModalDialogManager::FromWebContents( - contents)) { - // IsDialogActive() returns true if a dialog exists. - if (manager->IsDialogActive()) { - manager->FocusTopmostDialog(); - } - } + content::WebContents* webContents = self.webContents; + if (!webContents) { + return; + } + + web_modal::WebContentsModalDialogManager* manager = + web_modal::WebContentsModalDialogManager::FromWebContents(webContents); + if (!manager) { + return; + } + + if (manager->IsDialogActive()) { + manager->FocusTopmostDialog(); } } @@ -326,22 +372,24 @@ // window, like clicking the omnibox or typing cmd+L. In that case, the browser // window should become key. - (void)resignFirstResponder { - NSWindow* browserWindow = - [_renderWidgetHost->GetView()->GetNativeView().GetNativeNSView() window]; + NSWindow* browserWindow = self.nsView.window; DCHECK(browserWindow); // If the browser window is already key, there's nothing to do. - if (browserWindow.isKeyWindow) + if (browserWindow.isKeyWindow) { return; + } // Otherwise, look for it in the key window's chain of parents. NSWindow* keyWindowOrParent = NSApp.keyWindow; - while (keyWindowOrParent && keyWindowOrParent != browserWindow) + while (keyWindowOrParent && keyWindowOrParent != browserWindow) { keyWindowOrParent = keyWindowOrParent.parentWindow; + } // If the browser window isn't among the parents, there's nothing to do. - if (keyWindowOrParent != browserWindow) + if (keyWindowOrParent != browserWindow) { return; + } // Otherwise, temporarily set an ivar so that -windowDidBecomeKey, below, // doesn't immediately make the dialog key. @@ -354,12 +402,13 @@ // If the browser window becomes key while the RenderWidgetHostView is first // responder, make the dialog key (if there is one). - (void)windowDidBecomeKey { - if (_resigningFirstResponder) + if (_resigningFirstResponder) { return; - NSView* view = - _renderWidgetHost->GetView()->GetNativeView().GetNativeNSView(); - if (view.window.firstResponder == view) + } + NSView* view = self.nsView; + if (view.window.firstResponder == view) { [self makeAnyDialogKey]; + } } @end
diff --git a/chrome/browser/resources/app_home/app_item.ts b/chrome/browser/resources/app_home/app_item.ts index e903421..16bcd10 100644 --- a/chrome/browser/resources/app_home/app_item.ts +++ b/chrome/browser/resources/app_home/app_item.ts
@@ -180,7 +180,6 @@ this.appInfo.id, UserDisplayMode.kStandalone); recordUserAction(AppHomeUserAction.OPEN_IN_WINDOW_CHECKED); } - this.closeContextMenu(); } // Changing the app's launch mode. @@ -198,7 +197,6 @@ this.appInfo.id, RunOnOsLoginMode.kWindowed); recordUserAction(AppHomeUserAction.LAUNCH_AT_STARTUP_CHECKED); } - this.closeContextMenu(); } private onCreateShortcutItemClick_() {
diff --git a/chrome/browser/resources/nearby_share/BUILD.gn b/chrome/browser/resources/nearby_share/BUILD.gn index 2f917804..80b4b138 100644 --- a/chrome/browser/resources/nearby_share/BUILD.gn +++ b/chrome/browser/resources/nearby_share/BUILD.gn
@@ -2,106 +2,42 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import("//chrome/common/features.gni") -import("//tools/grit/grit_rule.gni") -import("//tools/grit/preprocess_if_expr.gni") -import("//tools/polymer/html_to_wrapper.gni") -import("//tools/typescript/ts_library.gni") -import("//ui/webui/resources/tools/generate_grd.gni") +import("//build/config/chromeos/ui_mode.gni") +import("//ui/webui/resources/tools/build_webui.gni") assert(is_chromeos_ash, "Nearby Share is CrOS only") -preprocess_folder = "preprocessed" +build_webui("build") { + grd_prefix = "nearby_share_dialog" -grit("resources") { - defines = chrome_grit_defines + static_files = [ "nearby_share_dialog.html" ] - # These arguments are needed since the grd is generated at build time. - enable_input_discovery_for_gn_analyze = false - source = "$target_gen_dir/nearby_share_dialog_resources.grd" - deps = [ ":build_grd" ] - outputs = [ - "grit/nearby_share_dialog_resources.h", - "grit/nearby_share_dialog_resources_map.cc", - "grit/nearby_share_dialog_resources_map.h", - "nearby_share_dialog_resources.pak", + web_component_files = [ + "app.ts", + "nearby_confirmation_page.ts", + "nearby_discovery_page.ts", ] - output_dir = "$root_gen_dir/chrome" -} -web_component_files = [ - "app.ts", - "nearby_confirmation_page.ts", - "nearby_discovery_page.ts", -] + non_web_component_files = [ "discovery_manager.ts" ] -# Files that are passed as input to html_to_wrapper(). -html_files = [] -foreach(f, web_component_files) { - html_files += [ string_replace(f, ".ts", ".html") ] -} - -# Files that are generated by html_to_wrapper(). -html_wrapper_files = [] -foreach(f, html_files) { - html_wrapper_files += [ f + ".ts" ] -} - -non_web_component_files = [ "discovery_manager.ts" ] - -html_to_wrapper("html_wrapper_files") { - in_files = html_files -} - -preprocess_if_expr("preprocess_src") { - out_folder = "$target_gen_dir/$preprocess_folder" - in_files = web_component_files + non_web_component_files -} - -preprocess_if_expr("preprocess_gen") { - deps = [ ":html_wrapper_files" ] - in_folder = target_gen_dir - out_folder = "$target_gen_dir/$preprocess_folder" - in_files = html_wrapper_files -} - -ts_library("build_ts") { - root_dir = "$target_gen_dir/$preprocess_folder" - out_dir = "$target_gen_dir/tsc" - tsconfig_base = "//tools/typescript/tsconfig_base_polymer.json" - in_files = web_component_files + non_web_component_files + html_wrapper_files - deps = [ + ts_deps = [ "./shared:build_ts", "//third_party/polymer/v3_0:library", "//ui/webui/resources/cr_elements:build_ts", "//ui/webui/resources/js:build_ts", "//ui/webui/resources/mojo:build_ts", ] - extra_deps = [ - ":preprocess_gen", - ":preprocess_src", - ] - definitions = [ "//tools/typescript/definitions/chrome_send.d.ts" ] - - path_mappings = + ts_definitions = [ "//tools/typescript/definitions/chrome_send.d.ts" ] + ts_path_mappings = [ "/shared/*|" + rebase_path("$target_gen_dir/shared/tsc/*", target_gen_dir) ] -} -generate_grd("build_grd") { - grd_prefix = "nearby_share_dialog" - out_grd = "$target_gen_dir/${grd_prefix}_resources.grd" - input_files = [ "nearby_share_dialog.html" ] - input_files_base_dir = rebase_path(".", "//") - deps = [ - ":build_ts", - "shared:build_json_grdp", - "shared:build_v3_grdp", - ] - grdp_files = [ + extra_grdp_files = [ "$target_gen_dir/shared/nearby_share_json_resources.grdp", - "$target_gen_dir/shared/nearby_share_resources_v3.grdp", + "$target_gen_dir/shared/resources.grdp", ] - manifest_files = - filter_include(get_target_outputs(":build_ts"), [ "*.manifest" ]) + extra_grdp_deps = [ + "shared:build_grdp", + "shared:build_json_grdp", + ] }
diff --git a/chrome/browser/resources/nearby_share/app.ts b/chrome/browser/resources/nearby_share/app.ts index 853cb18..1aa0acd 100644 --- a/chrome/browser/resources/nearby_share/app.ts +++ b/chrome/browser/resources/nearby_share/app.ts
@@ -9,7 +9,7 @@ import './nearby_discovery_page.js'; import 'chrome://resources/cr_elements/cr_view_manager/cr_view_manager.js'; -import {ConfirmationManagerInterface, PayloadPreview, ShareTarget, TransferUpdateListenerPendingReceiver} from '/shared/mojo/nearby_share.mojom-webui.js'; +import {ConfirmationManagerInterface, PayloadPreview, ShareTarget, TransferUpdateListenerPendingReceiver} from '/shared/nearby_share.mojom-webui.js'; import {NearbyShareSettingsMixin} from '/shared/nearby_share_settings_mixin.js'; import {CloseReason} from '/shared/types.js'; import {CrViewManagerElement} from 'chrome://resources/cr_elements/cr_view_manager/cr_view_manager.js';
diff --git a/chrome/browser/resources/nearby_share/discovery_manager.ts b/chrome/browser/resources/nearby_share/discovery_manager.ts index 9270a24..2c5adaa 100644 --- a/chrome/browser/resources/nearby_share/discovery_manager.ts +++ b/chrome/browser/resources/nearby_share/discovery_manager.ts
@@ -7,7 +7,7 @@ * DiscoveryManager which allows interaction with native code. */ -import {DiscoveryManager, DiscoveryManagerInterface, DiscoveryManagerRemote, DiscoveryObserverInterface, DiscoveryObserverReceiver, DiscoveryObserverRemote} from '/shared/mojo/nearby_share.mojom-webui.js'; +import {DiscoveryManager, DiscoveryManagerInterface, DiscoveryManagerRemote, DiscoveryObserverInterface, DiscoveryObserverReceiver, DiscoveryObserverRemote} from '/shared/nearby_share.mojom-webui.js'; let discoveryManager: DiscoveryManagerInterface|null = null; let isTesting: boolean = false;
diff --git a/chrome/browser/resources/nearby_share/nearby_confirmation_page.ts b/chrome/browser/resources/nearby_share/nearby_confirmation_page.ts index 108eba1..216dda6 100644 --- a/chrome/browser/resources/nearby_share/nearby_confirmation_page.ts +++ b/chrome/browser/resources/nearby_share/nearby_confirmation_page.ts
@@ -17,7 +17,7 @@ import '/shared/nearby_progress.js'; import './strings.m.js'; -import {ConfirmationManagerInterface, PayloadPreview, ShareTarget, TransferStatus, TransferUpdateListenerInterface, TransferUpdateListenerPendingReceiver, TransferUpdateListenerReceiver} from '/shared/mojo/nearby_share.mojom-webui.js'; +import {ConfirmationManagerInterface, PayloadPreview, ShareTarget, TransferStatus, TransferUpdateListenerInterface, TransferUpdateListenerPendingReceiver, TransferUpdateListenerReceiver} from '/shared/nearby_share.mojom-webui.js'; import {CloseReason} from '/shared/types.js'; import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
diff --git a/chrome/browser/resources/nearby_share/nearby_discovery_page.ts b/chrome/browser/resources/nearby_share/nearby_discovery_page.ts index bd468c6..6754780 100644 --- a/chrome/browser/resources/nearby_share/nearby_discovery_page.ts +++ b/chrome/browser/resources/nearby_share/nearby_discovery_page.ts
@@ -16,8 +16,8 @@ import '/shared/nearby_preview.js'; import './strings.m.js'; -import {ConfirmationManagerInterface, DiscoveryObserverReceiver, PayloadPreview, SelectShareTargetResult, ShareTarget, ShareTargetListenerCallbackRouter, StartDiscoveryResult, TransferUpdateListenerPendingReceiver} from '/shared/mojo/nearby_share.mojom-webui.js'; import {NearbyDeviceElement} from '/shared/nearby_device.js'; +import {ConfirmationManagerInterface, DiscoveryObserverReceiver, PayloadPreview, SelectShareTargetResult, ShareTarget, ShareTargetListenerCallbackRouter, StartDiscoveryResult, TransferUpdateListenerPendingReceiver} from '/shared/nearby_share.mojom-webui.js'; import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js'; import {assert, assertNotReached} from 'chrome://resources/js/assert_ts.js'; import {UnguessableToken} from 'chrome://resources/mojo/mojo/public/mojom/base/unguessable_token.mojom-webui.js';
diff --git a/chrome/browser/resources/nearby_share/shared/BUILD.gn b/chrome/browser/resources/nearby_share/shared/BUILD.gn index 21b9c7b..f2a4f4b 100644 --- a/chrome/browser/resources/nearby_share/shared/BUILD.gn +++ b/chrome/browser/resources/nearby_share/shared/BUILD.gn
@@ -2,20 +2,67 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import("//tools/grit/preprocess_if_expr.gni") -import("//tools/polymer/html_to_wrapper.gni") -import("//tools/typescript/ts_library.gni") +import("//ui/webui/resources/tools/build_webui.gni") import("//ui/webui/resources/tools/generate_grd.gni") assert(is_chromeos, "Nearby Share is CrOS only") -grd_prefix = "nearby_share" -preprocessed_dir = "$target_gen_dir/preprocessed" -tsc_dir = "$target_gen_dir/tsc" +# TODO(b/207087930) Consider moving these shared files to chrome://resources. +# b/207087942 provides context why chrome://resources did not work previously. +build_webui("build") { + grd_prefix = "nearby_share" + grd_resource_path_prefix = "shared" + + web_component_files = [ + "nearby_contact_visibility.ts", + "nearby_device_icon.ts", + "nearby_device.ts", + "nearby_onboarding_one_page.ts", + "nearby_onboarding_page.ts", + "nearby_page_template.ts", + "nearby_preview.ts", + "nearby_progress.ts", + "nearby_visibility_page.ts", + ] + + non_web_component_files = [ + "nearby_contact_manager.ts", + "nearby_metrics_logger.ts", + "nearby_share_settings_mixin.ts", + "nearby_share_settings.ts", + "types.ts", + ] + + icons_html_files = [ + "nearby_shared_icons.html", + "nearby_shared_share_type_icons.html", + ] + + mojo_files_deps = [ + "//chrome/browser/ui/webui/nearby_share:mojom_ts__generator", + "//chrome/browser/ui/webui/nearby_share:share_type_ts__generator", + ] + mojo_files = [ + "$root_gen_dir/chrome/browser/ui/webui/nearby_share/nearby_share.mojom-webui.ts", + "$root_gen_dir/chrome/browser/ui/webui/nearby_share/nearby_share_share_type.mojom-webui.ts", + ] + + ts_composite = true + ts_definitions = [ "//tools/typescript/definitions/chrome_send.d.ts" ] + ts_deps = [ + "//ash/webui/common/resources:build_ts", + "//third_party/polymer/v3_0:library", + "//ui/webui/resources/cr_elements:build_ts", + "//ui/webui/resources/js:build_ts", + "//ui/webui/resources/mojo:build_ts", + ] + + generate_grdp = true +} # Grdp of JSON files for OS Settings. generate_grd("build_json_grdp") { - grd_prefix = grd_prefix + grd_prefix = "nearby_share" out_grd = "$target_gen_dir/nearby_share_json_resources.grdp" input_files_base_dir = rebase_path(".", "//") input_files = [ @@ -25,104 +72,3 @@ "nearby_share_pulse_animation_light.json", ] } - -# TODO(b/207087930) Consider moving these shared files to chrome://resources. -# b/207087942 provides context why chrome://resources did not work previously. -generate_grd("build_v3_grdp") { - grd_prefix = grd_prefix - out_grd = "$target_gen_dir/${grd_prefix}_resources_v3.grdp" - deps = [ ":build_ts" ] - manifest_files = [ "$target_gen_dir/build_ts.manifest" ] - resource_path_prefix = "shared" -} - -web_component_files = [ - "nearby_contact_visibility.ts", - "nearby_device_icon.ts", - "nearby_device.ts", - "nearby_onboarding_one_page.ts", - "nearby_onboarding_page.ts", - "nearby_page_template.ts", - "nearby_preview.ts", - "nearby_progress.ts", - "nearby_visibility_page.ts", -] - -# Files that are passed as input to html_to_wrapper(). -html_files = [] -foreach(f, web_component_files) { - html_files += [ string_replace(f, ".ts", ".html") ] -} - -# Add icons -html_files += [ - "nearby_shared_icons.html", - "nearby_shared_share_type_icons.html", -] - -# Files that are generated by html_to_wrapper(). -html_wrapper_files = [] -foreach(f, html_files) { - html_wrapper_files += [ f + ".ts" ] -} - -non_web_component_files = [ - "nearby_contact_manager.ts", - "nearby_metrics_logger.ts", - "nearby_share_settings_mixin.ts", - "nearby_share_settings.ts", - "types.ts", -] - -preprocess_if_expr("preprocess") { - in_folder = "." - in_files = web_component_files + non_web_component_files + html_files - out_folder = preprocessed_dir -} - -html_to_wrapper("html_wrapper_files") { - deps = [ ":preprocess" ] - in_files = html_files - in_folder = preprocessed_dir - out_folder = preprocessed_dir -} - -# TODO(b/270653607) Update this to generate TS sources instead and remove -# listing in tools/typescript/validate_tsconfig.py. -copy("copy_mojo") { - deps = [ - "//chrome/browser/ui/webui/nearby_share:mojom_ts__generator", - "//chrome/browser/ui/webui/nearby_share:share_type_ts__generator", - ] - sources = [ - "$root_gen_dir/chrome/browser/ui/webui/nearby_share/nearby_share.mojom-webui.ts", - "$root_gen_dir/chrome/browser/ui/webui/nearby_share/nearby_share_share_type.mojom-webui.ts", - ] - outputs = [ "$preprocessed_dir/mojo/{{source_file_part}}" ] -} - -ts_library("build_ts") { - tsconfig_base = "//tools/typescript/tsconfig_base_polymer.json" - deps = [ - "//ash/webui/common/resources:build_ts", - "//third_party/polymer/v3_0:library", - "//ui/webui/resources/cr_elements:build_ts", - "//ui/webui/resources/js:build_ts", - "//ui/webui/resources/mojo:build_ts", - ] - extra_deps = [ - ":copy_mojo", - ":html_wrapper_files", - ":preprocess", - ] - root_dir = preprocessed_dir - in_files = - web_component_files + non_web_component_files + html_wrapper_files + [ - "mojo/nearby_share.mojom-webui.ts", - "mojo/nearby_share_share_type.mojom-webui.ts", - ] - out_dir = tsc_dir - definitions = [ "//tools/typescript/definitions/chrome_send.d.ts" ] - - composite = true -}
diff --git a/chrome/browser/resources/nearby_share/shared/nearby_device.ts b/chrome/browser/resources/nearby_share/shared/nearby_device.ts index 4bdead01..b04ba74d 100644 --- a/chrome/browser/resources/nearby_share/shared/nearby_device.ts +++ b/chrome/browser/resources/nearby_share/shared/nearby_device.ts
@@ -16,9 +16,9 @@ import {assert} from 'chrome://resources/js/assert_ts.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {ShareTarget} from './mojo/nearby_share.mojom-webui.js'; import {getTemplate} from './nearby_device.html.js'; import {NearbyDeviceIconElement} from './nearby_device_icon.js'; +import {ShareTarget} from './nearby_share.mojom-webui.js'; export class NearbyDeviceElement extends PolymerElement { static get is() {
diff --git a/chrome/browser/resources/nearby_share/shared/nearby_device_icon.ts b/chrome/browser/resources/nearby_share/shared/nearby_device_icon.ts index d77648b2..68d7960 100644 --- a/chrome/browser/resources/nearby_share/shared/nearby_device_icon.ts +++ b/chrome/browser/resources/nearby_share/shared/nearby_device_icon.ts
@@ -16,8 +16,8 @@ import {ShareTargetType} from 'chrome://resources/mojo/chromeos/ash/services/nearby/public/mojom/nearby_share_target_types.mojom-webui.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {ShareTarget} from './mojo/nearby_share.mojom-webui.js'; import {getTemplate} from './nearby_device_icon.html.js'; +import {ShareTarget} from './nearby_share.mojom-webui.js'; export class NearbyDeviceIconElement extends PolymerElement { static get is() {
diff --git a/chrome/browser/resources/nearby_share/shared/nearby_preview.ts b/chrome/browser/resources/nearby_share/shared/nearby_preview.ts index 951a520..f4dbdd51 100644 --- a/chrome/browser/resources/nearby_share/shared/nearby_preview.ts +++ b/chrome/browser/resources/nearby_share/shared/nearby_preview.ts
@@ -17,9 +17,9 @@ import {assertNotReached} from 'chrome://resources/js/assert_ts.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {PayloadPreview} from './mojo/nearby_share.mojom-webui.js'; -import {ShareType} from './mojo/nearby_share_share_type.mojom-webui.js'; import {getTemplate} from './nearby_preview.html.js'; +import {PayloadPreview} from './nearby_share.mojom-webui.js'; +import {ShareType} from './nearby_share_share_type.mojom-webui.js'; const NearbyPreviewElementBase = I18nMixin(PolymerElement);
diff --git a/chrome/browser/resources/nearby_share/shared/nearby_progress.ts b/chrome/browser/resources/nearby_share/shared/nearby_progress.ts index 2afbb4d..5470f2f 100644 --- a/chrome/browser/resources/nearby_share/shared/nearby_progress.ts +++ b/chrome/browser/resources/nearby_share/shared/nearby_progress.ts
@@ -18,9 +18,9 @@ import {assert} from 'chrome://resources/js/assert_ts.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {ShareTarget} from './mojo/nearby_share.mojom-webui.js'; import {NearbyDeviceIconElement} from './nearby_device_icon.js'; import {getTemplate} from './nearby_progress.html.js'; +import {ShareTarget} from './nearby_share.mojom-webui.js'; export class NearbyProgressElement extends PolymerElement { static get is() {
diff --git a/chrome/browser/resources/password_manager/passwords_importer.ts b/chrome/browser/resources/password_manager/passwords_importer.ts index 29f929a..4787b33 100644 --- a/chrome/browser/resources/password_manager/passwords_importer.ts +++ b/chrome/browser/resources/password_manager/passwords_importer.ts
@@ -37,6 +37,34 @@ CONFLICTS, } +/** + * Should be kept in sync with + * |password_manager::metrics_util::PasswordsImportDesktopInteractions|. + * These values are persisted to logs. Entries should not be renumbered and + * numeric values should never be reused. + */ +enum PasswordsImportDesktopInteractions { + DIALOG_OPENED_FROM_THREE_DOT_MENU = 0, + DIALOG_OPENED_FROM_EMPTY_STATE = 1, + CANCELED_BEFORE_FILE_SELECT = 2, + UPM_STORE_PICKER_OPENED = 3, + UPM_FILE_SELECT_LAUNCHED = 4, + UPM_VIEW_PASSWORDS_CLICKED = 5, + CONFLICTS_CANCELED = 6, + CONFLICTS_REAUTH_FAILED = 7, + CONFLICTS_SKIP_CLICKED = 8, + CONFLICTS_REPLACE_CLICKED = 9, + // Must be last. + COUNT = 10, +} + +function recordPasswordsImportInteraction( + interaction: PasswordsImportDesktopInteractions) { + chrome.metricsPrivate.recordEnumerationValue( + 'PasswordManager.Import.DesktopInteractions', interaction, + PasswordsImportDesktopInteractions.COUNT); +} + const PasswordsImporterElementBase = I18nMixin(PolymerElement); export class PasswordsImporterElement extends PasswordsImporterElementBase { @@ -147,6 +175,8 @@ PasswordManagerImpl.getInstance(); launchImport() { + recordPasswordsImportInteraction( + PasswordsImportDesktopInteractions.DIALOG_OPENED_FROM_EMPTY_STATE); this.inProgress_ = true; // Timeout is needed to allow Polymer to render the Settings page before the // system file picker has been opened. @@ -154,7 +184,7 @@ if (this.isAccountStoreUser) { this.dialogState_ = DialogState.STORE_PICKER; } else { - this.onSelectFileClick_(); + this.selectFileHelper_(); } }, 200); } @@ -201,6 +231,8 @@ private onBannerClick_() { if (this.isAccountStoreUser && !this.inProgress_ && this.isState_(DialogState.NO_DIALOG)) { + recordPasswordsImportInteraction( + PasswordsImportDesktopInteractions.UPM_STORE_PICKER_OPENED); this.inProgress_ = true; this.dialogState_ = DialogState.STORE_PICKER; } @@ -228,19 +260,25 @@ } private async onCloseClick_() { + if (this.isState_(DialogState.CONFLICTS)) { + recordPasswordsImportInteraction( + PasswordsImportDesktopInteractions.CONFLICTS_CANCELED); + } await this.resetImporter(); this.closeDialog_(); this.inProgress_ = false; } private async onViewPasswordsClick_() { + recordPasswordsImportInteraction( + PasswordsImportDesktopInteractions.UPM_VIEW_PASSWORDS_CLICKED); await this.resetImporter(); this.closeDialog_(); this.inProgress_ = false; Router.getInstance().navigateTo(Page.PASSWORDS); } - private async onSelectFileClick_() { + private async selectFileHelper_() { // Clear selected rows from previous import, so it won’t affect the // following import. this.conflictsSelectedForReplace_ = []; @@ -268,6 +306,12 @@ this.inProgress_ = false; } + private async onSelectFileClick_() { + recordPasswordsImportInteraction( + PasswordsImportDesktopInteractions.UPM_FILE_SELECT_LAUNCHED); + await this.selectFileHelper_(); + } + private async continueImportHelper_(selectedIds: number[]) { this.inProgress_ = true; // Close the dialog while import is in progress. @@ -275,6 +319,8 @@ this.results_ = await this.passwordManager_.continueImport(selectedIds); if (this.results_.status === chrome.passwordsPrivate.ImportResultsStatus.DISMISSED) { + recordPasswordsImportInteraction( + PasswordsImportDesktopInteractions.CONFLICTS_REAUTH_FAILED); // When re-auth fails, restore the conflicts dialog. this.dialogState_ = DialogState.CONFLICTS; return; @@ -283,10 +329,14 @@ } private async onSkipClick_() { + recordPasswordsImportInteraction( + PasswordsImportDesktopInteractions.CONFLICTS_SKIP_CLICKED); await this.continueImportHelper_(/*selectedIds=*/[]); } private async onReplaceClick_() { + recordPasswordsImportInteraction( + PasswordsImportDesktopInteractions.CONFLICTS_REPLACE_CLICKED); await this.continueImportHelper_(this.conflictsSelectedForReplace_); }
diff --git a/chrome/browser/resources/settings/autofill_page/passwords_import_dialog.html b/chrome/browser/resources/settings/autofill_page/passwords_import_dialog.html index e9ddc54..195f65b2 100644 --- a/chrome/browser/resources/settings/autofill_page/passwords_import_dialog.html +++ b/chrome/browser/resources/settings/autofill_page/passwords_import_dialog.html
@@ -134,7 +134,7 @@ </style> -<cr-dialog id="dialog" close-text="$i18n{close}" show-on-attach> +<cr-dialog id="dialog" close-text="$i18n{close}" show-on-attach no-cancel> <div slot="title" class="dialog-title"> <template is="dom-if" if="[[isState_(importDialogStateEnum_.CONFLICTS, dialogState)]]">
diff --git a/chrome/browser/resources/settings/autofill_page/passwords_import_dialog.ts b/chrome/browser/resources/settings/autofill_page/passwords_import_dialog.ts index 1d82dfc..2e3072ec 100644 --- a/chrome/browser/resources/settings/autofill_page/passwords_import_dialog.ts +++ b/chrome/browser/resources/settings/autofill_page/passwords_import_dialog.ts
@@ -83,8 +83,15 @@ DIALOG_OPENED_FROM_THREE_DOT_MENU = 0, DIALOG_OPENED_FROM_EMPTY_STATE = 1, CANCELED_BEFORE_FILE_SELECT = 2, + UPM_STORE_PICKER_OPENED = 3, + UPM_FILE_SELECT_LAUNCHED = 4, + UPM_VIEW_PASSWORDS_CLICKED = 5, + CONFLICTS_CANCELED = 6, + CONFLICTS_REAUTH_FAILED = 7, + CONFLICTS_SKIP_CLICKED = 8, + CONFLICTS_REPLACE_CLICKED = 9, // Must be last. - COUNT = 3, + COUNT = 10, } export class PasswordsImportDialogElement extends @@ -293,6 +300,8 @@ private async onSkipClick_() { assert(this.isState_(ImportDialogState.CONFLICTS)); + recordPasswordsImportInteraction( + PasswordsImportDesktopInteractions.CONFLICTS_SKIP_CLICKED); this.inProgress_ = true; this.results_ = await this.passwordManager_.continueImport(/*selectedIds=*/[]); @@ -301,6 +310,8 @@ private async onReplaceClick_() { assert(this.isState_(ImportDialogState.CONFLICTS)); + recordPasswordsImportInteraction( + PasswordsImportDesktopInteractions.CONFLICTS_REPLACE_CLICKED); this.inProgress_ = true; this.results_ = await this.passwordManager_.continueImport( this.conflictsSelectedForReplace_); @@ -351,6 +362,10 @@ this.dialogState = ImportDialogState.ERROR; break; case chrome.passwordsPrivate.ImportResultsStatus.DISMISSED: + if (this.isState_(ImportDialogState.CONFLICTS)) { + recordPasswordsImportInteraction( + PasswordsImportDesktopInteractions.CONFLICTS_REAUTH_FAILED); + } // Dialog state should not change if a system file picker was dismissed. break; case chrome.passwordsPrivate.ImportResultsStatus.IMPORT_ALREADY_ACTIVE: @@ -514,6 +529,10 @@ recordPasswordsImportInteraction( PasswordsImportDesktopInteractions.CANCELED_BEFORE_FILE_SELECT); } + if (this.isState_(ImportDialogState.CONFLICTS)) { + recordPasswordsImportInteraction( + PasswordsImportDesktopInteractions.CONFLICTS_CANCELED); + } if (this.enablePasswordsImportM2_) { // Trigger the file deletion if checkbox is ticked in SUCCESS (with no // errors) state.
diff --git a/chrome/browser/resources/settings/chromeos/BUILD.gn b/chrome/browser/resources/settings/chromeos/BUILD.gn index 94dd4ce..21f55a9a 100644 --- a/chrome/browser/resources/settings/chromeos/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/BUILD.gn
@@ -273,9 +273,9 @@ } else { deps += [ ":build_ts", - "//chrome/browser/resources/nearby_share/shared:build_v3_grdp", + "//chrome/browser/resources/nearby_share/shared:build_grdp", ] - grdp_files += [ "$root_gen_dir/chrome/browser/resources/nearby_share/shared/nearby_share_resources_v3.grdp" ] + grdp_files += [ "$root_gen_dir/chrome/browser/resources/nearby_share/shared/resources.grdp" ] manifest_files += filter_include(get_target_outputs(":build_ts"), [ "*.manifest" ]) }
diff --git a/chrome/browser/resources/settings/chromeos/device_page/per_device_mouse_subsection.html b/chrome/browser/resources/settings/chromeos/device_page/per_device_mouse_subsection.html index 7202d9500..f80f0071 100644 --- a/chrome/browser/resources/settings/chromeos/device_page/per_device_mouse_subsection.html +++ b/chrome/browser/resources/settings/chromeos/device_page/per_device_mouse_subsection.html
@@ -70,7 +70,7 @@ </div> <cr-toggle id="mouseReverseScroll" checked="{{reverseScrollValue}}" - aria-labelledby="enableMouseReverseScrollingLabel" + aria-label="[[mouse.name]] $i18n{learnMoreLabel}" deep-link-focus-id$="[[Setting.kMouseReverseScrolling]]"> </cr-toggle> </div>
diff --git a/chrome/browser/resources/settings/chromeos/device_page/per_device_touchpad_subsection.html b/chrome/browser/resources/settings/chromeos/device_page/per_device_touchpad_subsection.html index 2633de2e..d66aeb4b 100644 --- a/chrome/browser/resources/settings/chromeos/device_page/per_device_touchpad_subsection.html +++ b/chrome/browser/resources/settings/chromeos/device_page/per_device_touchpad_subsection.html
@@ -99,7 +99,8 @@ </div> <cr-toggle id="touchpadHapticFeedbackToggle" checked="{{hapticFeedbackValue}}" - aria-labelledby="touchpadHapticFeedbackRow" + aria-label= + "[[getTouchpadName(touchpad.name)]] $i18n{learnMoreLabel}" deep-link-focus-id$="[[Setting.kTouchpadHapticFeedback]]"> </cr-toggle> </div> @@ -116,7 +117,7 @@ </div> <cr-toggle id="enableReverseScrollingToggle" checked="{{reverseScrollValue}}" - aria-labelledby="enableReverseScrollingLabel" + aria-label="[[getTouchpadName(touchpad.name)]] $i18n{learnMoreLabel}" deep-link-focus-id$="[[Setting.kTouchpadReverseScrolling]]"> </cr-toggle> </div>
diff --git a/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_confirm_page.ts b/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_confirm_page.ts index e999f4a..7af3ed44 100644 --- a/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_confirm_page.ts +++ b/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_confirm_page.ts
@@ -15,7 +15,7 @@ import '/shared/nearby_preview.js'; import '/shared/nearby_progress.js'; -import {ShareTarget, TransferStatus} from '/shared/mojo/nearby_share.mojom-webui.js'; +import {ShareTarget, TransferStatus} from '/shared/nearby_share.mojom-webui.js'; import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
diff --git a/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_high_visibility_page.ts b/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_high_visibility_page.ts index 365d9f2..53900af 100644 --- a/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_high_visibility_page.ts +++ b/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_high_visibility_page.ts
@@ -15,7 +15,7 @@ import '/shared/nearby_page_template.js'; import '/shared/nearby_shared_icons.html.js'; -import {RegisterReceiveSurfaceResult} from '/shared/mojo/nearby_share.mojom-webui.js'; +import {RegisterReceiveSurfaceResult} from '/shared/nearby_share.mojom-webui.js'; import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
diff --git a/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_receive_dialog.ts b/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_receive_dialog.ts index 966651c..104c15407 100644 --- a/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_receive_dialog.ts +++ b/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_receive_dialog.ts
@@ -30,7 +30,7 @@ import './nearby_share_confirm_page.js'; import './nearby_share_high_visibility_page.js'; -import {ReceiveManagerInterface, ReceiveObserverReceiver, RegisterReceiveSurfaceResult, ShareTarget, TransferMetadata, TransferStatus} from '/shared/mojo/nearby_share.mojom-webui.js'; +import {ReceiveManagerInterface, ReceiveObserverReceiver, RegisterReceiveSurfaceResult, ShareTarget, TransferMetadata, TransferStatus} from '/shared/nearby_share.mojom-webui.js'; import {NearbySettings} from '/shared/nearby_share_settings_mixin.js'; import {CrDialogElement} from 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js'; import {CrViewManagerElement} from 'chrome://resources/cr_elements/cr_view_manager/cr_view_manager.js';
diff --git a/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_receive_manager.ts b/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_receive_manager.ts index d2878423..6343ac91 100644 --- a/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_receive_manager.ts +++ b/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_receive_manager.ts
@@ -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 {ReceiveManager, ReceiveManagerInterface, ReceiveObserverInterface, ReceiveObserverReceiver, ReceiveObserverRemote} from '/shared/mojo/nearby_share.mojom-webui.js'; +import {ReceiveManager, ReceiveManagerInterface, ReceiveObserverInterface, ReceiveObserverReceiver, ReceiveObserverRemote} from '/shared/nearby_share.mojom-webui.js'; let receiveManager: ReceiveManagerInterface|null = null; let isTesting = false;
diff --git a/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_subpage.ts b/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_subpage.ts index c59b885..fbd9891 100644 --- a/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_subpage.ts +++ b/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_subpage.ts
@@ -19,8 +19,8 @@ import './nearby_share_data_usage_dialog.js'; import './nearby_share_receive_dialog.js'; -import {ReceiveObserverReceiver, ShareTarget, TransferMetadata} from '/shared/mojo/nearby_share.mojom-webui.js'; import {getContactManager} from '/shared/nearby_contact_manager.js'; +import {ReceiveObserverReceiver, ShareTarget, TransferMetadata} from '/shared/nearby_share.mojom-webui.js'; import {NearbySettings} from '/shared/nearby_share_settings_mixin.js'; import {PrefsMixin} from 'chrome://resources/cr_components/settings_prefs/prefs_mixin.js'; import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_settings.ts b/chrome/browser/resources/settings/chromeos/os_settings.ts index a9428895..87c512a 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings.ts +++ b/chrome/browser/resources/settings/chromeos/os_settings.ts
@@ -93,8 +93,8 @@ * into a single JS file. The exports below are necessary so they can be * imported into browser tests. */ -export * as nearbyShareMojom from '/shared/mojo/nearby_share.mojom-webui.js'; export {getContactManager, observeContactManager, setContactManagerForTesting} from '/shared/nearby_contact_manager.js'; +export * as nearbyShareMojom from '/shared/nearby_share.mojom-webui.js'; export {getNearbyShareSettings, observeNearbyShareSettings, setNearbyShareSettingsForTesting} from '/shared/nearby_share_settings.js'; export {NearbySettings, NearbyShareSettingsMixin} from '/shared/nearby_share_settings_mixin.js'; export {LifetimeBrowserProxyImpl} from '/shared/settings/lifetime_browser_proxy.js';
diff --git a/chrome/browser/resources/settings/site_settings/chooser_exception_list.html b/chrome/browser/resources/settings/site_settings/chooser_exception_list.html index 36cc9dd..e509359 100644 --- a/chrome/browser/resources/settings/site_settings/chooser_exception_list.html +++ b/chrome/browser/resources/settings/site_settings/chooser_exception_list.html
@@ -3,14 +3,43 @@ padding: 0 var(--cr-section-padding); padding-top: 30px; } + + #exception-list { + padding-top: 0; + } + + #resetSettingsButton { + margin: 0 var(--cr-section-padding); + margin-top: 24px; + } </style> + <!-- Confirm reset settings dialog. --> + <cr-dialog id="confirmResetSettings" close-text="$i18n{close}"> + <div slot="body">[[resetPermissionsMessage_]]</div> + <div slot="button-container"> + <cr-button class="cancel-button" on-click="onCloseDialog_"> + $i18n{cancel} + </cr-button> + <cr-button class="action-button" on-click="onResetSettings_"> + $i18n{siteSettingsSiteResetAll} + </cr-button> + </div> + </cr-dialog> + <div id="empty-list-message" hidden$="[[hasExceptions_(chooserExceptions.*)]]"> <div class="secondary">[[emptyListMessage_]]</div> </div> - <template is="dom-repeat" items="[[chooserExceptions]]"> + <div hidden$="[[!hasExceptions_(chooserExceptions.*)]]"> + <cr-button id="resetSettingsButton" role="button" aria-disabled="false" + on-click="onConfirmClearSettings_"> + $i18n{siteSettingsReset} + </cr-button> + </div> + + <template id="exception-list" is="dom-repeat" items="[[chooserExceptions]]"> <chooser-exception-list-entry exception="[[item]]" on-show-tooltip="onShowTooltip_"> </chooser-exception-list-entry>
diff --git a/chrome/browser/resources/settings/site_settings/chooser_exception_list.ts b/chrome/browser/resources/settings/site_settings/chooser_exception_list.ts index ca12419..be9263b 100644 --- a/chrome/browser/resources/settings/site_settings/chooser_exception_list.ts +++ b/chrome/browser/resources/settings/site_settings/chooser_exception_list.ts
@@ -14,6 +14,7 @@ import '../i18n_setup.js'; import './chooser_exception_list_entry.js'; +import {CrDialogElement} from 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js'; import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js'; import {ListPropertyUpdateMixin} from 'chrome://resources/cr_elements/list_property_update_mixin.js'; import {WebUiListenerMixin} from 'chrome://resources/cr_elements/web_ui_listener_mixin.js'; @@ -29,6 +30,7 @@ export interface ChooserExceptionListElement { $: { + confirmResetSettings: CrDialogElement, tooltip: PaperTooltipElement, }; } @@ -75,6 +77,12 @@ }, hasIncognito_: Boolean, + + resetPermissionsMessage_: { + type: String, + value: '', + }, + tooltipText_: String, }; } @@ -83,6 +91,7 @@ chooserType: ChooserType; private emptyListMessage_: string; private hasIncognito_: boolean; + private resetPermissionsMessage_: string; private tooltipText_: string; override connectedCallback() { @@ -137,18 +146,24 @@ switch (this.chooserType) { case ChooserType.USB_DEVICES: this.emptyListMessage_ = this.i18n('noUsbDevicesFound'); + this.resetPermissionsMessage_ = this.i18n('resetUsbConfirmation'); break; case ChooserType.SERIAL_PORTS: this.emptyListMessage_ = this.i18n('noSerialPortsFound'); + this.resetPermissionsMessage_ = + this.i18n('resetSerialPortsConfirmation'); break; case ChooserType.HID_DEVICES: this.emptyListMessage_ = this.i18n('noHidDevicesFound'); + this.resetPermissionsMessage_ = this.i18n('resetHidConfirmation'); break; case ChooserType.BLUETOOTH_DEVICES: this.emptyListMessage_ = this.i18n('noBluetoothDevicesFound'); + this.resetPermissionsMessage_ = this.i18n('resetBluetoothConfirmation'); break; default: this.emptyListMessage_ = ''; + this.resetPermissionsMessage_ = ''; } this.populateList_(); @@ -204,6 +219,32 @@ }, this); } } + + /** + * Confirms the resetting of all content settings for an origin. + */ + private onConfirmClearSettings_(e: Event) { + e.preventDefault(); + this.$.confirmResetSettings.showModal(); + } + + private onCloseDialog_(e: Event) { + (e.target as HTMLElement).closest('cr-dialog')!.close(); + } + + /** + * Resets all permissions for the current origin. + */ + private onResetSettings_(e: Event) { + this.chooserExceptions.forEach(exception => { + exception.sites.forEach(site => { + this.browserProxy.resetChooserExceptionForSite( + exception.chooserType, site.origin, exception.object); + }); + }); + + this.onCloseDialog_(e); + } } declare global {
diff --git a/chrome/browser/resources/side_panel/bookmarks/power_bookmarks_list.ts b/chrome/browser/resources/side_panel/bookmarks/power_bookmarks_list.ts index e5a20e5..993c567b 100644 --- a/chrome/browser/resources/side_panel/bookmarks/power_bookmarks_list.ts +++ b/chrome/browser/resources/side_panel/bookmarks/power_bookmarks_list.ts
@@ -845,6 +845,7 @@ event.preventDefault(); event.stopPropagation(); this.showDeletionToastWithCount_(event.detail.bookmarks.length); + this.selectedBookmarks_ = []; this.editing_ = false; }
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_fetcher_win.cc b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_fetcher_win.cc index fbf0d1e..b61ad576 100644 --- a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_fetcher_win.cc +++ b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_fetcher_win.cc
@@ -13,7 +13,6 @@ #include "base/files/scoped_temp_dir.h" #include "base/functional/bind.h" #include "base/functional/callback_helpers.h" -#include "base/guid.h" #include "base/location.h" #include "base/memory/raw_ptr.h" #include "base/memory/ref_counted.h" @@ -24,6 +23,7 @@ #include "base/task/sequenced_task_runner.h" #include "base/task/thread_pool.h" #include "base/time/time.h" +#include "base/uuid.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.h" #include "chrome/install_static/install_details.h" @@ -180,7 +180,8 @@ DCHECK(!scoped_temp_dir_->GetPath().empty()); base::FilePath temp_file = scoped_temp_dir_->GetPath().Append( - base::ASCIIToWide(base::GenerateGUID()) + L".tmp"); + base::ASCIIToWide(base::Uuid::GenerateRandomV4().AsLowercaseString()) + + L".tmp"); auto request = std::make_unique<network::ResourceRequest>(); request->url = download_url_;
diff --git a/chrome/browser/ui/android/device_lock/java/src/org/chromium/chrome/browser/ui/device_lock/DeviceLockCoordinator.java b/chrome/browser/ui/android/device_lock/java/src/org/chromium/chrome/browser/ui/device_lock/DeviceLockCoordinator.java index 9275dac4..bf835806 100644 --- a/chrome/browser/ui/android/device_lock/java/src/org/chromium/chrome/browser/ui/device_lock/DeviceLockCoordinator.java +++ b/chrome/browser/ui/android/device_lock/java/src/org/chromium/chrome/browser/ui/device_lock/DeviceLockCoordinator.java
@@ -6,7 +6,9 @@ import android.content.Context; import android.view.LayoutInflater; +import android.view.View; +import org.chromium.chrome.browser.device_reauth.DeviceAuthRequester; import org.chromium.chrome.browser.device_reauth.ReauthenticatorBridge; import org.chromium.ui.base.WindowAndroid; import org.chromium.ui.modelutil.PropertyModelChangeProcessor; @@ -18,6 +20,13 @@ /** Delegate for device lock MVC. */ public interface Delegate { /** + * Logic for the delegate to attach the device lock view to its own UI. + * + * @param view - The device lock root View. + */ + void setView(View view); + + /** * The device has a device lock set and the user has chosen to continue. */ void onDeviceLockReady(); @@ -34,16 +43,31 @@ private final ReauthenticatorBridge mDeviceLockAuthenticatorBridge; private final PropertyModelChangeProcessor mPropertyModelChangeProcessor; + /** + * Constructs a coordinator for the Device Lock page. + * + * @param inSignInFlow - Whether the existing flow is related to account sign-in. + * @param delegate - The delegate invoked to interact with classes outside the module. + * @param windowAndroid - Used to launch Intents with callbacks. + * @param context - The activity context. + */ + public DeviceLockCoordinator( + boolean inSignInFlow, Delegate delegate, WindowAndroid windowAndroid, Context context) { + this(inSignInFlow, delegate, windowAndroid, context, + ReauthenticatorBridge.create(DeviceAuthRequester.DEVICE_LOCK_PAGE)); + } + protected DeviceLockCoordinator(boolean inSignInFlow, Delegate delegate, - WindowAndroid activityWindowAndroid, Context context, + WindowAndroid windowAndroid, Context context, ReauthenticatorBridge deviceLockAuthenticatorBridge) { mView = DeviceLockView.create(LayoutInflater.from(context)); - mWindowAndroid = activityWindowAndroid; + mWindowAndroid = windowAndroid; mDeviceLockAuthenticatorBridge = deviceLockAuthenticatorBridge; mMediator = new DeviceLockMediator( inSignInFlow, delegate, mWindowAndroid, mDeviceLockAuthenticatorBridge, context); mPropertyModelChangeProcessor = PropertyModelChangeProcessor.create( mMediator.getModel(), mView, DeviceLockViewBinder::bind); + delegate.setView(mView); } /**
diff --git a/chrome/browser/ui/android/device_lock/javatests/src/org/chromium/chrome/browser/ui/device_lock/DeviceLockCoordinatorTest.java b/chrome/browser/ui/android/device_lock/javatests/src/org/chromium/chrome/browser/ui/device_lock/DeviceLockCoordinatorTest.java index 1ccd470..e2bfdaf8 100644 --- a/chrome/browser/ui/android/device_lock/javatests/src/org/chromium/chrome/browser/ui/device_lock/DeviceLockCoordinatorTest.java +++ b/chrome/browser/ui/android/device_lock/javatests/src/org/chromium/chrome/browser/ui/device_lock/DeviceLockCoordinatorTest.java
@@ -5,14 +5,23 @@ package org.chromium.chrome.browser.ui.device_lock; import static org.junit.Assert.assertNotEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; import android.content.Context; +import android.view.View; import androidx.test.filters.SmallTest; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; import org.chromium.base.ContextUtils; import org.chromium.base.test.util.Batch; @@ -24,10 +33,17 @@ @RunWith(ChromeJUnit4ClassRunner.class) @Batch(Batch.UNIT_TESTS) public class DeviceLockCoordinatorTest { + @Rule + public final MockitoRule mMockitoRule = MockitoJUnit.rule(); + + @Mock + private MockDelegate mMockDelegate; + private Context mContext; @Before public void setUpTest() { + mMockDelegate = Mockito.mock(MockDelegate.class); mContext = ContextUtils.getApplicationContext(); } @@ -36,14 +52,18 @@ @SmallTest public void testDeviceLockCoordinator_simpleTest() { DeviceLockCoordinator deviceLockCoordinator = - new DeviceLockCoordinator(true, new MockDelegate(), null, mContext, null); + new DeviceLockCoordinator(true, mMockDelegate, null, mContext, null); assertNotEquals(deviceLockCoordinator, null); + verify(mMockDelegate, times(1)).setView(any()); deviceLockCoordinator.destroy(); } private class MockDelegate implements DeviceLockCoordinator.Delegate { @Override + public void setView(View view) {} + + @Override public void onDeviceLockReady() {} @Override
diff --git a/chrome/browser/ui/android/device_lock/junit/src/org/chromium/chrome/browser/ui/device_lock/DeviceLockMediatorUnitTest.java b/chrome/browser/ui/android/device_lock/junit/src/org/chromium/chrome/browser/ui/device_lock/DeviceLockMediatorUnitTest.java index b49a83a..4ad3fa5 100644 --- a/chrome/browser/ui/android/device_lock/junit/src/org/chromium/chrome/browser/ui/device_lock/DeviceLockMediatorUnitTest.java +++ b/chrome/browser/ui/android/device_lock/junit/src/org/chromium/chrome/browser/ui/device_lock/DeviceLockMediatorUnitTest.java
@@ -29,6 +29,7 @@ import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.ResolveInfo; +import android.view.View; import androidx.constraintlayout.utils.widget.MockView; @@ -305,6 +306,9 @@ private class MockDelegate implements DeviceLockCoordinator.Delegate { @Override + public void setView(View view) {} + + @Override public void onDeviceLockReady() {} @Override
diff --git a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/fre/SigninFirstRunCoordinator.java b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/fre/SigninFirstRunCoordinator.java index 73f8438..cbd7085f 100644 --- a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/fre/SigninFirstRunCoordinator.java +++ b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/fre/SigninFirstRunCoordinator.java
@@ -39,6 +39,9 @@ /** Called when the interaction with the page is over and the next page should be shown. */ void advanceToNextPage(); + /** Called to display the device lock page */ + void displayDeviceLockPage(); + /** * Records the FRE progress histogram MobileFre.Progress.*. * @param state FRE state to record. @@ -135,4 +138,12 @@ public void onAccountSelected(String accountName) { mMediator.onAccountSelected(accountName); } + + public void continueSignIn() { + mMediator.proceedWithSignIn(); + } + + public void cancelSignInAndDismiss() { + mMediator.dismiss(); + } }
diff --git a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/fre/SigninFirstRunMediator.java b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/fre/SigninFirstRunMediator.java index 725b6ddc..a8db47f 100644 --- a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/fre/SigninFirstRunMediator.java +++ b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/fre/SigninFirstRunMediator.java
@@ -13,6 +13,7 @@ import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; +import org.chromium.base.BuildInfo; import org.chromium.base.metrics.RecordHistogram; import org.chromium.chrome.browser.firstrun.MobileFreProgress; import org.chromium.chrome.browser.privacy.settings.PrivacyPreferencesManager; @@ -267,6 +268,17 @@ return; } + if (BuildInfo.getInstance().isAutomotive) { + mDelegate.displayDeviceLockPage(); + return; + } + proceedWithSignIn(); + } + + /** + * Accepts ToS and completes the account sign-in with the selected account. + */ + public void proceedWithSignIn() { // This is needed to get metrics/crash reports from the sign-in flow itself. mDelegate.acceptTermsOfService(mAllowMetricsAndCrashUploading); if (mModel.get(SigninFirstRunProperties.IS_SELECTED_ACCOUNT_SUPERVISED)) { @@ -325,6 +337,13 @@ assert mDelegate.getNativeInitializationPromise().isFulfilled(); + dismiss(); + } + + /** + * Dismisses the sign-in page and continues without a signed-in account. + */ + public void dismiss() { mDelegate.recordFreProgressHistogram(MobileFreProgress.WELCOME_DISMISS); mDelegate.acceptTermsOfService(mAllowMetricsAndCrashUploading); SigninPreferencesManager.getInstance().temporarilySuppressNewTabPagePromos();
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/LocationBarModel.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/LocationBarModel.java index e3dbd9f3..3aa9d8b7 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/LocationBarModel.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/LocationBarModel.java
@@ -22,6 +22,7 @@ import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.NativeMethods; import org.chromium.chrome.browser.flags.ChromeFeatureList; +import org.chromium.chrome.browser.flags.MutableFlagWithSafeDefault; import org.chromium.chrome.browser.layouts.LayoutStateProvider; import org.chromium.chrome.browser.omnibox.ChromeAutocompleteSchemeClassifier; import org.chromium.chrome.browser.omnibox.LocationBarDataProvider; @@ -180,6 +181,18 @@ protected String mUrlForDisplay; private boolean mOmniboxUpdatedConnectionSecurityIndicatorsEnabled; + // notifyUrlChanged and notifySecurityStateChanged are usually called 3 times across a same + // document navigation. The first call is usually necessary, which updates the UrlBar to reflect + // the new url. All subsequent calls are spurious and can be avoided. This experiment involves + // using the flags below to short circuit all calls after the UrlBar has already been updated. + private static final MutableFlagWithSafeDefault sSameDocOptimizationsFlag = + new MutableFlagWithSafeDefault( + ChromeFeatureList.REDUCE_TOOLBAR_UPDATES_FOR_SAME_DOC_NAVIGATIONS, true); + private boolean mIsInSameDocNav; + private boolean mIsSameDocNavFinished; + private boolean mAlreadyUpdatedUrlBarForSameDocNav; + private boolean mAlreadyChangedSecurityStateForSameDocNav; + /** * Default constructor for this class. * @param context The Context used for styling the toolbar visuals. @@ -335,12 +348,25 @@ } public void notifyUrlChanged() { - if (!updateVisibleGurl()) return; - // Url has changed, propagate it. + if (shouldDoSameDocOptimzations() && mAlreadyUpdatedUrlBarForSameDocNav) { + return; + } + if (!updateVisibleGurl()) { + return; + } + + // Url has changed, propagate it. for (LocationBarDataProvider.Observer observer : mLocationBarDataObservers) { observer.onUrlChanged(); } + + if (isSameDocOptimizationEnabled()) { + mAlreadyUpdatedUrlBarForSameDocNav = mIsInSameDocNav; + if (mIsSameDocNavFinished) { + resetSameDocNavFlags(); + } + } } public void notifyZeroSuggestRefresh() { @@ -758,6 +784,10 @@ } public void notifySecurityStateChanged() { + if (shouldDoSameDocOptimzations() && mAlreadyChangedSecurityStateForSameDocNav) { + return; + } + @ConnectionSecurityLevel int securityLevel = getSecurityLevel(); if (securityLevel == ConnectionSecurityLevel.DANGEROUS) { @@ -767,6 +797,13 @@ for (LocationBarDataProvider.Observer observer : mLocationBarDataObservers) { observer.onSecurityStateChanged(); } + + if (isSameDocOptimizationEnabled()) { + mAlreadyChangedSecurityStateForSameDocNav = mIsInSameDocNav; + if (mIsSameDocNavFinished) { + resetSameDocNavFlags(); + } + } } private void recalculateFormattedUrls() { @@ -840,6 +877,46 @@ notifyUrlChanged(); } + public void notifyDidStartNavigation(boolean isSameDocument) { + if (isSameDocOptimizationEnabled()) { + resetSameDocNavFlags(); + mIsSameDocNavFinished = false; + mIsInSameDocNav = isSameDocument; + } + } + + public void notifyDidFinishNavigation(boolean isSameDocument) { + if (isSameDocOptimizationEnabled()) { + mIsSameDocNavFinished = true; + } + } + + public void notifyOnCrash() { + resetSameDocNavFlags(); + } + + public void notifyContentChanged() { + resetSameDocNavFlags(); + } + + public void notifyWebContentsSwapped() { + resetSameDocNavFlags(); + } + + public boolean shouldDoSameDocOptimzations() { + return isSameDocOptimizationEnabled() && mIsInSameDocNav; + } + + private boolean isSameDocOptimizationEnabled() { + return sSameDocOptimizationsFlag.isEnabled(); + } + + private void resetSameDocNavFlags() { + mIsInSameDocNav = false; + mAlreadyUpdatedUrlBarForSameDocNav = false; + mAlreadyChangedSecurityStateForSameDocNav = false; + } + @NativeMethods interface Natives { long init(LocationBarModel caller);
diff --git a/chrome/browser/ui/ash/desks/desks_client_browsertest.cc b/chrome/browser/ui/ash/desks/desks_client_browsertest.cc index 8c89f8c..b10e1dd 100644 --- a/chrome/browser/ui/ash/desks/desks_client_browsertest.cc +++ b/chrome/browser/ui/ash/desks/desks_client_browsertest.cc
@@ -164,17 +164,25 @@ return urls; } -// Locate a browser launched from a template whose URLs match `urls`. -Browser* FindLaunchedBrowserByURLs(const std::vector<GURL>& urls) { +// Locate all browsers launched from templates whose URLs match `urls`. +std::vector<Browser*> FindLaunchedBrowsersByURLs( + const std::vector<GURL>& urls) { + std::vector<Browser*> browsers; for (auto* browser : *BrowserList::GetInstance()) { aura::Window* window = browser->window()->GetNativeWindow(); if (window->GetProperty(app_restore::kRestoreWindowIdKey) < kLaunchedWindowIdBase && GetURLsForBrowserWindow(browser) == urls) { - return browser; + browsers.push_back(browser); } } - return nullptr; + return browsers; +} + +// Locate a browser launched from a template whose URLs match `urls`. +Browser* FindLaunchedBrowserByURLs(const std::vector<GURL>& urls) { + auto browsers = FindLaunchedBrowsersByURLs(urls); + return browsers.empty() ? nullptr : browsers.front(); } // TODO(crbug.com/1286515): Remove this. Tests should navigate to overview and @@ -3402,26 +3410,35 @@ struct AdminTemplateDefinition { struct WindowDefinition { std::vector<std::string> urls; + absl::optional<gfx::Rect> bounds; }; std::vector<WindowDefinition> windows; }; + // Converts a `gfx::Rect` to a list, as expected by `RestoreData`. + base::Value::List CreateBounds(const gfx::Rect& bounds) { + base::Value::List list; + list.Append(bounds.x()); + list.Append(bounds.y()); + list.Append(bounds.width()); + list.Append(bounds.height()); + return list; + } + // Creates an admin template with the windows and URLs given by `definition`. std::unique_ptr<ash::DeskTemplate> CreateAdminTemplate( const AdminTemplateDefinition& definition) { - // Common set of bounds to use for now. Later, get from `definition`. - base::Value::List bounds; - for (int b : {100, 50, 400, 300}) { - bounds.Append(b); - } - base::Value::Dict windows; for (size_t i = 0; i != definition.windows.size(); ++i) { base::Value::Dict window; window.Set("title", "Chrome"); window.Set("window_state_type", 0); - window.Set("bounds", bounds.Clone()); + + if (definition.windows[i].bounds) { + window.Set("current_bounds", + CreateBounds(*definition.windows[i].bounds)); + } base::Value::List urls; for (const std::string& url : definition.windows[i].urls) { @@ -3454,8 +3471,9 @@ IN_PROC_BROWSER_TEST_F(AdminTemplateTest, LaunchAdminTemplate) { // Launch an admin template with a single browser. Verifies that a browser was // actually launched. - auto admin_template = - CreateAdminTemplate({.windows = {{.urls = {kExampleUrl1}}}}); + auto admin_template = CreateAdminTemplate( + {.windows = { + {.urls = {kExampleUrl1}, .bounds = gfx::Rect(100, 50, 400, 300)}}}); ASSERT_NE(admin_template, nullptr); base::Uuid template_uuid = admin_template->uuid(); @@ -3489,3 +3507,32 @@ EXPECT_GT(new_index, old_index); } + +IN_PROC_BROWSER_TEST_F(AdminTemplateTest, AdminTemplateWindowOffset) { + // Launch an admin template with a single browser. Verifies that a browser was + // actually launched. + auto admin_template = CreateAdminTemplate( + {.windows = { + {.urls = {kExampleUrl1}, .bounds = gfx::Rect(50, 50, 640, 480)}}}); + ASSERT_NE(admin_template, nullptr); + + base::Uuid template_uuid = admin_template->uuid(); + + auto* saved_desk_controller = ash::Shell::Get()->saved_desk_controller(); + ash::SavedDeskControllerTestApi(saved_desk_controller) + .SetAdminTemplate(std::move(admin_template)); + + // Launch the template twice. + for (int i = 0; i != 2; ++i) { + saved_desk_controller->LaunchAdminTemplate( + template_uuid, display::Screen::GetScreen()->GetPrimaryDisplay().id()); + } + + auto browsers = FindLaunchedBrowsersByURLs({GURL(kExampleUrl1)}); + ASSERT_EQ(browsers.size(), 2u); + + // Verify that the two windows are not in the same position. + aura::Window* window1 = browsers[0]->window()->GetNativeWindow(); + aura::Window* window2 = browsers[1]->window()->GetNativeWindow(); + EXPECT_NE(window1->bounds(), window2->bounds()); +}
diff --git a/chrome/browser/ui/quick_answers/quick_answers_browsertest.cc b/chrome/browser/ui/quick_answers/quick_answers_browsertest.cc index b2a0a4ca..db01212e 100644 --- a/chrome/browser/ui/quick_answers/quick_answers_browsertest.cc +++ b/chrome/browser/ui/quick_answers/quick_answers_browsertest.cc
@@ -10,6 +10,7 @@ #include "base/functional/callback_forward.h" #include "base/run_loop.h" #include "base/strings/string_piece_forward.h" +#include "base/strings/utf_string_conversions.h" #include "base/test/scoped_feature_list.h" #include "base/time/time.h" #include "base/timer/timer.h" @@ -51,6 +52,9 @@ constexpr char16_t kTestNotificationDisplaySource[] = u"display-source"; constexpr char kTestNotificationOriginUrl[] = "https://example.com/"; +constexpr char16_t kSourceText[] = u"prodotto"; +constexpr char16_t kTranslatedText[] = u"product"; + constexpr int kFakeImageWidth = 300; constexpr int kFakeImageHeight = 300; @@ -237,12 +241,28 @@ quick_answer->title.push_back( std::make_unique<quick_answers::QuickAnswerText>( l10n_util::GetStringFUTF8(IDS_QUICK_ANSWERS_TRANSLATION_TITLE_TEXT, - u"prodotto", u"Italian"))); + kSourceText, u"Italian"))); quick_answer->first_answer_row.push_back( std::make_unique<quick_answers::QuickAnswerResultText>( - l10n_util::GetStringUTF8(IDS_QUICK_ANSWERS_TRANSLATION_INTENT))); + base::UTF16ToUTF8(kTranslatedText))); + + std::unique_ptr<TranslationResult> translation_result = + std::make_unique<TranslationResult>(); + translation_result->text_to_translate = kSourceText; + translation_result->translated_text = kTranslatedText; + translation_result->target_locale = "en"; + translation_result->source_locale = "it"; + + std::unique_ptr<QuickAnswersSession> quick_answers_session = + std::make_unique<QuickAnswersSession>(); + quick_answers_session->quick_answer = std::move(quick_answer); + quick_answers_session->structured_result = + std::make_unique<StructuredResult>(); + quick_answers_session->structured_result->translation_result = + std::move(translation_result); + controller()->GetQuickAnswersDelegate()->OnQuickAnswerReceived( - std::move(quick_answer)); + std::move(quick_answers_session)); // Click on the quick answers view to trigger the rich answers view. views::NamedWidgetShownWaiter rich_answers_view_widget_waiter(
diff --git a/chrome/browser/ui/quick_answers/quick_answers_controller_impl.cc b/chrome/browser/ui/quick_answers/quick_answers_controller_impl.cc index 49d7bdb..527503e 100644 --- a/chrome/browser/ui/quick_answers/quick_answers_controller_impl.cc +++ b/chrome/browser/ui/quick_answers/quick_answers_controller_impl.cc
@@ -9,6 +9,7 @@ #include "chrome/browser/ui/quick_answers/quick_answers_ui_controller.h" #include "chromeos/components/quick_answers/public/cpp/quick_answers_prefs.h" #include "chromeos/components/quick_answers/public/cpp/quick_answers_state.h" +#include "chromeos/components/quick_answers/quick_answers_model.h" #include "chromeos/strings/grit/chromeos_strings.h" #include "components/prefs/pref_service.h" #include "ui/base/l10n/l10n_util.h" @@ -105,7 +106,7 @@ title_ = title; query_ = title; context_ = context; - quick_answer_.reset(); + quick_answers_session_.reset(); QuickAnswersRequest request = BuildRequest(); if (QuickAnswersState::Get()->ShouldUseQuickAnswersTextAnnotator()) { @@ -164,16 +165,16 @@ case QuickAnswersVisibility::kClosed: { bool closed = quick_answers_ui_controller_->CloseQuickAnswersView(); visibility_ = QuickAnswersVisibility::kClosed; - // |quick_answer_| could be null before we receive the result from the - // server. Do not send the signal since the quick answer is dismissed - // before ready. - if (quick_answer_) { + // |quick_answers_session_| could be null before we receive the result + // from the server. Do not send the signal since the quick answer is + // dismissed before ready. + if (quick_answers_session_ && quick_answer()) { // For quick-answer rendered along with browser context menu, if user // didn't click on other context menu items, it is considered as active // impression. bool is_active = exit_point != QuickAnswersExitPoint::kContextMenuClick; quick_answers_client_->OnQuickAnswersDismissed( - quick_answer_->result_type, is_active && closed); + quick_answer()->result_type, is_active && closed); // Record Quick Answers exit point. // Make sure |closed| is true so that only the direct exit point is @@ -205,18 +206,20 @@ } void QuickAnswersControllerImpl::OnQuickAnswerReceived( - std::unique_ptr<QuickAnswer> quick_answer) { + std::unique_ptr<quick_answers::QuickAnswersSession> quick_answers_session) { if (visibility_ != QuickAnswersVisibility::kQuickAnswersVisible) { return; } - if (quick_answer) { - if (quick_answer->title.empty()) { - quick_answer->title.push_back( + quick_answers_session_ = std::move(quick_answers_session); + + if (quick_answer()) { + if (quick_answer()->title.empty()) { + quick_answer()->title.push_back( std::make_unique<quick_answers::QuickAnswerText>(title_)); } quick_answers_ui_controller_->RenderQuickAnswersViewWithResult( - anchor_bounds_, *quick_answer); + anchor_bounds_, *quick_answer()); } else { quick_answers::QuickAnswer quick_answer_with_no_result; quick_answer_with_no_result.title.push_back( @@ -230,8 +233,6 @@ query_ = title_; quick_answers_ui_controller_->SetActiveQuery(query_); } - - quick_answer_ = std::move(quick_answer); } void QuickAnswersControllerImpl::OnNetworkError() { @@ -280,7 +281,7 @@ void QuickAnswersControllerImpl::OnQuickAnswerClick() { quick_answers_client_->OnQuickAnswerClick( - quick_answer_ ? quick_answer_->result_type : ResultType::kNoResult); + quick_answer() ? quick_answer()->result_type : ResultType::kNoResult); } void QuickAnswersControllerImpl::UpdateQuickAnswersAnchorBounds(
diff --git a/chrome/browser/ui/quick_answers/quick_answers_controller_impl.h b/chrome/browser/ui/quick_answers/quick_answers_controller_impl.h index 6c4e9a2f..c62ce38 100644 --- a/chrome/browser/ui/quick_answers/quick_answers_controller_impl.h +++ b/chrome/browser/ui/quick_answers/quick_answers_controller_impl.h
@@ -52,8 +52,8 @@ void SetVisibility(QuickAnswersVisibility visibility) override; // QuickAnswersDelegate: - void OnQuickAnswerReceived( - std::unique_ptr<quick_answers::QuickAnswer> answer) override; + void OnQuickAnswerReceived(std::unique_ptr<quick_answers::QuickAnswersSession> + quick_answers_session) override; void OnNetworkError() override; void OnRequestPreprocessFinished( const quick_answers::QuickAnswersRequest& processed_request) override; @@ -71,7 +71,15 @@ return quick_answers_ui_controller_.get(); } - quick_answers::QuickAnswer* quick_answer() { return quick_answer_.get(); } + raw_ptr<quick_answers::QuickAnswer> quick_answer() { + return quick_answers_session_ ? quick_answers_session_->quick_answer.get() + : nullptr; + } + raw_ptr<quick_answers::StructuredResult> structured_result() { + return quick_answers_session_ + ? quick_answers_session_->structured_result.get() + : nullptr; + } private: void HandleQuickAnswerRequest( @@ -102,8 +110,8 @@ std::unique_ptr<QuickAnswersUiController> quick_answers_ui_controller_; - // The last received QuickAnswer from client. - std::unique_ptr<quick_answers::QuickAnswer> quick_answer_; + // The last received `QuickAnswersSession` from client. + std::unique_ptr<quick_answers::QuickAnswersSession> quick_answers_session_; QuickAnswersVisibility visibility_ = QuickAnswersVisibility::kClosed; };
diff --git a/chrome/browser/ui/quick_answers/quick_answers_ui_controller.cc b/chrome/browser/ui/quick_answers/quick_answers_ui_controller.cc index acc5b7a..f44f345 100644 --- a/chrome/browser/ui/quick_answers/quick_answers_ui_controller.cc +++ b/chrome/browser/ui/quick_answers/quick_answers_ui_controller.cc
@@ -9,6 +9,7 @@ #include "base/strings/stringprintf.h" #include "build/chromeos_buildflags.h" #include "chrome/browser/ui/quick_answers/quick_answers_controller_impl.h" +#include "chrome/browser/ui/quick_answers/ui/rich_answers_translation_view.h" #include "chrome/browser/ui/quick_answers/ui/rich_answers_view.h" #include "chromeos/components/quick_answers/public/cpp/quick_answers_state.h" #include "chromeos/components/quick_answers/quick_answers_model.h" @@ -106,6 +107,10 @@ controller_->quick_answer() != nullptr && controller_->quick_answer()->result_type != quick_answers::ResultType::kNoResult) { + // TODO(b/279061152): Build result type specific rich answers view with + // reading `controller_->structured_result()`. Note that each result type + // will be copyable, i.e. we can copy a struct to a view without worrying + // about object-life-time management. auto* const rich_answers_view = new quick_answers::RichAnswersView( quick_answers_view_tracker_.view()->bounds(), weak_factory_.GetWeakPtr(), *controller_->quick_answer());
diff --git a/chrome/browser/ui/tabs/tab_strip_model.cc b/chrome/browser/ui/tabs/tab_strip_model.cc index 800732d7..0a17b70 100644 --- a/chrome/browser/ui/tabs/tab_strip_model.cc +++ b/chrome/browser/ui/tabs/tab_strip_model.cc
@@ -194,7 +194,7 @@ std::unique_ptr<TabGroupModel> TabGroupModelFactory::Create( TabGroupController* controller) { - return absl::make_unique<TabGroupModel>(controller); + return std::make_unique<TabGroupModel>(controller); } ///////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/ui/toolbar/app_menu_model.cc b/chrome/browser/ui/toolbar/app_menu_model.cc index c53244ad..ba2a88e 100644 --- a/chrome/browser/ui/toolbar/app_menu_model.cc +++ b/chrome/browser/ui/toolbar/app_menu_model.cc
@@ -865,6 +865,13 @@ UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.AppInfo", delta); LogMenuAction(MENU_ACTION_APP_INFO); break; + case IDC_VIEW_PASSWORDS: + if (!uma_action_recorded_) { + UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.PasswordManager", + delta); + } + LogMenuAction(MENU_ACTION_PASSWORD_MANAGER); + break; } if (!uma_action_recorded_) {
diff --git a/chrome/browser/ui/toolbar/app_menu_model.h b/chrome/browser/ui/toolbar/app_menu_model.h index 8b21b66..00d7ad3 100644 --- a/chrome/browser/ui/toolbar/app_menu_model.h +++ b/chrome/browser/ui/toolbar/app_menu_model.h
@@ -83,6 +83,7 @@ MENU_ACTION_MENU_OPENED = 56, // Only used by ExtensionsMenuModel sub menu. MENU_ACTION_VISIT_CHROME_WEB_STORE = 57, + MENU_ACTION_PASSWORD_MANAGER = 58, LIMIT_MENU_ACTION };
diff --git a/chrome/browser/ui/toolbar/app_menu_model_interactive_uitest.cc b/chrome/browser/ui/toolbar/app_menu_model_interactive_uitest.cc index 8167a44..88ac7c5 100644 --- a/chrome/browser/ui/toolbar/app_menu_model_interactive_uitest.cc +++ b/chrome/browser/ui/toolbar/app_menu_model_interactive_uitest.cc
@@ -2,6 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "chrome/browser/ui/toolbar/app_menu_model.h" + +#include "base/feature_list.h" #include "base/logging.h" #include "base/test/bind.h" #include "base/test/gtest_util.h" @@ -13,7 +16,6 @@ #include "chrome/browser/ui/browser_element_identifiers.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/browser_window.h" -#include "chrome/browser/ui/toolbar/app_menu_model.h" #include "chrome/browser/ui/ui_features.h" #include "chrome/common/webui_url_constants.h" #include "chrome/test/base/interactive_test_utils.h" @@ -21,6 +23,7 @@ #include "chrome/test/interaction/interactive_browser_test.h" #include "chrome/test/interaction/tracked_element_webcontents.h" #include "chrome/test/interaction/webcontents_interaction_test_util.h" +#include "components/password_manager/core/common/password_manager_features.h" #include "components/performance_manager/public/features.h" #include "content/public/test/browser_test.h" #include "extensions/common/extension_urls.h" @@ -203,3 +206,46 @@ histograms.ExpectBucketCount("WrenchMenu.MenuAction", MENU_ACTION_MANAGE_EXTENSIONS, 0); } + +class PasswordManagerMenuItemInteractiveTest + : public AppMenuModelInteractiveTest, + public testing::WithParamInterface<bool> { + public: + PasswordManagerMenuItemInteractiveTest() { + scoped_feature_list_.InitWithFeatureState( + password_manager::features::kPasswordManagerRedesign, GetParam()); + } + PasswordManagerMenuItemInteractiveTest( + const PasswordManagerMenuItemInteractiveTest&) = delete; + void operator=(const PasswordManagerMenuItemInteractiveTest&) = delete; + + ~PasswordManagerMenuItemInteractiveTest() override = default; +}; + +INSTANTIATE_TEST_SUITE_P( + All, + PasswordManagerMenuItemInteractiveTest, + /* features::kPasswordManagerRedesign status */ testing::Bool()); + +IN_PROC_BROWSER_TEST_P(PasswordManagerMenuItemInteractiveTest, + PasswordManagerMenuItem) { + base::HistogramTester histograms; + + if (base::FeatureList::IsEnabled( + password_manager::features::kPasswordManagerRedesign)) { + RunTestSequence(InstrumentTab(kPrimaryTabPageElementId), + PressButton(kAppMenuButtonElementId), + SelectMenuItem(AppMenuModel::kPasswordManagerMenuItem), + WaitForWebContentsNavigation( + kPrimaryTabPageElementId, + GURL("chrome://password-manager/passwords"))); + + histograms.ExpectTotalCount("WrenchMenu.TimeToAction.PasswordManager", 1); + histograms.ExpectBucketCount("WrenchMenu.MenuAction", + MENU_ACTION_PASSWORD_MANAGER, 1); + } else { + RunTestSequence(InstrumentTab(kPrimaryTabPageElementId), + PressButton(kAppMenuButtonElementId), + EnsureNotPresent(AppMenuModel::kPasswordManagerMenuItem)); + } +}
diff --git a/chrome/browser/ui/views/passwords/manage_passwords_list_view.cc b/chrome/browser/ui/views/passwords/manage_passwords_list_view.cc index 335cb97b..8bc00d08 100644 --- a/chrome/browser/ui/views/passwords/manage_passwords_list_view.cc +++ b/chrome/browser/ui/views/passwords/manage_passwords_list_view.cc
@@ -18,6 +18,7 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/base/models/image_model.h" #include "ui/gfx/favicon_size.h" +#include "ui/gfx/vector_icon_utils.h" #include "ui/views/bubble/bubble_frame_view.h" #include "ui/views/controls/separator.h" #include "ui/views/view_class_properties.h" @@ -40,11 +41,19 @@ DISTANCE_BUBBLE_HEADER_VECTOR_ICON_SIZE)))); views::Label* title_label = header->AddChildView( views::BubbleFrameView::CreateDefaultTitleLabel(title)); - // For simplicity use full width of the bubble instead of subtracting the - // space for the icon and the close button. It is more important that the - // bubble does not grow arbitrarily long than the actual max width. - title_label->SetMaximumWidth(layout_provider->GetDistanceMetric( - views::DISTANCE_BUBBLE_PREFERRED_WIDTH)); + + const int close_button_width = + layout_provider->GetDistanceMetric( + views::DISTANCE_RELATED_BUTTON_HORIZONTAL) + + gfx::GetDefaultSizeOfVectorIcon(vector_icons::kCloseRoundedIcon) + + layout_provider->GetDistanceMetric(views::DISTANCE_CLOSE_BUTTON_MARGIN); + const int title_width = + layout_provider->GetDistanceMetric( + views::DISTANCE_BUBBLE_PREFERRED_WIDTH) - + layout_provider->GetInsetsMetric(views::INSETS_DIALOG).width() - + layout_provider->GetInsetsMetric(views::INSETS_DIALOG_TITLE).width() - + close_button_width; + title_label->SetMaximumWidth(title_width); return header; }
diff --git a/chrome/browser/ui/webui/settings/ash/device_section.cc b/chrome/browser/ui/webui/settings/ash/device_section.cc index 508490cc..9e547ba 100644 --- a/chrome/browser/ui/webui/settings/ash/device_section.cc +++ b/chrome/browser/ui/webui/settings/ash/device_section.cc
@@ -1710,6 +1710,7 @@ {"touchpadScrollAccelerationLabel", IDS_SETTINGS_TOUCHPAD_SCROLL_ACCELERATION_LABEL}, {"touchpadScrollSpeed", IDS_SETTINGS_TOUCHPAD_SCROLL_SPEED_LABEL}, + {"learnMoreLabel", IDS_SETTINGS_LEARN_MORE_LABEL}, }; html_source->AddLocalizedStrings(kPointersStrings);
diff --git a/chrome/browser/ui/webui/settings/ash/multidevice_handler.cc b/chrome/browser/ui/webui/settings/ash/multidevice_handler.cc index 2c6ab1b..b2288b4 100644 --- a/chrome/browser/ui/webui/settings/ash/multidevice_handler.cc +++ b/chrome/browser/ui/webui/settings/ash/multidevice_handler.cc
@@ -315,6 +315,14 @@ camera_roll_manager_observation_.Reset(); } + if (phonehub::BrowserTabsModelProviderImpl:: + IsLacrosSessionSyncFeatureEnabled() && + browser_tabs_model_provider_) { + DCHECK(browser_tabs_model_provider_observation_.IsObservingSource( + browser_tabs_model_provider_)); + browser_tabs_model_provider_observation_.Reset(); + } + // Ensure that pending callbacks do not complete and cause JS to be evaluated. callback_weak_ptr_factory_.InvalidateWeakPtrs(); }
diff --git a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc index 7eb7329..3a64ca5 100644 --- a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
@@ -2564,6 +2564,11 @@ {"noHidDevicesFound", IDS_SETTINGS_NO_HID_DEVICES_FOUND}, {"noSerialPortsFound", IDS_SETTINGS_NO_SERIAL_PORTS_FOUND}, {"noUsbDevicesFound", IDS_SETTINGS_NO_USB_DEVICES_FOUND}, + {"resetBluetoothConfirmation", IDS_SETTINGS_RESET_BLUETOOTH_CONFIRMATION}, + {"resetHidConfirmation", IDS_SETTINGS_RESET_HID_CONFIRMATION}, + {"resetSerialPortsConfirmation", + IDS_SETTINGS_RESET_SERIAL_PORTS_CONFIRMATION}, + {"resetUsbConfirmation", IDS_SETTINGS_RESET_USB_CONFIRMATION}, {"serviceWorkerOrigin", IDS_SETTINGS_COOKIES_LOCAL_STORAGE_ORIGIN_LABEL}, {"serviceWorkerSize", IDS_SETTINGS_COOKIES_LOCAL_STORAGE_SIZE_ON_DISK_LABEL},
diff --git a/chrome/browser/ui/webui/side_panel/read_anything/read_anything_app_browsertest.cc b/chrome/browser/ui/webui/side_panel/read_anything/read_anything_app_browsertest.cc new file mode 100644 index 0000000..3dd86477 --- /dev/null +++ b/chrome/browser/ui/webui/side_panel/read_anything/read_anything_app_browsertest.cc
@@ -0,0 +1,202 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Test chrome/browser/resources/side_panel/read_anything/app.ts here. Add a new +// test script to chrome/test/data/webui/side_panel/read_anything and add a new +// pass the file name to RunTest in this file. + +#include "base/files/file_util.h" +#include "base/path_service.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/common/chrome_paths.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 "content/public/test/browser_test.h" +#include "ui/accessibility/accessibility_features.h" + +class ReadAnythingAppTest : public InProcessBrowserTest { + public: + ReadAnythingAppTest() { + scoped_feature_list_.InitAndEnableFeature(features::kReadAnything); + } + ~ReadAnythingAppTest() override = default; + ReadAnythingAppTest(const ReadAnythingAppTest&) = delete; + ReadAnythingAppTest& operator=(const ReadAnythingAppTest&) = delete; + + testing::AssertionResult RunTest(const char* name) { + std::string script; + { + base::ScopedAllowBlockingForTesting allow_blocking; + // Tests are located in + // chrome/test/data/webui/side_panel/read_anything/$(name). + base::FilePath path; + base::PathService::Get(chrome::DIR_TEST_DATA, &path); + path = path.AppendASCII("webui") + .AppendASCII("side_panel") + .AppendASCII("read_anything") + .AppendASCII(name); + + // Read the test. + if (!base::PathExists(path)) { + return testing::AssertionFailure() << "Couldn't find " << path.value(); + } + base::ReadFileToString(path, &script); + script = "(function(){'use strict';" + script + "}());"; + } + + // Run the test. + bool result = false; + EXPECT_TRUE(ui_test_utils::NavigateToURL( + browser(), GURL(chrome::kChromeUIUntrustedReadAnythingSidePanelURL))); + content::RenderFrameHost* webui = browser() + ->tab_strip_model() + ->GetActiveWebContents() + ->GetPrimaryMainFrame(); + if (!webui) { + return testing::AssertionFailure() << "Failed to navigate to WebUI"; + } + + EXPECT_TRUE(content::ExecuteScriptAndExtractBool(webui, script, &result)); + return result ? testing::AssertionSuccess() + : (testing::AssertionFailure() << "Check console output"); + } + + private: + base::test::ScopedFeatureList scoped_feature_list_; +}; + +IN_PROC_BROWSER_TEST_F(ReadAnythingAppTest, UpdateTheme_FontName) { + ASSERT_TRUE(RunTest("update_theme_font_name.js")); +} + +IN_PROC_BROWSER_TEST_F(ReadAnythingAppTest, DISABLED_UpdateTheme_FontSize) { + ASSERT_TRUE(RunTest("update_theme_font_size.js")); +} + +IN_PROC_BROWSER_TEST_F(ReadAnythingAppTest, UpdateTheme_ForegroundColor) { + ASSERT_TRUE(RunTest("update_theme_foreground_color.js")); +} + +IN_PROC_BROWSER_TEST_F(ReadAnythingAppTest, + DISABLED_UpdateTheme_BackgroundColor) { + ASSERT_TRUE(RunTest("update_theme_background_color.js")); +} + +IN_PROC_BROWSER_TEST_F(ReadAnythingAppTest, DISABLED_UpdateTheme_LineSpacing) { + ASSERT_TRUE(RunTest("update_theme_line_spacing.js")); +} + +IN_PROC_BROWSER_TEST_F(ReadAnythingAppTest, + DISABLED_UpdateTheme_LetterSpacing) { + ASSERT_TRUE(RunTest("update_theme_letter_spacing.js")); +} + +IN_PROC_BROWSER_TEST_F(ReadAnythingAppTest, + ConnectedCallback_ShowLoadingScreen) { + ASSERT_TRUE(RunTest("connected_callback_show_loading_screen.js")); +} + +IN_PROC_BROWSER_TEST_F( + ReadAnythingAppTest, + OnSelectionChange_NothingSelectedOnLoadingScreenSelection) { + ASSERT_TRUE(RunTest( + "on_selection_change_nothing_selected_on_loading_screen_selection.js")); +} + +IN_PROC_BROWSER_TEST_F(ReadAnythingAppTest, UpdateContent_HidesLoadingScreen) { + ASSERT_TRUE(RunTest("update_content_hides_loading_screen.js")); +} + +IN_PROC_BROWSER_TEST_F(ReadAnythingAppTest, UpdateContent_Paragraph) { + ASSERT_TRUE(RunTest("update_content_paragraph.js")); +} + +IN_PROC_BROWSER_TEST_F(ReadAnythingAppTest, + UpdateContent_Language_ChildNodeDiffLang) { + ASSERT_TRUE(RunTest("update_content_language_child_node_diff_lang.js")); +} + +IN_PROC_BROWSER_TEST_F(ReadAnythingAppTest, + UpdateContent_Language_ParentLangSet) { + ASSERT_TRUE(RunTest("update_content_language_parent_lang_set.js")); +} + +IN_PROC_BROWSER_TEST_F(ReadAnythingAppTest, UpdateContent_Heading) { + ASSERT_TRUE(RunTest("update_content_heading.js")); +} + +IN_PROC_BROWSER_TEST_F(ReadAnythingAppTest, UpdateContent_Link) { + ASSERT_TRUE(RunTest("update_content_link.js")); +} + +IN_PROC_BROWSER_TEST_F(ReadAnythingAppTest, UpdateContent_Link_BadInput) { + ASSERT_TRUE(RunTest("update_content_link_bad_input.js")); +} + +IN_PROC_BROWSER_TEST_F(ReadAnythingAppTest, UpdateContent_StaticText) { + ASSERT_TRUE(RunTest("update_content_static_text.js")); +} + +IN_PROC_BROWSER_TEST_F(ReadAnythingAppTest, UpdateContent_StaticText_BadInput) { + ASSERT_TRUE(RunTest("update_content_static_text_bad_input.js")); +} + +IN_PROC_BROWSER_TEST_F(ReadAnythingAppTest, UpdateContent_ClearContainer) { + ASSERT_TRUE(RunTest("update_content_clear_container.js")); +} + +IN_PROC_BROWSER_TEST_F(ReadAnythingAppTest, UpdateContent_Selection) { + ASSERT_TRUE(RunTest("update_content_selection.js")); +} + +IN_PROC_BROWSER_TEST_F(ReadAnythingAppTest, UpdateContent_Selection_Backwards) { + ASSERT_TRUE(RunTest("update_content_selection_backwards.js")); +} + +IN_PROC_BROWSER_TEST_F(ReadAnythingAppTest, + UpdateContent_Selection_OutsideDistilledContent) { + ASSERT_TRUE(RunTest("update_content_selection_outside_distilled_content.js")); +} + +IN_PROC_BROWSER_TEST_F( + ReadAnythingAppTest, + UpdateContent_Selection_PartiallyOutsideDistilledContent) { + ASSERT_TRUE(RunTest( + "update_content_selection_partially_outside_distilled_content.js")); +} + +IN_PROC_BROWSER_TEST_F(ReadAnythingAppTest, UpdateContent_SetSelectedText) { + ASSERT_TRUE(RunTest("update_content_set_selected_text.js")); +} + +IN_PROC_BROWSER_TEST_F(ReadAnythingAppTest, UpdateContent_TextDirection) { + ASSERT_TRUE(RunTest("update_content_text_direction.js")); +} + +IN_PROC_BROWSER_TEST_F(ReadAnythingAppTest, + UpdateContent_TextDirection_ParentNodeDiffDir) { + ASSERT_TRUE(RunTest("update_content_text_direction_parent_node_diff_dir.js")); +} + +IN_PROC_BROWSER_TEST_F(ReadAnythingAppTest, + UpdateContent_TextDirection_VerticalDir) { + ASSERT_TRUE(RunTest("update_content_text_direction_vertical_dir.js")); +} + +IN_PROC_BROWSER_TEST_F(ReadAnythingAppTest, UpdateContent_TextStyle_Overline) { + ASSERT_TRUE(RunTest("update_content_text_style_overline.js")); +} + +IN_PROC_BROWSER_TEST_F(ReadAnythingAppTest, UpdateContent_TextStyle_Bold) { + ASSERT_TRUE(RunTest("update_content_text_style_bold.js")); +} + +IN_PROC_BROWSER_TEST_F(ReadAnythingAppTest, UpdateContent_NoContentNodes) { + ASSERT_TRUE(RunTest("update_content_no_content_nodes.js")); +} + +IN_PROC_BROWSER_TEST_F(ReadAnythingAppTest, UpdateContent_InteractiveElement) { + ASSERT_TRUE(RunTest("update_content_interactive_element.js")); +}
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt index 7160814..1cea2587 100644 --- a/chrome/build/mac-arm.pgo.txt +++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@ -chrome-mac-arm-main-1682344142-b85859336025538f4445a76681a640e6340b71c6.profdata +chrome-mac-arm-main-1682351986-8ed2b2f46238bdf2904d724249589069861e8cae.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index cf2a7fe..07efc07 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1682337200-a6c4ff538fe6624799036953c506c12d59f80a93.profdata +chrome-win32-main-1682348397-46d998e3219286ae7ce1a9e713229107625154c1.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index ff61bc9c..5d110f315 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1682337200-bb29ac96eb2c6520b22458bb4e0d3ea43efa1e7b.profdata +chrome-win64-main-1682348397-19546752424be0b7a659b515dafebef9f73fb604.profdata
diff --git a/chrome/common/safe_browsing/seven_zip_analyzer.cc b/chrome/common/safe_browsing/seven_zip_analyzer.cc index c1e24b7..0bff74c 100644 --- a/chrome/common/safe_browsing/seven_zip_analyzer.cc +++ b/chrome/common/safe_browsing/seven_zip_analyzer.cc
@@ -4,15 +4,14 @@ #include "chrome/common/safe_browsing/seven_zip_analyzer.h" -#include "base/files/memory_mapped_file.h" +#include "base/feature_list.h" #include "base/memory/raw_ptr.h" #include "base/metrics/histogram_functions.h" #include "base/time/time.h" #include "build/build_config.h" #include "chrome/common/safe_browsing/archive_analyzer_results.h" #include "components/safe_browsing/content/common/file_type_policies.h" -#include "third_party/abseil-cpp/absl/types/optional.h" -#include "third_party/lzma_sdk/google/seven_zip_reader.h" +#include "components/safe_browsing/core/common/features.h" #if BUILDFLAG(IS_WIN) #include <windows.h> @@ -24,122 +23,6 @@ namespace safe_browsing { -namespace { - -constexpr base::TimeDelta kAnalysisTimeout = base::Seconds(10); - -class SevenZipDelegate : public seven_zip::Delegate { - public: - SevenZipDelegate(ArchiveAnalyzerResults* results, - base::File temp_file, - base::File temp_file2) - : results_(results), - temp_file_(std::move(temp_file)), - temp_file2_(std::move(temp_file2)) { - results_->success = false; - results_->analysis_result = ArchiveAnalysisResult::kUnknown; - results_->file_count = 0; - results_->directory_count = 0; - } - - void OnOpenError(seven_zip::Result result) override { - success_ = false; - results_->analysis_result = ArchiveAnalysisResult::kFailedToOpen; - } - - base::File OnTempFileRequest() override { return std::move(temp_file2_); } - - bool OnEntry(const seven_zip::EntryInfo& entry, - base::span<uint8_t>& output) override { - if (base::TimeTicks::Now() - start_time_ > kAnalysisTimeout) { - results_->success = false; - results_->analysis_result = ArchiveAnalysisResult::kTimeout; - return false; - } - - if (entry.file_size == 0) { - // Empty files try to initialize the memory mapping with region {0, 0}, - // which is confused with Region::kWholeFile. Since we can't truncate the - // file within the utility process sandbox, the file still has contents - // from a previous entry, and we end up mapping those contents. This leads - // to CHECK failures since `output.size()` does not match - // `entry.file_size`. Since the file is actually empty, we can skip the - // memory mapping here to avoid this. - output = base::span<uint8_t>(); - return true; - } - - mapped_file_.emplace(); - bool mapped_file_ok = mapped_file_->Initialize( - temp_file_.Duplicate(), {0, static_cast<size_t>(entry.file_size)}, - base::MemoryMappedFile::READ_WRITE_EXTEND); - if (!mapped_file_ok) { - results_->success = false; - results_->analysis_result = ArchiveAnalysisResult::kUnknown; - return false; - } - - output = base::span<uint8_t>(mapped_file_->data(), mapped_file_->length()); - return true; - } - - bool OnDirectory(const seven_zip::EntryInfo& entry) override { - if (base::TimeTicks::Now() - start_time_ > kAnalysisTimeout) { - results_->success = false; - results_->analysis_result = ArchiveAnalysisResult::kTimeout; - return false; - } - - UpdateArchiveAnalyzerResultsWithFile(entry.file_path, &temp_file_, - entry.file_size, entry.is_encrypted, - /*is_directory=*/true, results_); - results_->directory_count++; - return true; - } - - bool EntryDone(seven_zip::Result result, - const seven_zip::EntryInfo& entry) override { - base::UmaHistogramEnumeration("SBClientDownload.SevenZipEntryResult", - result); - - if (base::TimeTicks::Now() - start_time_ > kAnalysisTimeout) { - results_->success = false; - results_->analysis_result = ArchiveAnalysisResult::kTimeout; - return false; - } - - results_->file_count++; - - // Since unpacking an encrypted entry is expected to fail, allow all results - // here for encrypted entries. - if (result == seven_zip::Result::kSuccess || entry.is_encrypted) { - // TODO(crbug/1373509): We have the entire file in memory, so it's silly - // to do all this work to flush it and read it back. Can we simplify this - // process? This also reduces the risk that the file is not flushed fully. - mapped_file_.reset(); - UpdateArchiveAnalyzerResultsWithFile(entry.file_path, &temp_file_, - entry.file_size, entry.is_encrypted, - /*is_directory=*/false, results_); - } else { - success_ = false; - } - - return true; - } - - bool success() const { return success_; } - - private: - const raw_ptr<ArchiveAnalyzerResults> results_; - base::File temp_file_; - base::File temp_file2_; - const base::TimeTicks start_time_{base::TimeTicks::Now()}; - bool success_ = true; - absl::optional<base::MemoryMappedFile> mapped_file_; -}; - -} // namespace - SevenZipAnalyzer::~SevenZipAnalyzer() = default; SevenZipAnalyzer::SevenZipAnalyzer() = default; @@ -183,27 +66,159 @@ std::move(finished_analysis_callback_).Run(); return; } - AnalyzeSevenZipFile(); -} -void SevenZipAnalyzer::AnalyzeSevenZipFile() { - SevenZipDelegate delegate(results_, std::move(temp_file_), - std::move(temp_file2_)); - std::unique_ptr<seven_zip::SevenZipReader> reader = - seven_zip::SevenZipReader::Create(std::move(seven_zip_file_), delegate); - if (!reader) { + results_->success = true; + results_->analysis_result = ArchiveAnalysisResult::kValid; + + reader_ = + seven_zip::SevenZipReader::Create(std::move(seven_zip_file_), *this); + if (!reader_) { + // We will have been notified through OnOpenError and updated `results_` + // appropriately std::move(finished_analysis_callback_).Run(); return; } - reader->Extract(); + AnalyzeSevenZipFile(); +} - if (delegate.success()) { - results_->success = true; - results_->analysis_result = ArchiveAnalysisResult::kValid; +void SevenZipAnalyzer::AnalyzeSevenZipFile() { + reader_->Extract(); + + if (!awaiting_nested_) { + std::move(finished_analysis_callback_).Run(); + } +} + +void SevenZipAnalyzer::OnOpenError(seven_zip::Result result) { + results_->success = false; + results_->analysis_result = ArchiveAnalysisResult::kFailedToOpen; +} + +base::File SevenZipAnalyzer::OnTempFileRequest() { + return std::move(temp_file2_); +} + +bool SevenZipAnalyzer::OnEntry(const seven_zip::EntryInfo& entry, + base::span<uint8_t>& output) { + if (entry.file_size == 0) { + // Empty files try to initialize the memory mapping with region {0, 0}, + // which is confused with Region::kWholeFile. Since we can't truncate the + // file within the utility process sandbox, the file still has contents + // from a previous entry, and we end up mapping those contents. This leads + // to CHECK failures since `output.size()` does not match + // `entry.file_size`. Since the file is actually empty, we can skip the + // memory mapping here to avoid this. + output = base::span<uint8_t>(); + return true; } - std::move(finished_analysis_callback_).Run(); + mapped_file_.emplace(); + bool mapped_file_ok = mapped_file_->Initialize( + temp_file_.Duplicate(), {0, static_cast<size_t>(entry.file_size)}, + base::MemoryMappedFile::READ_WRITE_EXTEND); + if (!mapped_file_ok) { + results_->success = false; + results_->analysis_result = ArchiveAnalysisResult::kUnknown; + return false; + } + + output = base::span<uint8_t>(mapped_file_->data(), mapped_file_->length()); + return true; +} + +bool SevenZipAnalyzer::OnDirectory(const seven_zip::EntryInfo& entry) { + UpdateArchiveAnalyzerResultsWithFile(entry.file_path, &temp_file_, + entry.file_size, entry.is_encrypted, + /*is_directory=*/true, results_); + + results_->directory_count++; + return true; +} + +bool SevenZipAnalyzer::EntryDone(seven_zip::Result result, + const seven_zip::EntryInfo& entry) { + base::UmaHistogramEnumeration("SBClientDownload.SevenZipEntryResult", result); + + results_->file_count++; + + // Since unpacking an encrypted entry is expected to fail, allow all results + // here for encrypted entries. + if (result == seven_zip::Result::kSuccess || entry.is_encrypted) { + if (base::FeatureList::IsEnabled(kNestedArchives) && !entry.is_encrypted && + AnalyzeNestedArchive(GetFileType(entry.file_path), entry.file_path)) { + awaiting_nested_ = true; + return false; + } else { + // TODO(crbug/1373509): We have the entire file in memory, so it's silly + // to do all this work to flush it and read it back. Can we simplify this + // process? This also reduces the risk that the file is not flushed fully. + mapped_file_.reset(); + UpdateArchiveAnalyzerResultsWithFile( + root_seven_zip_path_.Append(entry.file_path), &temp_file_, + entry.file_size, entry.is_encrypted, + /*is_directory=*/false, results_); + } + } else { + results_->success = false; + } + + return true; +} + +bool SevenZipAnalyzer::AnalyzeNestedArchive( + safe_browsing::DownloadFileType_InspectionType file_type, + base::FilePath path) { + FinishedAnalysisCallback nested_analysis_finished_callback = base::BindOnce( + &SevenZipAnalyzer::NestedAnalysisFinished, weak_factory_.GetWeakPtr(), + root_seven_zip_path_.Append(path)); + if (file_type == DownloadFileType::ZIP) { + nested_zip_analyzer_ = std::make_unique<safe_browsing::ZipAnalyzer>(); + nested_zip_analyzer_->Init(temp_file_.Duplicate(), + root_seven_zip_path_.Append(path), + std::move(nested_analysis_finished_callback), + get_temp_file_callback_, results_); + return true; + } else if (file_type == DownloadFileType::RAR) { + nested_rar_analyzer_ = std::make_unique<safe_browsing::RarAnalyzer>(); + nested_rar_analyzer_->Init(temp_file_.Duplicate(), + root_seven_zip_path_.Append(path), + std::move(nested_analysis_finished_callback), + get_temp_file_callback_, results_); + return true; + } else if (file_type == DownloadFileType::SEVEN_ZIP) { + nested_seven_zip_analyzer_ = + std::make_unique<safe_browsing::SevenZipAnalyzer>(); + nested_seven_zip_analyzer_->Init( + temp_file_.Duplicate(), root_seven_zip_path_.Append(path), + std::move(nested_analysis_finished_callback), get_temp_file_callback_, + results_); + return true; + } + + return false; +} + +void SevenZipAnalyzer::NestedAnalysisFinished(base::FilePath path) { + awaiting_nested_ = false; + + // `results_->success` will contain the latest analyzer's success + // status and can be used to determine if the nester archive unpacked + // successfully. + if (!results_->success) { + results_->has_archive = true; + results_->archived_archive_filenames.push_back(path.BaseName()); + ClientDownloadRequest::ArchivedBinary* archived_archive = + results_->archived_binary.Add(); + archived_archive->set_download_type(ClientDownloadRequest::ARCHIVE); + archived_archive->set_is_encrypted(false); + archived_archive->set_is_archive(true); + SetNameForContainedFile(path, archived_archive); + SetLengthAndDigestForContainedFile(&temp_file_, temp_file_.GetLength(), + archived_archive); + } + + AnalyzeSevenZipFile(); } } // namespace safe_browsing
diff --git a/chrome/common/safe_browsing/seven_zip_analyzer.h b/chrome/common/safe_browsing/seven_zip_analyzer.h index 1707d81..1f2d886 100644 --- a/chrome/common/safe_browsing/seven_zip_analyzer.h +++ b/chrome/common/safe_browsing/seven_zip_analyzer.h
@@ -9,8 +9,13 @@ #define CHROME_COMMON_SAFE_BROWSING_SEVEN_ZIP_ANALYZER_H_ #include "base/files/file.h" +#include "base/files/memory_mapped_file.h" #include "base/functional/callback.h" +#include "chrome/common/safe_browsing/rar_analyzer.h" +#include "chrome/common/safe_browsing/zip_analyzer.h" #include "components/safe_browsing/content/common/proto/download_file_types.pb.h" +#include "third_party/abseil-cpp/absl/types/optional.h" +#include "third_party/lzma_sdk/google/seven_zip_reader.h" namespace safe_browsing { @@ -19,11 +24,11 @@ using GetTempFileCallback = base::RepeatingCallback<void(base::OnceCallback<void(base::File)>)>; -class SevenZipAnalyzer { +class SevenZipAnalyzer : public seven_zip::Delegate { public: SevenZipAnalyzer(); - ~SevenZipAnalyzer(); + ~SevenZipAnalyzer() override; SevenZipAnalyzer(const SevenZipAnalyzer&) = delete; SevenZipAnalyzer& operator=(const SevenZipAnalyzer&) = delete; @@ -36,6 +41,15 @@ GetTempFileCallback get_temp_file_callback, ArchiveAnalyzerResults* results); + // seven_zip::Delegate + void OnOpenError(seven_zip::Result result) override; + base::File OnTempFileRequest() override; + bool OnEntry(const seven_zip::EntryInfo& entry, + base::span<uint8_t>& output) override; + bool OnDirectory(const seven_zip::EntryInfo& entry) override; + bool EntryDone(seven_zip::Result result, + const seven_zip::EntryInfo& entry) override; + private: // Ensures that the `seven_zip_path` and both `temp_file`(s) are both // valid and should be analyzed. @@ -43,16 +57,38 @@ void AnalyzeSevenZipFile(); + // Checks the `file_type` and creates a new analyzer if the file is a + // nested archive. Returns true when a new analyzer is created, and + // false when one is not. + bool AnalyzeNestedArchive( + safe_browsing::DownloadFileType_InspectionType file_type, + base::FilePath path); + + // Called from a nested analyzer using + // `finished_analysis_callback_`. If unsuccessful, records unpacked + // archive in results + void NestedAnalysisFinished(base::FilePath path); + base::FilePath root_seven_zip_path_; base::File seven_zip_file_; base::File temp_file_; base::File temp_file2_; raw_ptr<ArchiveAnalyzerResults> results_; + std::unique_ptr<seven_zip::SevenZipReader> reader_; + absl::optional<base::MemoryMappedFile> mapped_file_; FinishedAnalysisCallback finished_analysis_callback_; GetTempFileCallback get_temp_file_callback_; + // The below analyzers are used to unpack nested archives using + // DFS to unpacked nested archives. + // TODO(crbug.com/1426164) Create a common class to hold all analyzers. + std::unique_ptr<safe_browsing::RarAnalyzer> nested_rar_analyzer_; + std::unique_ptr<safe_browsing::ZipAnalyzer> nested_zip_analyzer_; + std::unique_ptr<safe_browsing::SevenZipAnalyzer> nested_seven_zip_analyzer_; + bool awaiting_nested_ = false; + base::WeakPtrFactory<SevenZipAnalyzer> weak_factory_{this}; };
diff --git a/chrome/services/mac_notifications/mac_notification_service_ns.mm b/chrome/services/mac_notifications/mac_notification_service_ns.mm index ce0cc4d..99a3278 100644 --- a/chrome/services/mac_notifications/mac_notification_service_ns.mm +++ b/chrome/services/mac_notifications/mac_notification_service_ns.mm
@@ -199,8 +199,6 @@ base::SysUTF8ToNSString(DeriveMacNotificationId(notification->meta->id)); [toast setIdentifier:notification_id]; - LogMacNotificationDelivered(IsAppBundleAlertStyle(), /*success=*/true); - [notification_center_ deliverNotification:toast.get()]; }
diff --git a/chrome/services/mac_notifications/mac_notification_service_ns_unittest.mm b/chrome/services/mac_notifications/mac_notification_service_ns_unittest.mm index 32d046f..14bfeb1 100644 --- a/chrome/services/mac_notifications/mac_notification_service_ns_unittest.mm +++ b/chrome/services/mac_notifications/mac_notification_service_ns_unittest.mm
@@ -304,34 +304,6 @@ [mock_notification_center_ verify]; } -TEST_F(MacNotificationServiceNSTest, LogsMetricsForAlerts) { - base::HistogramTester histogram_tester; - id mainBundleMock = - [OCMockObject partialMockForObject:base::mac::MainBundle()]; - - // Mock the alert style to "alert" and verify we log the correct metrics. - [[[mainBundleMock stub] - andReturn:@{@"NSUserNotificationAlertStyle" : @"alert"}] infoDictionary]; - DisplayNotificationSync(); - histogram_tester.ExpectUniqueSample("Notifications.macOS.Delivered.Alert", - /*sample=*/true, /*expected_count=*/1); - [mainBundleMock stopMocking]; -} - -TEST_F(MacNotificationServiceNSTest, LogsMetricsForBanners) { - base::HistogramTester histogram_tester; - id mainBundleMock = - [OCMockObject partialMockForObject:base::mac::MainBundle()]; - - // Mock the alert style to "banner" and verify we log the correct metrics. - [[[mainBundleMock stub] - andReturn:@{@"NSUserNotificationAlertStyle" : @"banner"}] infoDictionary]; - DisplayNotificationSync(); - histogram_tester.ExpectUniqueSample("Notifications.macOS.Delivered.Banner", - /*sample=*/true, /*expected_count=*/1); - [mainBundleMock stopMocking]; -} - struct NotificationActionParams { NSUserNotificationActivationType activation_type; NSNumber* has_settings_button;
diff --git a/chrome/services/mac_notifications/mac_notification_service_un.mm b/chrome/services/mac_notifications/mac_notification_service_un.mm index d303e47..d2a4905f 100644 --- a/chrome/services/mac_notifications/mac_notification_service_un.mm +++ b/chrome/services/mac_notifications/mac_notification_service_un.mm
@@ -189,7 +189,6 @@ } auto completion_handler = ^(NSError* _Nullable error) { - LogMacNotificationDelivered(IsAppBundleAlertStyle(), !error); }; // If the renotify is not set try to replace the notification silently.
diff --git a/chrome/services/mac_notifications/mac_notification_service_un_unittest.mm b/chrome/services/mac_notifications/mac_notification_service_un_unittest.mm index 89fbb2d..8592d001 100644 --- a/chrome/services/mac_notifications/mac_notification_service_un_unittest.mm +++ b/chrome/services/mac_notifications/mac_notification_service_un_unittest.mm
@@ -493,16 +493,6 @@ andReturn:@{@"NSUserNotificationAlertStyle" : @"alert"}] infoDictionary]; - DisplayNotificationSync("notificationId", "profileId", /*incognito=*/true, - /*success=*/true); - histogram_tester.ExpectUniqueSample("Notifications.macOS.Delivered.Alert", - /*sample=*/true, /*expected_count=*/1); - - DisplayNotificationSync("notificationId", "profileId", /*incognito=*/true, - /*success=*/false); - histogram_tester.ExpectBucketCount("Notifications.macOS.Delivered.Alert", - /*sample=*/false, /*expected_count=*/1); - for (auto result : {UNNotificationRequestPermissionResult::kRequestFailed, UNNotificationRequestPermissionResult::kPermissionDenied, @@ -528,16 +518,6 @@ andReturn:@{@"NSUserNotificationAlertStyle" : @"banner"}] infoDictionary]; - DisplayNotificationSync("notificationId", "profileId", /*incognito=*/true, - /*success=*/true); - histogram_tester.ExpectUniqueSample("Notifications.macOS.Delivered.Banner", - /*sample=*/true, /*expected_count=*/1); - - DisplayNotificationSync("notificationId", "profileId", /*incognito=*/true, - /*success=*/false); - histogram_tester.ExpectBucketCount("Notifications.macOS.Delivered.Banner", - /*sample=*/false, /*expected_count=*/1); - for (auto result : {UNNotificationRequestPermissionResult::kRequestFailed, UNNotificationRequestPermissionResult::kPermissionDenied,
diff --git a/chrome/services/mac_notifications/public/cpp/mac_notification_metrics.h b/chrome/services/mac_notifications/public/cpp/mac_notification_metrics.h index f99bf1d..ea95b4c2 100644 --- a/chrome/services/mac_notifications/public/cpp/mac_notification_metrics.h +++ b/chrome/services/mac_notifications/public/cpp/mac_notification_metrics.h
@@ -16,11 +16,6 @@ // with variants of MacOSNotificationStyle in .../notifications/histograms.xml. std::string MacNotificationStyleSuffix(bool is_alert); -// Called when we delivered a new notification to the macOS notification center. -// |is_alert| determines if the notification was an alert or a banner. -// |success| determines if there was an error while delivering the notification. -void LogMacNotificationDelivered(bool is_alert, bool success); - // Called when a user performed an action on a notification on macOS. // |is_alert| determines if the notification was an alert or a banner. // |is_valid| determines if the action data was valid and we passed it along.
diff --git a/chrome/services/mac_notifications/public/cpp/mac_notification_metrics.mm b/chrome/services/mac_notifications/public/cpp/mac_notification_metrics.mm index b47b5b6..3f9fc5e 100644 --- a/chrome/services/mac_notifications/public/cpp/mac_notification_metrics.mm +++ b/chrome/services/mac_notifications/public/cpp/mac_notification_metrics.mm
@@ -22,13 +22,6 @@ return is_alert ? "Alert" : "Banner"; } -void LogMacNotificationDelivered(bool is_alert, bool success) { - base::UmaHistogramBoolean( - base::StrCat({"Notifications.macOS.Delivered.", - MacNotificationStyleSuffix(is_alert)}), - success); -} - void LogMacNotificationActionReceived(bool is_alert, bool is_valid) { base::UmaHistogramBoolean( base::StrCat({"Notifications.macOS.ActionReceived.",
diff --git a/chrome/services/printing/print_backend_service_impl.cc b/chrome/services/printing/print_backend_service_impl.cc index fcb3dc2..85e0ab1 100644 --- a/chrome/services/printing/print_backend_service_impl.cc +++ b/chrome/services/printing/print_backend_service_impl.cc
@@ -932,7 +932,8 @@ &value_result); if (value_result->is_result_code()) { DLOG(ERROR) << "Failure parsing XML of XPS capabilities of printer " - << printer_name << ", error: " << xml.error(); + << printer_name + << ", error: " << value_result->get_result_code(); return base::unexpected(value_result->get_result_code()); } @@ -940,7 +941,7 @@ ParseValueForXpsPrinterCapabilities(value_result->get_capabilities()); if (!xps_capabilities.has_value()) { DLOG(ERROR) << "Failure parsing value of XPS capabilities of printer " - << printer_name << ", error: " << xml.error(); + << printer_name << ", error: " << xps_capabilities.error(); return base::unexpected(xps_capabilities.error()); } return std::move(xps_capabilities).value();
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 2094878..4a1ce75 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -2379,6 +2379,7 @@ "../browser/ui/webui/settings/settings_secure_dns_handler_browsertest.cc", "../browser/ui/webui/settings/settings_ui_browsertest.cc", "../browser/ui/webui/side_panel/customize_chrome/customize_chrome_browsertest.cc", + "../browser/ui/webui/side_panel/read_anything/read_anything_app_browsertest.cc", "../browser/ui/webui/support_tool/support_tool_ui_browsertest.cc", "../browser/ui/webui/tab_search/tab_search_ui_browsertest.cc", "../browser/ui/webui/webui_load_timer_browsertest.cc",
diff --git a/chrome/test/chromedriver/commands_unittest.cc b/chrome/test/chromedriver/commands_unittest.cc index a6c1f5d..89c376fc 100644 --- a/chrome/test/chromedriver/commands_unittest.cc +++ b/chrome/test/chromedriver/commands_unittest.cc
@@ -95,8 +95,8 @@ ASSERT_TRUE(session1.is_dict()); ASSERT_TRUE(session2.is_dict()); - ASSERT_EQ(static_cast<size_t>(2), session1.DictSize()); - ASSERT_EQ(static_cast<size_t>(2), session2.DictSize()); + ASSERT_EQ(static_cast<size_t>(2), session1.GetDict().size()); + ASSERT_EQ(static_cast<size_t>(2), session2.GetDict().size()); const std::string* session1_id = session1.GetDict().FindString("id"); const std::string* session2_id = session2.GetDict().FindString("id");
diff --git a/chrome/test/data/webui/app_home/app_list_test.ts b/chrome/test/data/webui/app_home/app_list_test.ts index 1446567..4db37b8 100644 --- a/chrome/test/data/webui/app_home/app_list_test.ts +++ b/chrome/test/data/webui/app_home/app_list_test.ts
@@ -285,7 +285,6 @@ openInWindow.click(); await callbackRouterRemote.$.flushForTesting(); flush(); - appItem.dispatchEvent(new CustomEvent('contextmenu')); assertTrue(openInWindow.checked); assertEquals( 1, @@ -296,7 +295,6 @@ openInWindow.click(); await callbackRouterRemote.$.flushForTesting(); flush(); - appItem.dispatchEvent(new CustomEvent('contextmenu')); assertFalse(openInWindow.checked); assertEquals( 1, @@ -325,7 +323,6 @@ launchOnStartup.click(); await callbackRouterRemote.$.flushForTesting(); flush(); - appItem.dispatchEvent(new CustomEvent('contextmenu')); assertTrue(launchOnStartup.checked); assertEquals( 1, @@ -336,7 +333,6 @@ launchOnStartup.click(); await callbackRouterRemote.$.flushForTesting(); flush(); - appItem.dispatchEvent(new CustomEvent('contextmenu')); assertFalse(launchOnStartup.checked); assertEquals( 1, @@ -367,7 +363,6 @@ launchOnStartup.click(); await callbackRouterRemote.$.flushForTesting(); flush(); - appItem.dispatchEvent(new CustomEvent('contextmenu')); assertFalse(launchOnStartup.checked); assertEquals( 0, @@ -753,4 +748,39 @@ button.href, 'https://support.google.com/chrome?p=install_web_apps'); assertEquals(button.innerText, 'Learn how to install web apps'); }); + + test('context menu not closed on checkbox click', async () => { + // Test for crbug.com/1435592: Clicking the checkbox options on + // the context menu does not close it. + const appItem = appListElement.shadowRoot!.querySelector('app-item'); + assertTrue(!!appItem); + + appItem.dispatchEvent(new CustomEvent('contextmenu')); + assertTrue(apps.appList.length >= 1); + + const contextMenu = appItem.shadowRoot!.querySelector('cr-action-menu'); + assertTrue(!!contextMenu); + const launchOnStartup = + contextMenu.querySelector<CrCheckboxElement>('#launchOnStartup'); + assertTrue(!!launchOnStartup); + assertFalse(launchOnStartup.checked); + const openInWindow = + contextMenu.querySelector<CrCheckboxElement>('#openInWindow'); + assertTrue(!!openInWindow); + assertFalse(openInWindow.checked); + + // Launch on Startup check. + launchOnStartup.click(); + await callbackRouterRemote.$.flushForTesting(); + flush(); + assertTrue(launchOnStartup.checked); + assertFalse(contextMenu.hidden); + + // Open In Window check. + openInWindow.click(); + await callbackRouterRemote.$.flushForTesting(); + flush(); + assertTrue(openInWindow.checked); + assertFalse(contextMenu.hidden); + }); });
diff --git a/chrome/test/data/webui/chromeos/diagnostics/routine_section_test.js b/chrome/test/data/webui/chromeos/diagnostics/routine_section_test.js index 0b6f4c7..197eaba 100644 --- a/chrome/test/data/webui/chromeos/diagnostics/routine_section_test.js +++ b/chrome/test/data/webui/chromeos/diagnostics/routine_section_test.js
@@ -528,6 +528,45 @@ }); }); + test('PowerTestResultListStatusSuccess', () => { + /** @type {!Array<!RoutineType>} */ + const routines = [ + RoutineType.kBatteryCharge, + ]; + + routineController.setFakeStandardRoutineResult( + RoutineType.kBatteryCharge, StandardRoutineResult.kTestPassed); + + return initializeRoutineSection(routines) + .then(() => { + // Hidden by default. + assertFalse(isVisible(getStatusBadge())); + assertFalse(isVisible(getStatusTextElement())); + return clickRunTestsButton(); + }) + .then(() => { + // Text is visible describing which test is being run. + assertFalse(getStatusTextElement().hidden); + dx_utils.assertElementContainsText( + getStatusTextElement(), + loadTimeData.getString('batteryChargeRoutineText').toLowerCase()); + + // Resolve the running test. + return routineController.resolveRoutineForTesting(); + }) + .then(() => { + return flushTasks(); + }) + .then(() => { + // Text is visible saying test progress. + assertFalse(getStatusTextElement().hidden); + dx_utils.assertElementContainsText( + getStatusTextElement(), 'Charged 0.00% in 0 seconds.'); + dx_utils.assertElementContainsText( + getStatusTextElement(), 'Learn more'); + }); + }); + test('ResultListStatusFail', () => { /** @type {!Array<!RoutineType>} */ const routines = [
diff --git a/chrome/test/data/webui/chromeos/scanning/loading_page_test.js b/chrome/test/data/webui/chromeos/scanning/loading_page_test.js index 080ece7b..e2bfc17 100644 --- a/chrome/test/data/webui/chromeos/scanning/loading_page_test.js +++ b/chrome/test/data/webui/chromeos/scanning/loading_page_test.js
@@ -26,6 +26,12 @@ let fakePrefersColorSchemeDarkMediaQuery = null; /** + * Type alias for SVGUseElement. + * @typedef {{href: {baseVal: string}}} + */ + let SVGUseElement; + + /** * @param {boolean} enabled * @return {!Promise} */ @@ -36,6 +42,17 @@ return flushTasks(); } + /** + * @param {boolean} enabled + * @returns {!Promise} + */ + function setJellyEnabled(enabled) { + assertTrue(!!loadingPage); + loadingPage.setIsJellyEnabledForTesting(enabled); + + return flushTasks(); + } + setup(() => { loadingPage = /** @type {!LoadingPageElement} */ ( @@ -113,15 +130,17 @@ // Setup UI to display no scanners div. loadingPage.appState = AppState.NO_SCANNERS; await setFakePrefersColorSchemeDark(false); - assertEquals(getNoScannersSvg().src, lightModeSvg); + assertEquals(lightModeSvg, getNoScannersSvg().src); // Mock media query state for dark mode. await setFakePrefersColorSchemeDark(true); - assertEquals(getNoScannersSvg().src, darkModeSvg); + assertEquals(darkModeSvg, getNoScannersSvg().src); }); + // TODO(b/276493795): After the Jelly experiment is launched, remove test. // Verify correct 'loading scanners' svg displayed when page is in dark mode. test('scanLoadingSvgSetByColorScheme', async () => { + await setJellyEnabled(false); const lightModeSvg = `${scanningSrcBase}svg/scanners_loading.svg`; const darkModeSvg = `${scanningSrcBase}svg/scanners_loading_dark.svg`; const getLoadingSvg = () => @@ -130,10 +149,30 @@ // Setup UI to display no scanners div. loadingPage.appState = AppState.NO_SCANNERS; await setFakePrefersColorSchemeDark(false); - assertEquals(getLoadingSvg().src, lightModeSvg); + assertEquals(lightModeSvg, getLoadingSvg().src); // Mock media query state for dark mode. await setFakePrefersColorSchemeDark(true); - assertEquals(getLoadingSvg().src, darkModeSvg); + assertEquals(darkModeSvg, getLoadingSvg().src); + }); + + // Verify "loading scanners" dynamic SVG use when dynamic colors enabled. + test('jellyColors_LoadingScannersSvg', async () => { + await setJellyEnabled(true); + const dynamicSvg = `svg/illo_loading_scanner.svg#illo_loading_scanner`; + + const getLoadingScannersSvgValue = () => + (/** @type {!SVGUseElement} */ ( + loadingPage.shadowRoot.querySelector('#loadingDiv > svg > use')) + .href.baseVal); + + // Setup UI to display no scanners div. + loadingPage.appState = AppState.NO_SCANNERS; + await setFakePrefersColorSchemeDark(false); + assertEquals(dynamicSvg, getLoadingScannersSvgValue()); + + // Mock media query state for dark mode. + await setFakePrefersColorSchemeDark(true); + assertEquals(dynamicSvg, getLoadingScannersSvgValue()); }); });
diff --git a/chrome/test/data/webui/chromeos/scanning/scan_preview_test.js b/chrome/test/data/webui/chromeos/scanning/scan_preview_test.js index 602107b..9b2ac81 100644 --- a/chrome/test/data/webui/chromeos/scanning/scan_preview_test.js +++ b/chrome/test/data/webui/chromeos/scanning/scan_preview_test.js
@@ -453,10 +453,10 @@ // Mock media query state for light mode. await setFakePrefersColorSchemeDark(false); - assertEquals(getReadyToScanSvg().src, lightModeSvg); + assertEquals(lightModeSvg, getReadyToScanSvg().src); // Mock media query state for dark mode. await setFakePrefersColorSchemeDark(true); - assertEquals(getReadyToScanSvg().src, darkModeSvg); + assertEquals(darkModeSvg, getReadyToScanSvg().src); }); });
diff --git a/chrome/test/data/webui/chromeos/shortcut_customization/input_key_test.ts b/chrome/test/data/webui/chromeos/shortcut_customization/input_key_test.ts index 19ab1ff..9e8b334 100644 --- a/chrome/test/data/webui/chromeos/shortcut_customization/input_key_test.ts +++ b/chrome/test/data/webui/chromeos/shortcut_customization/input_key_test.ts
@@ -85,7 +85,7 @@ const iconWrapperElement = inputKeyElement.shadowRoot!.querySelector( '#key > div') as HTMLDivElement; assertTrue(isVisible(iconWrapperElement)); - assertEquals('screenshot', iconWrapperElement.ariaLabel); + assertEquals('take screenshot', iconWrapperElement.ariaLabel); assertEquals('img', iconWrapperElement.getAttribute('role')); });
diff --git a/chrome/test/data/webui/chromeos/shortcut_customization/search_result_row_test.ts b/chrome/test/data/webui/chromeos/shortcut_customization/search_result_row_test.ts index 5396991..8893277 100644 --- a/chrome/test/data/webui/chromeos/shortcut_customization/search_result_row_test.ts +++ b/chrome/test/data/webui/chromeos/shortcut_customization/search_result_row_test.ts
@@ -109,7 +109,7 @@ 'ctrl', keys1[0]!.shadowRoot!.querySelector('#key')!.textContent!.trim()); assertEquals( - 'overview', + 'show windows', keys1[1]!.shadowRoot!.querySelector('div:has(> iron-icon)')!.ariaLabel); const keys2: NodeListOf<InputKeyElement> = @@ -117,7 +117,7 @@ // Screenshot assertEquals(1, keys2.length); assertEquals( - 'screenshot', + 'take screenshot', keys2[0]!.shadowRoot!.querySelector('div:has(> iron-icon)')!.ariaLabel); // Select the row and verify that the keys are highlighted.
diff --git a/chrome/test/data/webui/nearby_share/fake_mojo_interfaces.js b/chrome/test/data/webui/nearby_share/fake_mojo_interfaces.js index 81edc90..a8f97de 100644 --- a/chrome/test/data/webui/nearby_share/fake_mojo_interfaces.js +++ b/chrome/test/data/webui/nearby_share/fake_mojo_interfaces.js
@@ -4,7 +4,7 @@ /** @fileoverview Contains fake implementations of mojo interfaces. */ -import {DiscoveryObserverRemote, SelectShareTargetResult, ShareTargetListenerRemote, StartDiscoveryResult, TransferUpdateListenerPendingReceiver, TransferUpdateListenerRemote} from 'chrome://nearby/shared/mojo/nearby_share.mojom-webui.js'; +import {DiscoveryObserverRemote, SelectShareTargetResult, ShareTargetListenerRemote, StartDiscoveryResult, TransferUpdateListenerPendingReceiver, TransferUpdateListenerRemote} from 'chrome://nearby/shared/nearby_share.mojom-webui.js'; import {UnguessableToken} from 'chrome://resources/mojo/mojo/public/mojom/base/unguessable_token.mojom-webui.js'; import {TestBrowserProxy} from '../chromeos/test_browser_proxy.js';
diff --git a/chrome/test/data/webui/nearby_share/nearby_confirmation_page_test.js b/chrome/test/data/webui/nearby_share/nearby_confirmation_page_test.js index de56655..f4f2d92b 100644 --- a/chrome/test/data/webui/nearby_share/nearby_confirmation_page_test.js +++ b/chrome/test/data/webui/nearby_share/nearby_confirmation_page_test.js
@@ -5,8 +5,8 @@ import 'chrome://nearby/nearby_confirmation_page.js'; import 'chrome://webui-test/mojo_webui_test_support.js'; -import {TransferStatus} from 'chrome://nearby/shared/mojo/nearby_share.mojom-webui.js'; -import {ShareType} from 'chrome://nearby/shared/mojo/nearby_share_share_type.mojom-webui.js'; +import {TransferStatus} from 'chrome://nearby/shared/nearby_share.mojom-webui.js'; +import {ShareType} from 'chrome://nearby/shared/nearby_share_share_type.mojom-webui.js'; import {ShareTargetType} from 'chrome://resources/mojo/chromeos/ash/services/nearby/public/mojom/nearby_share_target_types.mojom-webui.js'; import {assertEquals, assertFalse, assertTrue} from '../chromeos/chai_assert.js';
diff --git a/chrome/test/data/webui/nearby_share/nearby_discovery_page_test.js b/chrome/test/data/webui/nearby_share/nearby_discovery_page_test.js index c2f19a06..31a9de48 100644 --- a/chrome/test/data/webui/nearby_share/nearby_discovery_page_test.js +++ b/chrome/test/data/webui/nearby_share/nearby_discovery_page_test.js
@@ -6,8 +6,8 @@ import 'chrome://webui-test/mojo_webui_test_support.js'; import {setDiscoveryManagerForTesting} from 'chrome://nearby/discovery_manager.js'; -import {SelectShareTargetResult, ShareTargetListenerRemote, StartDiscoveryResult} from 'chrome://nearby/shared/mojo/nearby_share.mojom-webui.js'; -import {ShareType} from 'chrome://nearby/shared/mojo/nearby_share_share_type.mojom-webui.js'; +import {SelectShareTargetResult, ShareTargetListenerRemote, StartDiscoveryResult} from 'chrome://nearby/shared/nearby_share.mojom-webui.js'; +import {ShareType} from 'chrome://nearby/shared/nearby_share_share_type.mojom-webui.js'; import {getDeepActiveElement} from 'chrome://resources/ash/common/util.js'; import {ShareTargetType} from 'chrome://resources/mojo/chromeos/ash/services/nearby/public/mojom/nearby_share_target_types.mojom-webui.js'; import {UnguessableToken} from 'chrome://resources/mojo/mojo/public/mojom/base/unguessable_token.mojom-webui.js';
diff --git a/chrome/test/data/webui/nearby_share/shared/nearby_preview_test.js b/chrome/test/data/webui/nearby_share/shared/nearby_preview_test.js index 7db4a40..69a7845 100644 --- a/chrome/test/data/webui/nearby_share/shared/nearby_preview_test.js +++ b/chrome/test/data/webui/nearby_share/shared/nearby_preview_test.js
@@ -5,7 +5,7 @@ import 'chrome://nearby/shared/nearby_preview.js'; import 'chrome://webui-test/mojo_webui_test_support.js'; -import {ShareType} from 'chrome://nearby/shared/mojo/nearby_share_share_type.mojom-webui.js'; +import {ShareType} from 'chrome://nearby/shared/nearby_share_share_type.mojom-webui.js'; import {assertEquals} from '../../chromeos/chai_assert.js';
diff --git a/chrome/test/data/webui/new_tab_page/modules/history_clusters/module_test.ts b/chrome/test/data/webui/new_tab_page/modules/history_clusters/module_test.ts index aef8e11..d591a627 100644 --- a/chrome/test/data/webui/new_tab_page/modules/history_clusters/module_test.ts +++ b/chrome/test/data/webui/new_tab_page/modules/history_clusters/module_test.ts
@@ -128,80 +128,6 @@ assertEquals(null, moduleElement); }); - test('Layout 1 is used', async () => { - // Arrange. - const moduleElement = await initializeModule([createSampleCluster()]); - - // Assert. - assertTrue(!!moduleElement); - assertLayoutSet(moduleElement, HistoryClusterLayoutType.LAYOUT_1); - // Check that metrics are set. - assertEquals(1, metrics.count(DISPLAY_LAYOUT_METRIC_NAME)); - assertEquals( - 1, - metrics.count( - DISPLAY_LAYOUT_METRIC_NAME, HistoryClusterLayoutType.LAYOUT_1)); - // Check that the visits are processed and set properly. - const visits = moduleElement.cluster.visits; - assertEquals(visits.length, LAYOUT_1_MIN_VISITS); - for (let i = 0; i < visits.length; i++) { - assertTrue(!!visits[i]); - if (i < LAYOUT_1_MIN_IMAGE_VISITS) { - assertTrue(visits[i]!.hasUrlKeyedImage); - } - } - }); - - test('Layout 2 is used', async () => { - // Arrange. - const moduleElement = await initializeModule( - [createSampleCluster(HistoryClusterLayoutType.LAYOUT_2)]); - - // Assert. - assertTrue(!!moduleElement); - assertLayoutSet(moduleElement, HistoryClusterLayoutType.LAYOUT_2); - // Check that metrics are set. - assertEquals(1, metrics.count(DISPLAY_LAYOUT_METRIC_NAME)); - assertEquals( - 1, - metrics.count( - DISPLAY_LAYOUT_METRIC_NAME, HistoryClusterLayoutType.LAYOUT_2)); - // Check that the visits are processed and set properly. - const visits = moduleElement.cluster.visits; - assertEquals(visits.length, LAYOUT_2_MIN_VISITS); - for (let i = 0; i < visits.length; i++) { - assertTrue(!!visits[i]); - if (i < LAYOUT_2_MIN_IMAGE_VISITS) { - assertTrue(visits[i]!.hasUrlKeyedImage); - } - } - }); - - test('Layout 3 is used', async () => { - // Arrange. - const moduleElement = await initializeModule( - [createSampleCluster(HistoryClusterLayoutType.LAYOUT_3)]); - - // Assert. - assertTrue(!!moduleElement); - assertLayoutSet(moduleElement, HistoryClusterLayoutType.LAYOUT_3); - // Check that metrics are set. - assertEquals(1, metrics.count(DISPLAY_LAYOUT_METRIC_NAME)); - assertEquals( - 1, - metrics.count( - DISPLAY_LAYOUT_METRIC_NAME, HistoryClusterLayoutType.LAYOUT_3)); - // Check that the visits are processed and set properly. - const visits = moduleElement.cluster.visits; - assertEquals(visits.length, LAYOUT_3_MIN_VISITS); - for (let i = 0; i < visits.length; i++) { - assertTrue(!!visits[i]); - if (i < LAYOUT_3_MIN_IMAGE_VISITS) { - assertTrue(visits[i]!.hasUrlKeyedImage); - } - } - }); - test('Header element populated with correct data', async () => { // Arrange. const sampleClusterLabel = '"Sample Journey"'; @@ -315,11 +241,18 @@ assertEquals(index, Number(visit.visitId)); }); }); + }); + + suite('layouts', () => { + function removeHrefAndClick(element: HTMLElement) { + element.removeAttribute('href'); + element.click(); + } [HistoryClusterLayoutType.LAYOUT_1, HistoryClusterLayoutType.LAYOUT_2, HistoryClusterLayoutType.LAYOUT_3] .forEach(layoutType => { - test('Module produces visit tile click metrics', async () => { + test(`Layout ${layoutType}: Visit tile click metrics`, async () => { // Arrange. const moduleElement = await initializeModule([createSampleCluster(layoutType)]); @@ -330,7 +263,7 @@ $$(moduleElement, 'ntp-history-clusters-tile') as HTMLElement; assertTrue(!!tileElement); - ($$(tileElement, '#content') as HTMLElement).click(); + removeHrefAndClick($$(tileElement, '#content') as HTMLElement); assertEquals( 1, metrics.count(`NewTabPage.HistoryClusters.Layout${ @@ -346,7 +279,7 @@ HistoryClusterElementType.VISIT)); }); - test('Module produces suggest tile click metrics', async () => { + test(`Layout ${layoutType}: Suggest tile click metrics`, async () => { // Arrange. const moduleElement = await initializeModule([createSampleCluster(layoutType)]); @@ -357,7 +290,8 @@ $$(moduleElement, 'ntp-history-clusters-suggest-tile'); assertTrue(!!suggestTileElement); - ($$(suggestTileElement, '.related-search') as HTMLElement).click(); + removeHrefAndClick( + $$(suggestTileElement, '.related-search') as HTMLElement); assertEquals( 1, metrics.count(`NewTabPage.HistoryClusters.Layout${ @@ -372,6 +306,36 @@ `NewTabPage.HistoryClusters.Layout${layoutType}.Click`, HistoryClusterElementType.SUGGEST)); }); + + const LAYOUT_MIN_VISITS = + [LAYOUT_1_MIN_VISITS, LAYOUT_2_MIN_VISITS, LAYOUT_3_MIN_VISITS]; + const LAYOUT_MIN_IMAGE_VISITS = [ + LAYOUT_1_MIN_IMAGE_VISITS, + LAYOUT_2_MIN_IMAGE_VISITS, + LAYOUT_3_MIN_IMAGE_VISITS, + ]; + test(`Layout ${layoutType} is used`, async () => { + // Arrange. + const moduleElement = + await initializeModule([createSampleCluster(layoutType)]); + + // Assert. + assertTrue(!!moduleElement); + assertLayoutSet(moduleElement, layoutType); + // Check that metrics are set. + assertEquals(1, metrics.count(DISPLAY_LAYOUT_METRIC_NAME)); + assertEquals( + 1, metrics.count(DISPLAY_LAYOUT_METRIC_NAME, layoutType)); + // Check that the visits are processed and set properly. + const visits = moduleElement.cluster.visits; + assertEquals(visits.length, LAYOUT_MIN_VISITS[layoutType - 1]); + for (let i = 0; i < visits.length; i++) { + assertTrue(!!visits[i]); + if (i < LAYOUT_MIN_IMAGE_VISITS[layoutType - 1]!) { + assertTrue(visits[i]!.hasUrlKeyedImage); + } + } + }); }); });
diff --git a/chrome/test/data/webui/new_tab_page/new_tab_page_browsertest.js b/chrome/test/data/webui/new_tab_page/new_tab_page_browsertest.js index 75c52e2..5153cef0 100644 --- a/chrome/test/data/webui/new_tab_page/new_tab_page_browsertest.js +++ b/chrome/test/data/webui/new_tab_page/new_tab_page_browsertest.js
@@ -409,17 +409,13 @@ } }; -// https://crbug.com/1428590: Flaky on LaCrOS. -GEN('#if BUILDFLAG(IS_CHROMEOS_LACROS)'); -GEN('#define MAYBE_Core DISABLED_Core'); -GEN('#else'); -GEN('#define MAYBE_Core Core'); -GEN('#endif'); - -TEST_F('NewTabPageModulesHistoryClustersModuleTest', 'MAYBE_Core', function() { +TEST_F('NewTabPageModulesHistoryClustersModuleTest', 'Core', function() { runMochaSuite('NewTabPageModulesHistoryClustersModuleTest core'); }); -GEN('#undef MAYBE_Core'); + +TEST_F('NewTabPageModulesHistoryClustersModuleTest', 'Layouts', function() { + runMochaSuite('NewTabPageModulesHistoryClustersModuleTest layouts'); +}); TEST_F( 'NewTabPageModulesHistoryClustersModuleTest',
diff --git a/chrome/test/data/webui/settings/chooser_exception_list_test.ts b/chrome/test/data/webui/settings/chooser_exception_list_test.ts index 3344ae8..63a9560 100644 --- a/chrome/test/data/webui/settings/chooser_exception_list_test.ts +++ b/chrome/test/data/webui/settings/chooser_exception_list_test.ts
@@ -560,4 +560,51 @@ assertEquals(text, tooltip.innerHTML.trim()); }); }); + + test('show confirmation dialog on reset settings', async function() { + setUpChooserType( + ContentSettingsTypes.USB_DEVICES, ChooserType.USB_DEVICES, + prefsUserProvider); + assertEquals(ContentSettingsTypes.USB_DEVICES, testElement.category); + assertEquals(ChooserType.USB_DEVICES, testElement.chooserType); + const chooserType = + await browserProxy.whenCalled('getChooserExceptionList'); + assertEquals(ChooserType.USB_DEVICES, chooserType); + assertEquals(1, testElement.chooserExceptions.length); + + assertChooserExceptionEquals( + prefsUserProvider + .chooserExceptions[ContentSettingsTypes.USB_DEVICES][0]!, + testElement.chooserExceptions[0]!); + + // Flush the container to ensure that the container is populated. + flush(); + + const chooserExceptionListEntry = + testElement.shadowRoot!.querySelector('chooser-exception-list-entry'); + assertTrue(!!chooserExceptionListEntry); + + const siteListEntry = + chooserExceptionListEntry!.shadowRoot!.querySelector('site-list-entry'); + assertTrue(!!siteListEntry); + + // Check both cancelling and accepting the dialog closes it. + assertFalse(testElement.$.confirmResetSettings.open); + ['cancel-button', 'action-button'].forEach(buttonType => { + testElement.shadowRoot! + .querySelector<HTMLElement>('#resetSettingsButton')!.click(); + assertTrue(testElement.$.confirmResetSettings.open); + const actionButtonList = + testElement.shadowRoot!.querySelectorAll<HTMLElement>( + `#confirmResetSettings .${buttonType}`); + assertEquals(1, actionButtonList.length); + actionButtonList[0]!.click(); + assertFalse(testElement.$.confirmResetSettings.open); + }); + + const args = await browserProxy.whenCalled('resetChooserExceptionForSite'); + assertEquals(testElement.chooserExceptions[0]!.chooserType, args[0]); + assertEquals(testElement.chooserExceptions[0]!.sites[0]!.origin, args[1]); + assertDeepEquals(testElement.chooserExceptions[0]!.object, args[2]); + }); });
diff --git a/chrome/test/data/webui/side_panel/read_anything/connected_callback_show_loading_screen.js b/chrome/test/data/webui/side_panel/read_anything/connected_callback_show_loading_screen.js new file mode 100644 index 0000000..c888b14 --- /dev/null +++ b/chrome/test/data/webui/side_panel/read_anything/connected_callback_show_loading_screen.js
@@ -0,0 +1,40 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// out/Debug/browser_tests \ +// --gtest_filter=ReadAnythingAppTest.ConnectedCallback_ShowLoadingScreen + +const readAnythingApp = document.querySelector('read-anything-app').shadowRoot; +const emptyState = readAnythingApp.querySelector('sp-empty-state'); +let result = true; + +function assertEquals(actual, expected) { + const isEqual = actual === expected; + if (!isEqual) { + console.error( + 'Expected: ' + JSON.stringify(expected) + ', ' + + 'Actual: ' + JSON.stringify(actual)); + } + result = result && isEqual; + return isEqual; +} + +function assertStringContains(string, value) { + const contains = string.includes(value); + if (!contains) { + console.error( + 'Expected to find: ' + JSON.stringify(value) + ', ' + + 'Actual: ' + JSON.stringify(string)); + } + result = result && contains; + return contains; +} + +assertEquals( + readAnythingApp.getElementById('empty-state-container').hidden, false); +assertEquals(emptyState.heading, 'Getting ready'); +assertEquals(emptyState.body, ''); +assertStringContains(emptyState.imagePath, 'throbber'); +assertStringContains(emptyState.darkImagePath, 'throbber'); +domAutomationController.send(result);
diff --git a/chrome/test/data/webui/side_panel/read_anything/on_selection_change_nothing_selected_on_loading_screen_selection.js b/chrome/test/data/webui/side_panel/read_anything/on_selection_change_nothing_selected_on_loading_screen_selection.js new file mode 100644 index 0000000..0dcc1a23 --- /dev/null +++ b/chrome/test/data/webui/side_panel/read_anything/on_selection_change_nothing_selected_on_loading_screen_selection.js
@@ -0,0 +1,27 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// out/Debug/browser_tests \ +// --gtest_filter=ReadAnythingAppTest.\ +// OnSelectionChange_NothingSelectedOnLoadingScreenSelection + +const readAnythingApp = document.querySelector('read-anything-app').shadowRoot; +const emptyState = readAnythingApp.getElementById('empty-state-container'); + +let selectionChanged = false; +chrome.readAnything.onSelectionChange = function( + _anchorNodeId, _anchorOffset, _focusNodeId, _focusOffset) { + selectionChanged = true; +}; + +const range = new Range(); +range.setStartBefore(emptyState); +range.setEndAfter(emptyState); +const selection = readAnythingApp.getSelection(); +selection.removeAllRanges(); +selection.addRange(range); + +setTimeout(() => { + domAutomationController.send(!selectionChanged); +}, 1000);
diff --git a/chrome/test/data/webui/side_panel/read_anything/read_anything_app_test.ts b/chrome/test/data/webui/side_panel/read_anything/read_anything_app_test.ts deleted file mode 100644 index 6a365f6..0000000 --- a/chrome/test/data/webui/side_panel/read_anything/read_anything_app_test.ts +++ /dev/null
@@ -1,1324 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'chrome://read-anything-side-panel.top-chrome/app.js'; -import 'chrome://webui-test/mojo_webui_test_support.js'; - -import {ReadAnythingElement} from 'chrome://read-anything-side-panel.top-chrome/app.js'; -import {assertEquals, assertFalse, assertStringContains} from 'chrome://webui-test/chai_assert.js'; -import {eventToPromise} from 'chrome://webui-test/test_util.js'; - -suite('ReadAnythingAppTest', () => { - let readAnythingApp: ReadAnythingElement; - - // Do not call the real `onConnected()`. As defined in - // ReadAnythingAppController, onConnected creates mojo pipes to connect to the - // rest of the Read Anything feature, which we are not testing here. - chrome.readAnything.onConnected = () => {}; - - setup(() => { - document.body.innerHTML = window.trustedTypes!.emptyHTML; - readAnythingApp = document.createElement('read-anything-app'); - document.body.appendChild(readAnythingApp); - chrome.readAnything.setThemeForTesting('default', 18.0, 0, 0, 1, 0); - }); - - const setOnSelectionChangeForTest = () => { - // This is called by readAnythingApp onselectionchange. It is usually - // implemented by ReadAnythingAppController which forwards these arguments - // to the browser process in the form of an AXEventNotificationDetail. - // Instead, we capture the arguments here and verify their values. Since - // onselectionchange is called asynchronously, the test must wait for this - // function to be called; therefore we fire a custom event - // on-selection-change-for-text here for the test to await. - chrome.readAnything.onSelectionChange = - (anchorNodeId: number, anchorOffset: number, focusNodeId: number, - focusOffset: number) => { - readAnythingApp.shadowRoot!.dispatchEvent( - new CustomEvent('on-selection-change-for-test', { - detail: { - anchorNodeId: anchorNodeId, - anchorOffset: anchorOffset, - focusNodeId: focusNodeId, - focusOffset: focusOffset, - }, - })); - }; - }; - - const assertFontName = (fontFamily: string) => { - const container = readAnythingApp.shadowRoot!.getElementById('container'); - assertEquals(fontFamily, getComputedStyle(container!).fontFamily); - }; - - const assertFontSize = (fontSize: string) => { - const container = readAnythingApp.shadowRoot!.getElementById('container'); - assertEquals(fontSize, getComputedStyle(container!).fontSize); - }; - - const assertLineSpacing = (lineSpacing: string) => { - const container = readAnythingApp.shadowRoot!.getElementById('container'); - assertEquals(lineSpacing, getComputedStyle(container!).lineHeight); - }; - - const assertContainerInnerHTML = (expected: string) => { - const actual = - readAnythingApp.shadowRoot!.getElementById('container')!.innerHTML; - assertEquals(actual, expected); - }; - - test('updateTheme fontName', () => { - chrome.readAnything.setThemeForTesting('Standard font', 18.0, 0, 0, 1, 0); - assertFontName('"Standard font"'); - - chrome.readAnything.setThemeForTesting('Sans-serif', 18.0, 0, 0, 1, 0); - assertFontName('sans-serif'); - - chrome.readAnything.setThemeForTesting('Serif', 18.0, 0, 0, 1, 0); - assertFontName('serif'); - - chrome.readAnything.setThemeForTesting('Arial', 18.0, 0, 0, 1, 0); - assertFontName('Arial'); - - chrome.readAnything.setThemeForTesting('Comic Sans MS', 18.0, 0, 0, 1, 0); - assertFontName('"Comic Sans MS"'); - - chrome.readAnything.setThemeForTesting('Times New Roman', 18.0, 0, 0, 1, 0); - assertFontName('"Times New Roman"'); - }); - - test('updateTheme fontSize', () => { - chrome.readAnything.setThemeForTesting('Standard font', 1.0, 0, 0, 1, 0); - assertFontSize('16px'); // 1em = 16px - }); - - test('updateTheme foregroundColor', () => { - chrome.readAnything.setThemeForTesting( - 'f', 1, /* SkColorSetRGB(0x33, 0x36, 0x39) = */ 4281546297, 0, 1, 0); - const container = readAnythingApp.shadowRoot!.getElementById('container'); - assertEquals( - /* #333639 = */ 'rgb(51, 54, 57)', getComputedStyle(container!).color); - }); - - test('updateTheme backgroundColor', () => { - chrome.readAnything.setThemeForTesting( - 'f', 1, 0, /* SkColorSetRGB(0xFD, 0xE2, 0x93) = */ 4294828691, 1, 0); - assertEquals( - /* #FDE293 = */ 'rgb(253, 226, 147)', - getComputedStyle(document.body).backgroundColor); - }); - - test('updateTheme lineSpacing', () => { - chrome.readAnything.setThemeForTesting('Standard font', 1.0, 0, 0, 2, 0); - assertLineSpacing('24px'); // 1.5 times the 1em (16px) font size - }); - - test('updateTheme letterSpacing', () => { - chrome.readAnything.setThemeForTesting('f', 1, 0, 0, 1, 3); - const container = readAnythingApp.shadowRoot!.getElementById('container'); - // very loose letter letter spacing = 0.1em, font size = 1em = 16px - assertEquals('1.6px', getComputedStyle(container!).letterSpacing); - }); - - // The loading screen shows when we connect. - test('connectedCallback showLoadingScreen', () => { - const emptyState = - readAnythingApp.shadowRoot!.querySelector('sp-empty-state')!; - - assertEquals( - readAnythingApp.shadowRoot!.getElementById( - 'empty-state-container')!.hidden, - false); - assertEquals(emptyState.heading, 'Getting ready'); - assertEquals(emptyState.body, ''); - assertStringContains(emptyState.imagePath, 'throbber'); - assertStringContains(emptyState.darkImagePath, 'throbber'); - }); - - test( - 'onselectionchange nothingSelectedOnLoadingScreenSelection', async () => { - const emptyState = - readAnythingApp.shadowRoot!.getElementById('empty-state-container'); - let selectionChanged = false; - chrome.readAnything.onSelectionChange = - (_anchorNodeId: number, _anchorOffset: number, _focusNodeId: number, - _focusOffset: number) => { - selectionChanged = true; - }; - - const range = new Range(); - range.setStartBefore(emptyState!); - range.setEndAfter(emptyState!); - const selection = readAnythingApp.shadowRoot!.getSelection(); - selection!.removeAllRanges(); - selection!.addRange(range); - - setTimeout(() => { - assertFalse(selectionChanged); - }, 1000); - }); - - test('updateContent hidesLoadingScreen', () => { - // root htmlTag='#document' id=1 - // ++paragraph htmlTag='p' id=2 - // ++++staticText name='This is a paragraph' id=3 - const axTree = { - rootId: 1, - nodes: [ - { - id: 1, - role: 'rootWebArea', - htmlTag: '#document', - childIds: [2], - }, - { - id: 2, - role: 'paragraph', - htmlTag: 'p', - childIds: [3], - }, - { - id: 3, - role: 'staticText', - name: 'This is a paragraph', - }, - ], - }; - chrome.readAnything.setContentForTesting(axTree, [2]); - - assertEquals( - readAnythingApp.shadowRoot!.getElementById( - 'empty-state-container')!.hidden, - true); - }); - - test('updateContent paragraph', () => { - // root htmlTag='#document' id=1 - // ++paragraph htmlTag='p' id=2 - // ++++staticText name='This is a paragraph' id=3 - // ++paragraph htmlTag='p' id=4 - // ++++staticText name='This is a second paragraph' id=5 - const axTree = { - rootId: 1, - nodes: [ - { - id: 1, - role: 'rootWebArea', - htmlTag: '#document', - childIds: [2, 4], - }, - { - id: 2, - role: 'paragraph', - htmlTag: 'p', - childIds: [3], - }, - { - id: 3, - role: 'staticText', - name: 'This is a paragraph', - }, - { - id: 4, - role: 'paragraph', - htmlTag: 'p', - childIds: [5], - }, - { - id: 5, - role: 'staticText', - name: 'This is a second paragraph', - }, - ], - }; - chrome.readAnything.setContentForTesting(axTree, [2, 4]); - const expected = '<div><p>This is a paragraph</p>' + - '<p>This is a second paragraph</p></div>'; - assertContainerInnerHTML(expected); - }); - - test('updateContent language childNodeDiffLang', () => { - // root htmlTag='#document' id=1 - // ++paragraph htmlTag='p' id=2 language='en' - // ++++staticText name='This is in English' id=3 - // ++paragraph htmlTag='p' id=4 language='es' - // ++++staticText name='Esto es en español' id=5 - // ++++link htmlTag='a' url='http://www.google.cn/' id=6 language='zh' - // ++++++staticText name='This is a link in Chinese' id=7 - const axTree = { - rootId: 1, - nodes: [ - { - id: 1, - role: 'rootWebArea', - htmlTag: '#document', - childIds: [2, 4], - }, - { - id: 2, - role: 'paragraph', - htmlTag: 'p', - language: 'en', - childIds: [3], - }, - { - id: 3, - role: 'staticText', - name: 'This is in English', - }, - { - id: 4, - role: 'paragraph', - htmlTag: 'p', - language: 'es', - childIds: [5, 6], - }, - { - id: 5, - role: 'staticText', - name: 'Esto es en español', - }, - { - id: 6, - role: 'link', - htmlTag: 'a', - language: 'zh', - url: 'http://www.google.cn/', - childIds: [7], - }, - { - id: 7, - role: 'staticText', - name: 'This is a link in Chinese', - }, - ], - }; - chrome.readAnything.setContentForTesting(axTree, [2, 4]); - const expected = '<div><p lang="en">This is in English</p>' + - '<p lang="es">Esto es en español' + - '<a href="http://www.google.cn/" lang="zh">' + - 'This is a link in Chinese</a></p></div>'; - assertContainerInnerHTML(expected); - }); - - test('updateContent language parentLangSet', () => { - // root htmlTag='#document' id=1 - // ++paragraph htmlTag='p' id=2 language='en' - // ++++staticText name='This is in English' id=3 - // ++++link htmlTag='a' url='http://www.google.com/' id=4 - // ++++++staticText name='This link has no language set' id=5 - const axTree = { - rootId: 1, - nodes: [ - { - id: 1, - role: 'rootWebArea', - htmlTag: '#document', - childIds: [2], - }, - { - id: 2, - role: 'paragraph', - htmlTag: 'p', - language: 'en', - childIds: [3, 4], - }, - { - id: 3, - role: 'staticText', - name: 'This is in English', - }, - { - id: 4, - role: 'link', - htmlTag: 'a', - url: 'http://www.google.com/', - childIds: [5], - }, - { - id: 5, - role: 'staticText', - name: 'This link has no language set', - }, - ], - }; - chrome.readAnything.setContentForTesting(axTree, [2]); - const expected = '<div><p lang="en">This is in English' + - '<a href="http://www.google.com/">This link has no language set</a>' + - '</p></div>'; - assertContainerInnerHTML(expected); - }); - - test('updateContent heading', () => { - // Fake chrome.readAnything methods for the following AXTree - // root htmlTag='#document' id=1 - // ++heading htmlTag='h1' id=2 - // ++++staticText name='This is an h1.' id=3 - // ++heading htmlTag='h2' id=4 - // ++++staticText name='This is an h2.' id=5 - // ++heading htmlTag='h3' id=6 - // ++++staticText name='This is an h3.' id=7 - // ++heading htmlTag='h4' id=8 - // ++++staticText name='This is an h4.' id=9 - // ++heading htmlTag='h5' id=10 - // ++++staticText name='This is an h5.' id=11 - // ++heading htmlTag='h6' id=12 - // ++++staticText name='This is an h6.' id=13 - const axTree = { - rootId: 1, - nodes: [ - { - id: 1, - role: 'rootWebArea', - htmlTag: '#document', - childIds: [2, 4, 6, 8, 10, 12], - }, - { - id: 2, - role: 'heading', - htmlTag: 'h1', - childIds: [3], - }, - { - id: 3, - role: 'staticText', - name: 'This is an h1.', - }, - { - id: 4, - role: 'heading', - htmlTag: 'h2', - childIds: [5], - }, - { - id: 5, - role: 'staticText', - name: 'This is an h2.', - }, - { - id: 6, - role: 'heading', - htmlTag: 'h3', - childIds: [7], - }, - { - id: 7, - role: 'staticText', - name: 'This is an h3.', - }, - { - id: 8, - role: 'heading', - htmlTag: 'h4', - childIds: [9], - }, - { - id: 9, - role: 'staticText', - name: 'This is an h4.', - }, - { - id: 10, - role: 'heading', - htmlTag: 'h5', - childIds: [11], - }, - { - id: 11, - role: 'staticText', - name: 'This is an h5.', - }, - { - id: 12, - role: 'heading', - htmlTag: 'h6', - childIds: [13], - }, - { - id: 13, - role: 'staticText', - name: 'This is an h6.', - }, - ], - }; - chrome.readAnything.setContentForTesting(axTree, [2, 4, 6, 8, 10, 12]); - const expected = '<div><h1>This is an h1.</h1><h2>This is an h2.</h2>' + - '<h3>This is an h3.</h3><h4>This is an h4.</h4>' + - '<h5>This is an h5.</h5><h6>This is an h6.</h6></div>'; - assertContainerInnerHTML(expected); - }); - - test('updateContent link', () => { - // Fake chrome.readAnything methods for the following AXTree - // root htmlTag='#document' id=1 - // ++link htmlTag='a' url='http://www.google.com' id=2 - // ++++staticText name='This is a link.' id=3 - // ++link htmlTag='a' url='http://www.youtube.com' id=4 - // ++++staticText name='This is another link.' id=5 - const axTree = { - rootId: 1, - nodes: [ - { - id: 1, - role: 'rootWebArea', - htmlTag: '#document', - childIds: [2, 4], - }, - { - id: 2, - role: 'link', - htmlTag: 'a', - url: 'http://www.google.com', - childIds: [3], - }, - { - id: 3, - role: 'staticText', - name: 'This is a link.', - }, - { - id: 4, - role: 'link', - htmlTag: 'a', - url: 'http://www.youtube.com', - childIds: [5], - }, - { - id: 5, - role: 'staticText', - name: 'This is another link.', - }, - ], - }; - chrome.readAnything.setContentForTesting(axTree, [2, 4]); - const expected = '<div><a href="http://www.google.com">This is a link.' + - '</a><a href="http://www.youtube.com">This is another link.</a></div>'; - assertContainerInnerHTML(expected); - }); - - test('updateContent link badInput', () => { - // Fake chrome.readAnything methods for the following AXTree - // root htmlTag='#document' id=1 - // ++link htmlTag='a' id=2 - // ++++staticText name='This link does not have a url.' id=3 - // ++image htmlTag='img' url='http://www.mycat.com' id=4 - const axTree = { - rootId: 1, - nodes: [ - { - id: 1, - role: 'rootWebArea', - htmlTag: '#document', - childIds: [2, 4], - }, - { - id: 2, - role: 'link', - htmlTag: 'a', - childIds: [3], - }, - { - id: 3, - role: 'staticText', - name: 'This link does not have a url.', - }, - { - id: 4, - role: 'image', - htmlTag: 'img', - url: 'http://www.mycat.com', - }, - ], - }; - chrome.readAnything.setContentForTesting(axTree, [2, 4]); - const expected = '<div><a>This link does not have a url.</a><img></div>'; - assertContainerInnerHTML(expected); - }); - - test('updateContent staticText', () => { - // Fake chrome.readAnything methods for the following AXTree - // root htmlTag='#document' id=1 - // ++staticText name='This is some text.' id=2 - // ++staticText name='This is some more text.' id=3 - const axTree = { - rootId: 1, - nodes: [ - { - id: 1, - role: 'rootWebArea', - htmlTag: '#document', - childIds: [2, 3], - }, - { - id: 2, - role: 'staticText', - name: 'This is some text.', - }, - { - id: 3, - role: 'staticText', - name: 'This is some more text.', - }, - ], - }; - chrome.readAnything.setContentForTesting(axTree, [2, 3]); - const expected = '<div>This is some text.This is some more text.</div>'; - assertContainerInnerHTML(expected); - }); - - test('updateContent staticText badInput', () => { - // Fake chrome.readAnything methods for the following AXTree - // root htmlTag='#document' id=1 - // ++staticText name='' id=2 - const axTree = { - rootId: 1, - nodes: [ - { - id: 1, - role: 'rootWebArea', - htmlTag: '#document', - childIds: [2], - }, - { - id: 2, - role: 'staticText', - }, - ], - }; - chrome.readAnything.setContentForTesting(axTree, [2]); - const expected = ''; - assertContainerInnerHTML(expected); - }); - - // The container clears its old content when it receives new content. - test('updateContent clearContainer', () => { - // Fake chrome.readAnything methods for the following AXTree - // root htmlTag='#document' id=1 - // ++staticText name='First set of content.' id=2 - const axTree1 = { - rootId: 1, - nodes: [ - { - id: 1, - role: 'rootWebArea', - htmlTag: '#document', - childIds: [2], - }, - { - id: 2, - role: 'staticText', - name: 'First set of content.', - }, - ], - }; - chrome.readAnything.setContentForTesting(axTree1, [2]); - const expected1 = '<div>First set of content.</div>'; - assertContainerInnerHTML(expected1); - - // Fake chrome.readAnything methods for the following AXTree - // root htmlTag='#document' id=1 - // ++staticText name='Second set of content.' id=2 - const axTree2 = { - rootId: 1, - nodes: [ - { - id: 1, - role: 'rootWebArea', - htmlTag: '#document', - childIds: [2], - }, - { - id: 2, - role: 'staticText', - name: 'Second set of content.', - }, - ], - }; - chrome.readAnything.setContentForTesting(axTree2, [2]); - const expected2 = '<div>Second set of content.</div>'; - assertContainerInnerHTML(expected2); - }); - - test('updateContent selection', () => { - // root htmlTag='#document' id=1 - // ++paragraph htmlTag='p' id=2 - // ++++staticText name='Hello' id=3 - // ++paragraph htmlTag='p' id=4 - // ++++staticText name='World' id=5 - // ++paragraph htmlTag='p' id=6 - // ++++staticText name='Friend' id=7 - // ++++staticText name='!' id=8 - const axTree = { - rootId: 1, - nodes: [ - { - id: 1, - role: 'rootWebArea', - htmlTag: '#document', - childIds: [2, 4, 6], - }, - { - id: 2, - role: 'paragraph', - htmlTag: 'p', - childIds: [3], - }, - { - id: 3, - role: 'staticText', - name: 'Hello', - }, - { - id: 4, - role: 'paragraph', - htmlTag: 'p', - childIds: [5], - }, - { - id: 5, - role: 'staticText', - name: 'World', - }, - { - id: 6, - role: 'paragraph', - htmlTag: 'p', - childIds: [7, 8], - }, - { - id: 7, - role: 'staticText', - name: 'Friend', - }, - { - id: 8, - role: 'staticText', - name: '!', - }, - ], - selection: { - anchor_object_id: 5, - focus_object_id: 7, - anchor_offset: 1, - focus_offset: 2, - is_backward: false, - }, - }; - setOnSelectionChangeForTest(); - chrome.readAnything.setContentForTesting(axTree, []); - // The expected string contains the complete text of each node in the - // selection. - const expected = '<div><p>World</p><p>Friend</p></div>'; - assertContainerInnerHTML(expected); - const selection = readAnythingApp.shadowRoot!.getSelection(); - assertEquals(selection!.anchorNode!.textContent, 'World'); - assertEquals(selection!.focusNode!.textContent, 'Friend'); - assertEquals(selection!.anchorOffset, 1); - assertEquals(selection!.focusOffset, 2); - }); - - test('updateContent selection backwards', () => { - // root htmlTag='#document' id=1 - // ++paragraph htmlTag='p' id=2 - // ++++staticText name='Hello' id=3 - // ++paragraph htmlTag='p' id=4 - // ++++staticText name='World' id=5 - // ++paragraph htmlTag='p' id=6 - // ++++staticText name='Friend' id=7 - // ++++staticText name='!' id=8 - const axTree = { - rootId: 1, - nodes: [ - { - id: 1, - role: 'rootWebArea', - htmlTag: '#document', - childIds: [2, 4, 6], - }, - { - id: 2, - role: 'paragraph', - htmlTag: 'p', - childIds: [3], - }, - { - id: 3, - role: 'staticText', - name: 'Hello', - }, - { - id: 4, - role: 'paragraph', - htmlTag: 'p', - childIds: [5], - }, - { - id: 5, - role: 'staticText', - name: 'World', - }, - { - id: 6, - role: 'paragraph', - htmlTag: 'p', - childIds: [7, 8], - }, - { - id: 7, - role: 'staticText', - name: 'Friend', - }, - { - id: 8, - role: 'staticText', - name: '!', - }, - ], - selection: { - anchor_object_id: 7, - focus_object_id: 3, - anchor_offset: 2, - focus_offset: 1, - is_backward: true, - }, - }; - setOnSelectionChangeForTest(); - chrome.readAnything.setContentForTesting(axTree, []); - // The expected string contains the complete text of each node in the - // selection. - const expected = '<div><p>Hello</p><p>World</p><p>Friend</p></div>'; - assertContainerInnerHTML(expected); - const selection = readAnythingApp.shadowRoot!.getSelection(); - assertEquals(selection!.anchorNode!.textContent, 'Hello'); - assertEquals(selection!.focusNode!.textContent, 'Friend'); - assertEquals(selection!.anchorOffset, 1); - assertEquals(selection!.focusOffset, 2); - }); - - test('updateContent selection outsideDistilledContent', () => { - // root htmlTag='#document' id=1 - // ++paragraph htmlTag='p' id=2 - // ++++staticText name='Hello' id=3 - // ++paragraph htmlTag='p' id=4 - // ++++staticText name='World' id=5 - // ++paragraph htmlTag='p' id=6 - // ++++staticText name='Friend' id=7 - // ++++staticText name='!' id=8 - const axTree = { - rootId: 1, - nodes: [ - { - id: 1, - role: 'rootWebArea', - htmlTag: '#document', - childIds: [2, 4, 6], - }, - { - id: 2, - role: 'paragraph', - htmlTag: 'p', - childIds: [3], - }, - { - id: 3, - role: 'staticText', - name: 'Hello', - }, - { - id: 4, - role: 'paragraph', - htmlTag: 'p', - childIds: [5], - }, - { - id: 5, - role: 'staticText', - name: 'World', - }, - { - id: 6, - role: 'paragraph', - htmlTag: 'p', - childIds: [7, 8], - }, - { - id: 7, - role: 'staticText', - name: 'Friend', - }, - { - id: 8, - role: 'staticText', - name: '!', - }, - ], - selection: { - anchor_object_id: 5, - focus_object_id: 7, - anchor_offset: 1, - focus_offset: 2, - is_backward: false, - }, - }; - chrome.readAnything.setContentForTesting(axTree, [2]); - // The selection is outside the content nodes.The expected string contains - // the complete text of each node in the selection. - const expected = '<div><p>World</p><p>Friend</p></div>'; - assertContainerInnerHTML(expected); - }); - - test('updateContent selection partiallyOutsideDistilledContent', () => { - // root htmlTag='#document' id=1 - // ++paragraph htmlTag='p' id=2 - // ++++staticText name='Hello' id=3 - // ++paragraph htmlTag='p' id=4 - // ++++staticText name='World' id=5 - // ++paragraph htmlTag='p' id=6 - // ++++staticText name='Friend' id=7 - // ++++staticText name='!' id=8 - const axTree = { - rootId: 1, - nodes: [ - { - id: 1, - role: 'rootWebArea', - htmlTag: '#document', - childIds: [2, 4, 6], - }, - { - id: 2, - role: 'paragraph', - htmlTag: 'p', - childIds: [3], - }, - { - id: 3, - role: 'staticText', - name: 'Hello', - }, - { - id: 4, - role: 'paragraph', - htmlTag: 'p', - childIds: [5], - }, - { - id: 5, - role: 'staticText', - name: 'World', - }, - { - id: 6, - role: 'paragraph', - htmlTag: 'p', - childIds: [7, 8], - }, - { - id: 7, - role: 'staticText', - name: 'Friend', - }, - { - id: 8, - role: 'staticText', - name: '!', - }, - ], - selection: { - anchor_object_id: 3, - focus_object_id: 7, - anchor_offset: 1, - focus_offset: 2, - is_backward: false, - }, - }; - chrome.readAnything.setContentForTesting(axTree, [2, 4]); - // The selection has content inside and outside the content nodes. The - // expected string contains the complete text of each node in the selection. - const expected = '<div><p>Hello</p><p>World</p><p>Friend</p></div>'; - assertContainerInnerHTML(expected); - }); - - test('updateContent setSelectedText', async () => { - // root htmlTag='#document' id=1 - // ++staticText name='Hello' id=2 - // ++staticText name='World' id=3 - // ++staticText name='Friend' id=4 - const axTree = { - rootId: 1, - nodes: [ - { - id: 1, - role: 'rootWebArea', - htmlTag: '#document', - childIds: [2, 3, 4], - }, - { - id: 2, - role: 'staticText', - name: 'Hello', - }, - { - id: 3, - role: 'staticText', - name: 'World', - }, - { - id: 4, - role: 'staticText', - name: 'Friend', - }, - ], - }; - setOnSelectionChangeForTest(); - chrome.readAnything.setContentForTesting(axTree, [1]); - const expected = '<div>HelloWorldFriend</div>'; - assertContainerInnerHTML(expected); - - // Create a selection of "elloWorldFr". The anchor node has id 2 and the - // focus node has id 4. - const outerDiv = - readAnythingApp.shadowRoot!.getElementById( - 'container')!.firstElementChild; - const range = new Range(); - range.setStart(outerDiv!.firstChild!, 1); - range.setEnd(outerDiv!.lastChild!, 2); - const selection = readAnythingApp.shadowRoot!.getSelection(); - selection!.removeAllRanges(); - selection!.addRange(range); - - // When the selection is set, readAnythingApp listens for the selection - // change event and calls chrome.readAnything.onSelectionChange. This test - // overrides that method and fires a custom event - // 'on-selection-change-for-test' with the parameters to onSelectionChange - // stored in details. Here, we check the values of the parameters of - // onSelectionChange. - const onSelectionChangeEvent = await eventToPromise( - 'on-selection-change-for-test', readAnythingApp.shadowRoot!); - assertEquals(onSelectionChangeEvent.detail.anchorNodeId, 2); - assertEquals(onSelectionChangeEvent.detail.anchorOffset, 1); - assertEquals(onSelectionChangeEvent.detail.focusNodeId, 4); - assertEquals(onSelectionChangeEvent.detail.focusOffset, 2); - }); - - test('updateContent textDirection', () => { - // root htmlTag='#document' id=1 - // ++paragraph htmlTag='p' id=2 direction='ltr' - // ++++staticText name='This is left to right writing' id=3 - // ++paragraph htmlTag='p' id=4 direction='rtl' - // ++++staticText name='This is right to left writing' id=4 - const axTree = { - rootId: 1, - nodes: [ - { - id: 1, - role: 'rootWebArea', - htmlTag: '#document', - childIds: [2, 4], - }, - { - id: 2, - role: 'paragraph', - htmlTag: 'p', - direction: 1, - childIds: [3], - }, - { - id: 3, - role: 'staticText', - name: 'This is left to right writing', - }, - { - id: 4, - role: 'paragraph', - htmlTag: 'p', - direction: 2, - childIds: [5], - }, - { - id: 5, - role: 'staticText', - name: 'This is right to left writing', - }, - ], - }; - chrome.readAnything.setContentForTesting(axTree, [2, 4]); - const expected = '<div><p dir="ltr">This is left to right writing</p>' + - '<p dir="rtl">This is right to left writing</p></div>'; - assertContainerInnerHTML(expected); - }); - - test('updateContent textDirection parentNodeDiffDir', () => { - // root htmlTag='#document' id=1 - // ++paragraph htmlTag='p' id=2 direction='ltr' - // ++++staticText name='This is ltr' id=3 - // ++++link htmlTag='a' url='http://www.google.com/' id=4 direction='rtl' - // ++++++staticText name='This link is rtl' id=5 - const axTree = { - rootId: 1, - nodes: [ - { - id: 1, - role: 'rootWebArea', - htmlTag: '#document', - childIds: [2], - }, - { - id: 2, - role: 'paragraph', - htmlTag: 'p', - direction: 1, - childIds: [3, 4], - }, - { - id: 3, - role: 'staticText', - name: 'This is ltr', - }, - { - id: 4, - role: 'link', - htmlTag: 'a', - direction: 2, - url: 'http://www.google.com/', - childIds: [5], - }, - { - id: 5, - role: 'staticText', - name: 'This link is rtl', - }, - ], - }; - chrome.readAnything.setContentForTesting(axTree, [2]); - const expected = '<div><p dir="ltr">This is ltr' + - '<a dir="rtl" href="http://www.google.com/">' + - 'This link is rtl</a></p></div>'; - assertContainerInnerHTML(expected); - }); - - test('updateContent textDirection verticalDir', () => { - // root htmlTag='#document' id=1 - // ++paragraph htmlTag='p' id=2 direction='ttb' - // ++++staticText name='This should be auto' id=3 - // ++paragraph htmlTag='p' id=4 direction='btt' - // ++++staticText name='This should be also be auto' id=4 - const axTree = { - rootId: 1, - nodes: [ - { - id: 1, - role: 'rootWebArea', - htmlTag: '#document', - childIds: [2, 4], - }, - { - id: 2, - role: 'paragraph', - htmlTag: 'p', - direction: 3, - childIds: [3], - }, - { - id: 3, - role: 'staticText', - name: 'This should be auto', - }, - { - id: 4, - role: 'paragraph', - htmlTag: 'p', - direction: 4, - childIds: [5], - }, - { - id: 5, - role: 'staticText', - name: 'This should be also be auto', - }, - ], - }; - chrome.readAnything.setContentForTesting(axTree, [2, 4]); - const expected = '<div><p dir="auto">This should be auto</p>' + - '<p dir="auto">This should be also be auto</p></div>'; - assertContainerInnerHTML(expected); - }); - - test('updateContent textStyle overline', () => { - // root htmlTag='#document' id=1 - // ++paragraph htmlTag='p' id=2 - // ++++staticText name='This should be overlined.' textStyle='overline' id=3 - // ++++staticText name='Regular text.' id=4 - // ++++staticText name='This is overlined and bolded.' textStyle='overline - // underline'id=5 - const axTree = { - rootId: 1, - nodes: [ - { - id: 1, - role: 'rootWebArea', - htmlTag: '#document', - childIds: [2], - }, - { - id: 2, - role: 'paragraph', - htmlTag: 'p', - childIds: [3, 4, 5], - }, - { - id: 3, - role: 'staticText', - textStyle: 'overline', - name: 'This should be overlined.', - }, - { - id: 4, - role: 'staticText', - name: 'Regular text.', - }, - { - id: 5, - role: 'staticText', - textStyle: 'overline underline', - name: 'This is overlined and bolded.', - }, - ], - }; - chrome.readAnything.setContentForTesting(axTree, [2]); - const expected = '<div><p><span style="text-decoration: overline;">This ' + - 'should be overlined.</span>Regular text.<b style="text-decoration: ' + - 'overline;">This is overlined and bolded.</b></p></div>'; - assertContainerInnerHTML(expected); - }); - - test('updateContent textStyle bold', () => { - // root htmlTag='#document' id=1 - // ++paragraph htmlTag='p' id=2 - // ++++staticText name='Regular text.' id=3 - // ++++staticText name='This should be bolded.' textStyle='underline' id=4 - // ++paragraph htmlTag='p' id=5 - // ++++staticText name='Bolded text.' textStyle='italic' id=6 - // ++++staticText name='Bolded text.' textStyle='bold' id=7 - const axTree = { - rootId: 1, - nodes: [ - { - id: 1, - role: 'rootWebArea', - htmlTag: '#document', - childIds: [2, 5], - }, - { - id: 2, - role: 'paragraph', - htmlTag: 'p', - childIds: [3, 4], - }, - { - id: 3, - role: 'staticText', - name: 'Regular text.', - }, - { - id: 4, - role: 'staticText', - textStyle: 'underline', - name: 'This should be bolded.', - }, - { - id: 5, - role: 'paragraph', - htmlTag: 'p', - childIds: [6, 7], - }, - { - id: 6, - role: 'staticText', - textStyle: 'italic', - name: 'Bolded text.', - }, - { - id: 7, - role: 'staticText', - textStyle: 'bold', - name: 'Bolded text.', - }, - ], - }; - chrome.readAnything.setContentForTesting(axTree, [2, 5]); - const expected = '<div><p>Regular text.<b>This should be bolded.</b></p>' + - '<p><b>Bolded text.</b><b>Bolded text.</b></p></div>'; - assertContainerInnerHTML(expected); - }); - - test('updateContent noContentNodes', () => { - // Fake chrome.readAnything methods for the following AXTree - // root htmlTag='#document' id=1 - // ++staticText name='This is some text.' id=2 - const axTree = { - rootId: 1, - nodes: [ - { - id: 1, - role: 'rootWebArea', - htmlTag: '#document', - childIds: [2], - }, - { - id: 2, - role: 'staticText', - name: 'This is some text.', - }, - ], - }; - chrome.readAnything.setContentForTesting(axTree, []); - const expected = ''; - assertContainerInnerHTML(expected); - }); - - test('updateContent interactiveElement', () => { - // root htmlTag='#document' id=1 - // ++paragraph htmlTag='p' id=2 - // ++++staticText name='hello world' id=3 - // ++button htmlTag='button' id=4 - // ++++staticText name='button text' id=5 - const axTree = { - rootId: 1, - nodes: [ - { - id: 1, - role: 'rootWebArea', - htmlTag: '#document', - childIds: [2, 4], - }, - { - id: 2, - role: 'paragraph', - htmlTag: 'p', - childIds: [3], - }, - { - id: 3, - role: 'staticText', - name: 'hello world', - }, - { - id: 4, - role: 'button', - htmlTag: 'button', - childIds: [5], - }, - { - id: 5, - role: 'staticText', - name: 'button text', - }, - ], - }; - chrome.readAnything.setContentForTesting(axTree, [2, 4]); - const expected = '<div><p>hello world</p></div>'; - assertContainerInnerHTML(expected); - }); -});
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_clear_container.js b/chrome/test/data/webui/side_panel/read_anything/update_content_clear_container.js new file mode 100644 index 0000000..6bbdcba --- /dev/null +++ b/chrome/test/data/webui/side_panel/read_anything/update_content_clear_container.js
@@ -0,0 +1,74 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// out/Debug/browser_tests \ +// --gtest_filter=ReadAnythingAppTest.UpdateContent_ClearContainer + +// The container clears its old content when it receives new content. + +const readAnythingApp = document.querySelector('read-anything-app').shadowRoot; +const container = readAnythingApp.getElementById('container'); +let result = true; + +function assertEquals(actual, expected) { + const isEqual = actual === expected; + if (!isEqual) { + console.error( + 'Expected: ' + JSON.stringify(expected) + ', ' + + 'Actual: ' + JSON.stringify(actual)); + } + result = result && isEqual; + return isEqual; +} + +function assertContainerInnerHTML(expected) { + const actual = container.innerHTML; + assertEquals(actual, expected); +} + +// root htmlTag='#document' id=1 +// ++staticText name='First set of content.' id=2 +const axTree1 = { + rootId: 1, + nodes: [ + { + id: 1, + role: 'rootWebArea', + htmlTag: '#document', + childIds: [2], + }, + { + id: 2, + role: 'staticText', + name: 'First set of content.', + }, + ], +}; +chrome.readAnything.setContentForTesting(axTree1, [2]); +const expected1 = '<div>First set of content.</div>'; +assertContainerInnerHTML(expected1); + +// root htmlTag='#document' id=1 +// ++staticText name='Second set of content.' id=2 +const axTree2 = { + rootId: 1, + nodes: [ + { + id: 1, + role: 'rootWebArea', + htmlTag: '#document', + childIds: [2], + }, + { + id: 2, + role: 'staticText', + name: 'Second set of content.', + }, + ], +}; +chrome.readAnything.setContentForTesting(axTree2, [2]); +const expected2 = '<div>Second set of content.</div>'; +assertContainerInnerHTML(expected2); + +domAutomationController.send(result);
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_heading.js b/chrome/test/data/webui/side_panel/read_anything/update_content_heading.js new file mode 100644 index 0000000..cc174918 --- /dev/null +++ b/chrome/test/data/webui/side_panel/read_anything/update_content_heading.js
@@ -0,0 +1,124 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// out/Debug/browser_tests \ +// --gtest_filter=ReadAnythingAppTest.UpdateContent_Heading + +const readAnythingApp = document.querySelector('read-anything-app').shadowRoot; +const container = readAnythingApp.getElementById('container'); +let result = true; + +function assertEquals(actual, expected) { + const isEqual = actual === expected; + if (!isEqual) { + console.error( + 'Expected: ' + JSON.stringify(expected) + ', ' + + 'Actual: ' + JSON.stringify(actual)); + } + result = result && isEqual; + return isEqual; +} + +function assertContainerInnerHTML(expected) { + const actual = container.innerHTML; + assertEquals(actual, expected); +} + +// root htmlTag='#document' id=1 +// ++heading htmlTag='h1' id=2 +// ++++staticText name='This is an h1.' id=3 +// ++heading htmlTag='h2' id=4 +// ++++staticText name='This is an h2.' id=5 +// ++heading htmlTag='h3' id=6 +// ++++staticText name='This is an h3.' id=7 +// ++heading htmlTag='h4' id=8 +// ++++staticText name='This is an h4.' id=9 +// ++heading htmlTag='h5' id=10 +// ++++staticText name='This is an h5.' id=11 +// ++heading htmlTag='h6' id=12 +// ++++staticText name='This is an h6.' id=13 +const axTree = { + rootId: 1, + nodes: [ + { + id: 1, + role: 'rootWebArea', + htmlTag: '#document', + childIds: [2, 4, 6, 8, 10, 12], + }, + { + id: 2, + role: 'heading', + htmlTag: 'h1', + childIds: [3], + }, + { + id: 3, + role: 'staticText', + name: 'This is an h1.', + }, + { + id: 4, + role: 'heading', + htmlTag: 'h2', + childIds: [5], + }, + { + id: 5, + role: 'staticText', + name: 'This is an h2.', + }, + { + id: 6, + role: 'heading', + htmlTag: 'h3', + childIds: [7], + }, + { + id: 7, + role: 'staticText', + name: 'This is an h3.', + }, + { + id: 8, + role: 'heading', + htmlTag: 'h4', + childIds: [9], + }, + { + id: 9, + role: 'staticText', + name: 'This is an h4.', + }, + { + id: 10, + role: 'heading', + htmlTag: 'h5', + childIds: [11], + }, + { + id: 11, + role: 'staticText', + name: 'This is an h5.', + }, + { + id: 12, + role: 'heading', + htmlTag: 'h6', + childIds: [13], + }, + { + id: 13, + role: 'staticText', + name: 'This is an h6.', + }, + ], +}; +chrome.readAnything.setContentForTesting(axTree, [2, 4, 6, 8, 10, 12]); +const expected = '<div><h1>This is an h1.</h1><h2>This is an h2.</h2>' + + '<h3>This is an h3.</h3><h4>This is an h4.</h4>' + + '<h5>This is an h5.</h5><h6>This is an h6.</h6></div>'; +assertContainerInnerHTML(expected); + +domAutomationController.send(result);
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_hides_loading_screen.js b/chrome/test/data/webui/side_panel/read_anything/update_content_hides_loading_screen.js new file mode 100644 index 0000000..a46cbdc --- /dev/null +++ b/chrome/test/data/webui/side_panel/read_anything/update_content_hides_loading_screen.js
@@ -0,0 +1,52 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// out/Debug/browser_tests \ +// --gtest_filter=ReadAnythingAppTest.UpdateContent_HidesLoadingScreen + +const readAnythingApp = document.querySelector('read-anything-app').shadowRoot; +let result = true; + +function assertEquals(actual, expected) { + const isEqual = actual === expected; + if (!isEqual) { + console.error( + 'Expected: ' + JSON.stringify(expected) + ', ' + + 'Actual: ' + JSON.stringify(actual)); + } + result = result && isEqual; + return isEqual; +} + +// root htmlTag='#document' id=1 +// ++paragraph htmlTag='p' id=2 +// ++++staticText name='This is a paragraph' id=3 +const axTree = { + rootId: 1, + nodes: [ + { + id: 1, + role: 'rootWebArea', + htmlTag: '#document', + childIds: [2], + }, + { + id: 2, + role: 'paragraph', + htmlTag: 'p', + childIds: [3], + }, + { + id: 3, + role: 'staticText', + name: 'This is a paragraph', + }, + ], +}; +chrome.readAnything.setContentForTesting(axTree, [2]); + +assertEquals( + readAnythingApp.getElementById('empty-state-container').hidden, true); + +domAutomationController.send(result);
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_interactive_element.js b/chrome/test/data/webui/side_panel/read_anything/update_content_interactive_element.js new file mode 100644 index 0000000..26b8549 --- /dev/null +++ b/chrome/test/data/webui/side_panel/read_anything/update_content_interactive_element.js
@@ -0,0 +1,70 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// out/Debug/browser_tests \ +// --gtest_filter=ReadAnythingAppTest.UpdateContent_InteractiveElement + +const readAnythingApp = document.querySelector('read-anything-app').shadowRoot; +const container = readAnythingApp.getElementById('container'); +let result = true; + +function assertEquals(actual, expected) { + const isEqual = actual === expected; + if (!isEqual) { + console.error( + 'Expected: ' + JSON.stringify(expected) + ', ' + + 'Actual: ' + JSON.stringify(actual)); + } + result = result && isEqual; + return isEqual; +} + +function assertContainerInnerHTML(expected) { + const actual = container.innerHTML; + assertEquals(actual, expected); +} + +// root htmlTag='#document' id=1 +// ++paragraph htmlTag='p' id=2 +// ++++staticText name='hello world' id=3 +// ++button htmlTag='button' id=4 +// ++++staticText name='button text' id=5 +const axTree = { + rootId: 1, + nodes: [ + { + id: 1, + role: 'rootWebArea', + htmlTag: '#document', + childIds: [2, 4], + }, + { + id: 2, + role: 'paragraph', + htmlTag: 'p', + childIds: [3], + }, + { + id: 3, + role: 'staticText', + name: 'hello world', + }, + { + id: 4, + role: 'button', + htmlTag: 'button', + childIds: [5], + }, + { + id: 5, + role: 'staticText', + name: 'button text', + }, + ], +}; +chrome.readAnything.setContentForTesting(axTree, [2, 4]); +const expected = '<div><p>hello world</p></div>'; +assertContainerInnerHTML(expected); + +domAutomationController.send(result);
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_language_child_node_diff_lang.js b/chrome/test/data/webui/side_panel/read_anything/update_content_language_child_node_diff_lang.js new file mode 100644 index 0000000..0c894c6 --- /dev/null +++ b/chrome/test/data/webui/side_panel/read_anything/update_content_language_child_node_diff_lang.js
@@ -0,0 +1,91 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// out/Debug/browser_tests \ +// --gtest_filter=ReadAnythingAppTest.\ +// UpdateContent_Language_ChildNodeDiffLang + +const readAnythingApp = document.querySelector('read-anything-app').shadowRoot; +const container = readAnythingApp.getElementById('container'); +let result = true; + +function assertEquals(actual, expected) { + const isEqual = actual === expected; + if (!isEqual) { + console.error( + 'Expected: ' + JSON.stringify(expected) + ', ' + + 'Actual: ' + JSON.stringify(actual)); + } + result = result && isEqual; + return isEqual; +} + +function assertContainerInnerHTML(expected) { + const actual = container.innerHTML; + assertEquals(actual, expected); +} + +// root htmlTag='#document' id=1 +// ++paragraph htmlTag='p' id=2 language='en' +// ++++staticText name='This is in English' id=3 +// ++paragraph htmlTag='p' id=4 language='es' +// ++++staticText name='Esto es en español' id=5 +// ++++link htmlTag='a' url='http://www.google.cn/' id=6 language='zh' +// ++++++staticText name='This is a link in Chinese' id=7 +const axTree = { + rootId: 1, + nodes: [ + { + id: 1, + role: 'rootWebArea', + htmlTag: '#document', + childIds: [2, 4], + }, + { + id: 2, + role: 'paragraph', + htmlTag: 'p', + language: 'en', + childIds: [3], + }, + { + id: 3, + role: 'staticText', + name: 'This is in English', + }, + { + id: 4, + role: 'paragraph', + htmlTag: 'p', + language: 'es', + childIds: [5, 6], + }, + { + id: 5, + role: 'staticText', + name: 'Esto es en español', + }, + { + id: 6, + role: 'link', + htmlTag: 'a', + language: 'zh', + url: 'http://www.google.cn/', + childIds: [7], + }, + { + id: 7, + role: 'staticText', + name: 'This is a link in Chinese', + }, + ], +}; +chrome.readAnything.setContentForTesting(axTree, [2, 4]); +const expected = '<div><p lang="en">This is in English</p>' + + '<p lang="es">Esto es en español' + + '<a href="http://www.google.cn/" lang="zh">' + + 'This is a link in Chinese</a></p></div>'; +assertContainerInnerHTML(expected); + +domAutomationController.send(result);
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_language_parent_lang_set.js b/chrome/test/data/webui/side_panel/read_anything/update_content_language_parent_lang_set.js new file mode 100644 index 0000000..1b9a5b4 --- /dev/null +++ b/chrome/test/data/webui/side_panel/read_anything/update_content_language_parent_lang_set.js
@@ -0,0 +1,74 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// out/Debug/browser_tests \ +// --gtest_filter=ReadAnythingAppTest.UpdateContent_Language_ParentLangSet + +const readAnythingApp = document.querySelector('read-anything-app').shadowRoot; +const container = readAnythingApp.getElementById('container'); +let result = true; + +function assertEquals(actual, expected) { + const isEqual = actual === expected; + if (!isEqual) { + console.error( + 'Expected: ' + JSON.stringify(expected) + ', ' + + 'Actual: ' + JSON.stringify(actual)); + } + result = result && isEqual; + return isEqual; +} + +function assertContainerInnerHTML(expected) { + const actual = container.innerHTML; + assertEquals(actual, expected); +} + +// root htmlTag='#document' id=1 +// ++paragraph htmlTag='p' id=2 language='en' +// ++++staticText name='This is in English' id=3 +// ++++link htmlTag='a' url='http://www.google.com/' id=4 +// ++++++staticText name='This link has no language set' id=5 +const axTree = { + rootId: 1, + nodes: [ + { + id: 1, + role: 'rootWebArea', + htmlTag: '#document', + childIds: [2], + }, + { + id: 2, + role: 'paragraph', + htmlTag: 'p', + language: 'en', + childIds: [3, 4], + }, + { + id: 3, + role: 'staticText', + name: 'This is in English', + }, + { + id: 4, + role: 'link', + htmlTag: 'a', + url: 'http://www.google.com/', + childIds: [5], + }, + { + id: 5, + role: 'staticText', + name: 'This link has no language set', + }, + ], +}; +chrome.readAnything.setContentForTesting(axTree, [2]); +const expected = '<div><p lang="en">This is in English' + + '<a href="http://www.google.com/">This link has no language set</a>' + + '</p></div>'; +assertContainerInnerHTML(expected); + +domAutomationController.send(result);
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_link.js b/chrome/test/data/webui/side_panel/read_anything/update_content_link.js new file mode 100644 index 0000000..7abdd61 --- /dev/null +++ b/chrome/test/data/webui/side_panel/read_anything/update_content_link.js
@@ -0,0 +1,73 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// out/Debug/browser_tests \ +// --gtest_filter=ReadAnythingAppTest.UpdateContent_Link + +const readAnythingApp = document.querySelector('read-anything-app').shadowRoot; +const container = readAnythingApp.getElementById('container'); +let result = true; + +function assertEquals(actual, expected) { + const isEqual = actual === expected; + if (!isEqual) { + console.error( + 'Expected: ' + JSON.stringify(expected) + ', ' + + 'Actual: ' + JSON.stringify(actual)); + } + result = result && isEqual; + return isEqual; +} + +function assertContainerInnerHTML(expected) { + const actual = container.innerHTML; + assertEquals(actual, expected); +} + +// root htmlTag='#document' id=1 +// ++link htmlTag='a' url='http://www.google.com' id=2 +// ++++staticText name='This is a link.' id=3 +// ++link htmlTag='a' url='http://www.youtube.com' id=4 +// ++++staticText name='This is another link.' id=5 +const axTree = { + rootId: 1, + nodes: [ + { + id: 1, + role: 'rootWebArea', + htmlTag: '#document', + childIds: [2, 4], + }, + { + id: 2, + role: 'link', + htmlTag: 'a', + url: 'http://www.google.com', + childIds: [3], + }, + { + id: 3, + role: 'staticText', + name: 'This is a link.', + }, + { + id: 4, + role: 'link', + htmlTag: 'a', + url: 'http://www.youtube.com', + childIds: [5], + }, + { + id: 5, + role: 'staticText', + name: 'This is another link.', + }, + ], +}; +chrome.readAnything.setContentForTesting(axTree, [2, 4]); +const expected = '<div><a href="http://www.google.com">This is a link.' + + '</a><a href="http://www.youtube.com">This is another link.</a></div>'; +assertContainerInnerHTML(expected); + +domAutomationController.send(result);
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_link_bad_input.js b/chrome/test/data/webui/side_panel/read_anything/update_content_link_bad_input.js new file mode 100644 index 0000000..eba18cc2 --- /dev/null +++ b/chrome/test/data/webui/side_panel/read_anything/update_content_link_bad_input.js
@@ -0,0 +1,64 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// out/Debug/browser_tests \ +// --gtest_filter=ReadAnythingAppTest.UpdateContent_Link_BadInput + +const readAnythingApp = document.querySelector('read-anything-app').shadowRoot; +const container = readAnythingApp.getElementById('container'); +let result = true; + +function assertEquals(actual, expected) { + const isEqual = actual === expected; + if (!isEqual) { + console.error( + 'Expected: ' + JSON.stringify(expected) + ', ' + + 'Actual: ' + JSON.stringify(actual)); + } + result = result && isEqual; + return isEqual; +} + +function assertContainerInnerHTML(expected) { + const actual = container.innerHTML; + assertEquals(actual, expected); +} + +// root htmlTag='#document' id=1 +// ++link htmlTag='a' id=2 +// ++++staticText name='This link does not have a url.' id=3 +// ++image htmlTag='img' url='http://www.mycat.com' id=4 +const axTree = { + rootId: 1, + nodes: [ + { + id: 1, + role: 'rootWebArea', + htmlTag: '#document', + childIds: [2, 4], + }, + { + id: 2, + role: 'link', + htmlTag: 'a', + childIds: [3], + }, + { + id: 3, + role: 'staticText', + name: 'This link does not have a url.', + }, + { + id: 4, + role: 'image', + htmlTag: 'img', + url: 'http://www.mycat.com', + }, + ], +}; +chrome.readAnything.setContentForTesting(axTree, [2, 4]); +const expected = '<div><a>This link does not have a url.</a><img></div>'; +assertContainerInnerHTML(expected); + +domAutomationController.send(result);
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_no_content_nodes.js b/chrome/test/data/webui/side_panel/read_anything/update_content_no_content_nodes.js new file mode 100644 index 0000000..9ec28cf --- /dev/null +++ b/chrome/test/data/webui/side_panel/read_anything/update_content_no_content_nodes.js
@@ -0,0 +1,50 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// out/Debug/browser_tests \ +// --gtest_filter=ReadAnythingAppTest.UpdateContent_NoContentNodes + +const readAnythingApp = document.querySelector('read-anything-app').shadowRoot; +const container = readAnythingApp.getElementById('container'); +let result = true; + +function assertEquals(actual, expected) { + const isEqual = actual === expected; + if (!isEqual) { + console.error( + 'Expected: ' + JSON.stringify(expected) + ', ' + + 'Actual: ' + JSON.stringify(actual)); + } + result = result && isEqual; + return isEqual; +} + +function assertContainerInnerHTML(expected) { + const actual = container.innerHTML; + assertEquals(actual, expected); +} + +// root htmlTag='#document' id=1 +// ++staticText name='This is some text.' id=2 +const axTree = { + rootId: 1, + nodes: [ + { + id: 1, + role: 'rootWebArea', + htmlTag: '#document', + childIds: [2], + }, + { + id: 2, + role: 'staticText', + name: 'This is some text.', + }, + ], +}; +chrome.readAnything.setContentForTesting(axTree, []); +const expected = ''; +assertContainerInnerHTML(expected); + +domAutomationController.send(result);
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_paragraph.js b/chrome/test/data/webui/side_panel/read_anything/update_content_paragraph.js new file mode 100644 index 0000000..3b9e9f3b --- /dev/null +++ b/chrome/test/data/webui/side_panel/read_anything/update_content_paragraph.js
@@ -0,0 +1,71 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// out/Debug/browser_tests \ +// --gtest_filter=ReadAnythingAppTest.UpdateContent_Paragraph + +const readAnythingApp = document.querySelector('read-anything-app').shadowRoot; +const container = readAnythingApp.getElementById('container'); +let result = true; + +function assertEquals(actual, expected) { + const isEqual = actual === expected; + if (!isEqual) { + console.error( + 'Expected: ' + JSON.stringify(expected) + ', ' + + 'Actual: ' + JSON.stringify(actual)); + } + result = result && isEqual; + return isEqual; +} + +function assertContainerInnerHTML(expected) { + const actual = container.innerHTML; + assertEquals(actual, expected); +} + +// root htmlTag='#document' id=1 +// ++paragraph htmlTag='p' id=2 +// ++++staticText name='This is a paragraph' id=3 +// ++paragraph htmlTag='p' id=4 +// ++++staticText name='This is a second paragraph' id=5 +const axTree = { + rootId: 1, + nodes: [ + { + id: 1, + role: 'rootWebArea', + htmlTag: '#document', + childIds: [2, 4], + }, + { + id: 2, + role: 'paragraph', + htmlTag: 'p', + childIds: [3], + }, + { + id: 3, + role: 'staticText', + name: 'This is a paragraph', + }, + { + id: 4, + role: 'paragraph', + htmlTag: 'p', + childIds: [5], + }, + { + id: 5, + role: 'staticText', + name: 'This is a second paragraph', + }, + ], +}; +chrome.readAnything.setContentForTesting(axTree, [2, 4]); +const expected = '<div><p>This is a paragraph</p>' + + '<p>This is a second paragraph</p></div>'; +assertContainerInnerHTML(expected); + +domAutomationController.send(result);
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_selection.js b/chrome/test/data/webui/side_panel/read_anything/update_content_selection.js new file mode 100644 index 0000000..75422fb --- /dev/null +++ b/chrome/test/data/webui/side_panel/read_anything/update_content_selection.js
@@ -0,0 +1,126 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// out/Debug/browser_tests \ +// --gtest_filter=ReadAnythingAppTest.UpdateContent_Selection + +const readAnythingApp = document.querySelector('read-anything-app').shadowRoot; +const container = readAnythingApp.getElementById('container'); +let result = true; + +function assertEquals(actual, expected) { + const isEqual = actual === expected; + if (!isEqual) { + console.error( + 'Expected: ' + JSON.stringify(expected) + ', ' + + 'Actual: ' + JSON.stringify(actual)); + } + result = result && isEqual; + return isEqual; +} + +function assertContainerInnerHTML(expected) { + const actual = container.innerHTML; + assertEquals(actual, expected); +} + +function setOnSelectionChangeForTest() { + // This is called by readAnythingApp onselectionchange. It is usually + // implemented by ReadAnythingAppController which forwards these arguments + // to the browser process in the form of an AXEventNotificationDetail. + // Instead, we capture the arguments here and verify their values. Since + // onselectionchange is called asynchronously, the test must wait for this + // function to be called; therefore we fire a custom event + // on-selection-change-for-text here for the test to await. + chrome.readAnything.onSelectionChange = function( + anchorNodeId, anchorOffset, focusNodeId, focusOffset) { + readAnythingApp.dispatchEvent( + new CustomEvent('on-selection-change-for-test', { + detail: { + anchorNodeId: anchorNodeId, + anchorOffset: anchorOffset, + focusNodeId: focusNodeId, + focusOffset: focusOffset, + }, + })); + }; +} + +// root htmlTag='#document' id=1 +// ++paragraph htmlTag='p' id=2 +// ++++staticText name='Hello' id=3 +// ++paragraph htmlTag='p' id=4 +// ++++staticText name='World' id=5 +// ++paragraph htmlTag='p' id=6 +// ++++staticText name='Friend' id=7 +// ++++staticText name='!' id=8 +const axTree = { + rootId: 1, + nodes: [ + { + id: 1, + role: 'rootWebArea', + htmlTag: '#document', + childIds: [2, 4, 6], + }, + { + id: 2, + role: 'paragraph', + htmlTag: 'p', + childIds: [3], + }, + { + id: 3, + role: 'staticText', + name: 'Hello', + }, + { + id: 4, + role: 'paragraph', + htmlTag: 'p', + childIds: [5], + }, + { + id: 5, + role: 'staticText', + name: 'World', + }, + { + id: 6, + role: 'paragraph', + htmlTag: 'p', + childIds: [7, 8], + }, + { + id: 7, + role: 'staticText', + name: 'Friend', + }, + { + id: 8, + role: 'staticText', + name: '!', + }, + ], + selection: { + anchor_object_id: 5, + focus_object_id: 7, + anchor_offset: 1, + focus_offset: 2, + is_backward: false, + }, +}; +setOnSelectionChangeForTest(); +chrome.readAnything.setContentForTesting(axTree, []); +// The expected string contains the complete text of each node in the +// selection. +const expected = '<div><p>World</p><p>Friend</p></div>'; +assertContainerInnerHTML(expected); +const selection = readAnythingApp.getSelection(); +assertEquals(selection.anchorNode.textContent, 'World'); +assertEquals(selection.focusNode.textContent, 'Friend'); +assertEquals(selection.anchorOffset, 1); +assertEquals(selection.focusOffset, 2); + +domAutomationController.send(result);
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_selection_backwards.js b/chrome/test/data/webui/side_panel/read_anything/update_content_selection_backwards.js new file mode 100644 index 0000000..0de21fb --- /dev/null +++ b/chrome/test/data/webui/side_panel/read_anything/update_content_selection_backwards.js
@@ -0,0 +1,126 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// out/Debug/browser_tests \ +// --gtest_filter=ReadAnythingAppTest.UpdateContent_Selection_Backwards + +const readAnythingApp = document.querySelector('read-anything-app').shadowRoot; +const container = readAnythingApp.getElementById('container'); +let result = true; + +function assertEquals(actual, expected) { + const isEqual = actual === expected; + if (!isEqual) { + console.error( + 'Expected: ' + JSON.stringify(expected) + ', ' + + 'Actual: ' + JSON.stringify(actual)); + } + result = result && isEqual; + return isEqual; +} + +function assertContainerInnerHTML(expected) { + const actual = container.innerHTML; + assertEquals(actual, expected); +} + +function setOnSelectionChangeForTest() { + // This is called by readAnythingApp onselectionchange. It is usually + // implemented by ReadAnythingAppController which forwards these arguments + // to the browser process in the form of an AXEventNotificationDetail. + // Instead, we capture the arguments here and verify their values. Since + // onselectionchange is called asynchronously, the test must wait for this + // function to be called; therefore we fire a custom event + // on-selection-change-for-text here for the test to await. + chrome.readAnything.onSelectionChange = function( + anchorNodeId, anchorOffset, focusNodeId, focusOffset) { + readAnythingApp.dispatchEvent( + new CustomEvent('on-selection-change-for-test', { + detail: { + anchorNodeId: anchorNodeId, + anchorOffset: anchorOffset, + focusNodeId: focusNodeId, + focusOffset: focusOffset, + }, + })); + }; +} + +// root htmlTag='#document' id=1 +// ++paragraph htmlTag='p' id=2 +// ++++staticText name='Hello' id=3 +// ++paragraph htmlTag='p' id=4 +// ++++staticText name='World' id=5 +// ++paragraph htmlTag='p' id=6 +// ++++staticText name='Friend' id=7 +// ++++staticText name='!' id=8 +const axTree = { + rootId: 1, + nodes: [ + { + id: 1, + role: 'rootWebArea', + htmlTag: '#document', + childIds: [2, 4, 6], + }, + { + id: 2, + role: 'paragraph', + htmlTag: 'p', + childIds: [3], + }, + { + id: 3, + role: 'staticText', + name: 'Hello', + }, + { + id: 4, + role: 'paragraph', + htmlTag: 'p', + childIds: [5], + }, + { + id: 5, + role: 'staticText', + name: 'World', + }, + { + id: 6, + role: 'paragraph', + htmlTag: 'p', + childIds: [7, 8], + }, + { + id: 7, + role: 'staticText', + name: 'Friend', + }, + { + id: 8, + role: 'staticText', + name: '!', + }, + ], + selection: { + anchor_object_id: 7, + focus_object_id: 3, + anchor_offset: 2, + focus_offset: 1, + is_backward: true, + }, +}; +setOnSelectionChangeForTest(); +chrome.readAnything.setContentForTesting(axTree, []); +// The expected string contains the complete text of each node in the +// selection. +const expected = '<div><p>Hello</p><p>World</p><p>Friend</p></div>'; +assertContainerInnerHTML(expected); +const selection = readAnythingApp.getSelection(); +assertEquals(selection.anchorNode.textContent, 'Hello'); +assertEquals(selection.focusNode.textContent, 'Friend'); +assertEquals(selection.anchorOffset, 1); +assertEquals(selection.focusOffset, 2); + +domAutomationController.send(result);
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_selection_outside_distilled_content.js b/chrome/test/data/webui/side_panel/read_anything/update_content_selection_outside_distilled_content.js new file mode 100644 index 0000000..b2c4d625 --- /dev/null +++ b/chrome/test/data/webui/side_panel/read_anything/update_content_selection_outside_distilled_content.js
@@ -0,0 +1,99 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// out/Debug/browser_tests \ +// --gtest_filter=ReadAnythingAppTest.\ +// UpdateContent_Selection_OutsideDistilledContent + +const readAnythingApp = document.querySelector('read-anything-app').shadowRoot; +const container = readAnythingApp.getElementById('container'); +let result = true; + +function assertEquals(actual, expected) { + const isEqual = actual === expected; + if (!isEqual) { + console.error( + 'Expected: ' + JSON.stringify(expected) + ', ' + + 'Actual: ' + JSON.stringify(actual)); + } + result = result && isEqual; + return isEqual; +} + +function assertContainerInnerHTML(expected) { + const actual = container.innerHTML; + assertEquals(actual, expected); +} + +// root htmlTag='#document' id=1 +// ++paragraph htmlTag='p' id=2 +// ++++staticText name='Hello' id=3 +// ++paragraph htmlTag='p' id=4 +// ++++staticText name='World' id=5 +// ++paragraph htmlTag='p' id=6 +// ++++staticText name='Friend' id=7 +// ++++staticText name='!' id=8 +const axTree = { + rootId: 1, + nodes: [ + { + id: 1, + role: 'rootWebArea', + htmlTag: '#document', + childIds: [2, 4, 6], + }, + { + id: 2, + role: 'paragraph', + htmlTag: 'p', + childIds: [3], + }, + { + id: 3, + role: 'staticText', + name: 'Hello', + }, + { + id: 4, + role: 'paragraph', + htmlTag: 'p', + childIds: [5], + }, + { + id: 5, + role: 'staticText', + name: 'World', + }, + { + id: 6, + role: 'paragraph', + htmlTag: 'p', + childIds: [7, 8], + }, + { + id: 7, + role: 'staticText', + name: 'Friend', + }, + { + id: 8, + role: 'staticText', + name: '!', + }, + ], + selection: { + anchor_object_id: 5, + focus_object_id: 7, + anchor_offset: 1, + focus_offset: 2, + is_backward: false, + }, +}; +chrome.readAnything.setContentForTesting(axTree, [2]); +// The selection is outside the content nodes.The expected string contains +// the complete text of each node in the selection. +const expected = '<div><p>World</p><p>Friend</p></div>'; +assertContainerInnerHTML(expected); + +domAutomationController.send(result);
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_selection_partially_outside_distilled_content.js b/chrome/test/data/webui/side_panel/read_anything/update_content_selection_partially_outside_distilled_content.js new file mode 100644 index 0000000..69ba548 --- /dev/null +++ b/chrome/test/data/webui/side_panel/read_anything/update_content_selection_partially_outside_distilled_content.js
@@ -0,0 +1,99 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// out/Debug/browser_tests \ +// --gtest_filter=ReadAnythingAppTest.\ +// UpdateContent_Selection_PartiallyOutsideDistilledContent + +const readAnythingApp = document.querySelector('read-anything-app').shadowRoot; +const container = readAnythingApp.getElementById('container'); +let result = true; + +function assertEquals(actual, expected) { + const isEqual = actual === expected; + if (!isEqual) { + console.error( + 'Expected: ' + JSON.stringify(expected) + ', ' + + 'Actual: ' + JSON.stringify(actual)); + } + result = result && isEqual; + return isEqual; +} + +function assertContainerInnerHTML(expected) { + const actual = container.innerHTML; + assertEquals(actual, expected); +} + +// root htmlTag='#document' id=1 +// ++paragraph htmlTag='p' id=2 +// ++++staticText name='Hello' id=3 +// ++paragraph htmlTag='p' id=4 +// ++++staticText name='World' id=5 +// ++paragraph htmlTag='p' id=6 +// ++++staticText name='Friend' id=7 +// ++++staticText name='!' id=8 +const axTree = { + rootId: 1, + nodes: [ + { + id: 1, + role: 'rootWebArea', + htmlTag: '#document', + childIds: [2, 4, 6], + }, + { + id: 2, + role: 'paragraph', + htmlTag: 'p', + childIds: [3], + }, + { + id: 3, + role: 'staticText', + name: 'Hello', + }, + { + id: 4, + role: 'paragraph', + htmlTag: 'p', + childIds: [5], + }, + { + id: 5, + role: 'staticText', + name: 'World', + }, + { + id: 6, + role: 'paragraph', + htmlTag: 'p', + childIds: [7, 8], + }, + { + id: 7, + role: 'staticText', + name: 'Friend', + }, + { + id: 8, + role: 'staticText', + name: '!', + }, + ], + selection: { + anchor_object_id: 3, + focus_object_id: 7, + anchor_offset: 1, + focus_offset: 2, + is_backward: false, + }, +}; +chrome.readAnything.setContentForTesting(axTree, [2, 4]); +// The selection has content inside and outside the content nodes. The +// expected string contains the complete text of each node in the selection. +const expected = '<div><p>Hello</p><p>World</p><p>Friend</p></div>'; +assertContainerInnerHTML(expected); + +domAutomationController.send(result);
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_set_selected_text.js b/chrome/test/data/webui/side_panel/read_anything/update_content_set_selected_text.js new file mode 100644 index 0000000..06ab34e --- /dev/null +++ b/chrome/test/data/webui/side_panel/read_anything/update_content_set_selected_text.js
@@ -0,0 +1,109 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// out/Debug/browser_tests \ +// --gtest_filter=ReadAnythingAppTest.UpdateContent_SetSelectedText + +const readAnythingApp = document.querySelector('read-anything-app').shadowRoot; +const container = readAnythingApp.getElementById('container'); +let result = true; + +function assertEquals(actual, expected) { + const isEqual = actual === expected; + if (!isEqual) { + console.error( + 'Expected: ' + JSON.stringify(expected) + ', ' + + 'Actual: ' + JSON.stringify(actual)); + } + result = result && isEqual; + return isEqual; +} + +function assertContainerInnerHTML(expected) { + const actual = container.innerHTML; + assertEquals(actual, expected); +} + +function setOnSelectionChangeForTest() { + // This is called by readAnythingApp onselectionchange. It is usually + // implemented by ReadAnythingAppController which forwards these arguments + // to the browser process in the form of an AXEventNotificationDetail. + // Instead, we capture the arguments here and verify their values. Since + // onselectionchange is called asynchronously, the test must wait for this + // function to be called; therefore we fire a custom event + // on-selection-change-for-text here for the test to await. + chrome.readAnything.onSelectionChange = function( + anchorNodeId, anchorOffset, focusNodeId, focusOffset) { + readAnythingApp.dispatchEvent( + new CustomEvent('on-selection-change-for-test', { + detail: { + anchorNodeId: anchorNodeId, + anchorOffset: anchorOffset, + focusNodeId: focusNodeId, + focusOffset: focusOffset, + }, + })); + }; +} + +// root htmlTag='#document' id=1 +// ++staticText name='Hello' id=2 +// ++staticText name='World' id=3 +// ++staticText name='Friend' id=4 +const axTree = { + rootId: 1, + nodes: [ + { + id: 1, + role: 'rootWebArea', + htmlTag: '#document', + childIds: [2, 3, 4], + }, + { + id: 2, + role: 'staticText', + name: 'Hello', + }, + { + id: 3, + role: 'staticText', + name: 'World', + }, + { + id: 4, + role: 'staticText', + name: 'Friend', + }, + ], +}; +setOnSelectionChangeForTest(); +chrome.readAnything.setContentForTesting(axTree, [1]); +const expected = '<div>HelloWorldFriend</div>'; +assertContainerInnerHTML(expected); + +// When the selection is set, readAnythingApp listens for the selection +// change event and calls chrome.readAnything.onSelectionChange. This test +// overrides that method and fires a custom event +// 'on-selection-change-for-test' with the parameters to onSelectionChange +// stored in details. Here, we check the values of the parameters of +// onSelectionChange. +readAnythingApp.addEventListener( + 'on-selection-change-for-test', function(onSelectionChangeEvent) { + assertEquals(onSelectionChangeEvent.detail.anchorNodeId, 2); + assertEquals(onSelectionChangeEvent.detail.anchorOffset, 1); + assertEquals(onSelectionChangeEvent.detail.focusNodeId, 4); + assertEquals(onSelectionChangeEvent.detail.focusOffset, 2); + + domAutomationController.send(result); + }); + +// Create a selection of "elloWorldFr". The anchor node has id 2 and the +// focus node has id 4. +const outerDiv = container.firstElementChild; +const range = new Range(); +range.setStart(outerDiv.firstChild, 1); +range.setEnd(outerDiv.lastChild, 2); +const selection = readAnythingApp.getSelection(); +selection.removeAllRanges(); +selection.addRange(range);
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_static_text.js b/chrome/test/data/webui/side_panel/read_anything/update_content_static_text.js new file mode 100644 index 0000000..c812c8f7 --- /dev/null +++ b/chrome/test/data/webui/side_panel/read_anything/update_content_static_text.js
@@ -0,0 +1,56 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// out/Debug/browser_tests \ +// --gtest_filter=ReadAnythingAppTest.UpdateContent_StaticText + +const readAnythingApp = document.querySelector('read-anything-app').shadowRoot; +const container = readAnythingApp.getElementById('container'); +let result = true; + +function assertEquals(actual, expected) { + const isEqual = actual === expected; + if (!isEqual) { + console.error( + 'Expected: ' + JSON.stringify(expected) + ', ' + + 'Actual: ' + JSON.stringify(actual)); + } + result = result && isEqual; + return isEqual; +} + +function assertContainerInnerHTML(expected) { + const actual = container.innerHTML; + assertEquals(actual, expected); +} + +// root htmlTag='#document' id=1 +// ++staticText name='This is some text.' id=2 +// ++staticText name='This is some more text.' id=3 +const axTree = { + rootId: 1, + nodes: [ + { + id: 1, + role: 'rootWebArea', + htmlTag: '#document', + childIds: [2, 3], + }, + { + id: 2, + role: 'staticText', + name: 'This is some text.', + }, + { + id: 3, + role: 'staticText', + name: 'This is some more text.', + }, + ], +}; +chrome.readAnything.setContentForTesting(axTree, [2, 3]); +const expected = '<div>This is some text.This is some more text.</div>'; +assertContainerInnerHTML(expected); + +domAutomationController.send(result);
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_static_text_bad_input.js b/chrome/test/data/webui/side_panel/read_anything/update_content_static_text_bad_input.js new file mode 100644 index 0000000..89413ecf --- /dev/null +++ b/chrome/test/data/webui/side_panel/read_anything/update_content_static_text_bad_input.js
@@ -0,0 +1,49 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// out/Debug/browser_tests \ +// --gtest_filter=ReadAnythingAppTest.UpdateContent_StaticText_BadInput + +const readAnythingApp = document.querySelector('read-anything-app').shadowRoot; +const container = readAnythingApp.getElementById('container'); +let result = true; + +function assertEquals(actual, expected) { + const isEqual = actual === expected; + if (!isEqual) { + console.error( + 'Expected: ' + JSON.stringify(expected) + ', ' + + 'Actual: ' + JSON.stringify(actual)); + } + result = result && isEqual; + return isEqual; +} + +function assertContainerInnerHTML(expected) { + const actual = container.innerHTML; + assertEquals(actual, expected); +} + +// root htmlTag='#document' id=1 +// ++staticText name='' id=2 +const axTree = { + rootId: 1, + nodes: [ + { + id: 1, + role: 'rootWebArea', + htmlTag: '#document', + childIds: [2], + }, + { + id: 2, + role: 'staticText', + }, + ], +}; +chrome.readAnything.setContentForTesting(axTree, [2]); +const expected = ''; +assertContainerInnerHTML(expected); + +domAutomationController.send(result);
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_text_direction.js b/chrome/test/data/webui/side_panel/read_anything/update_content_text_direction.js new file mode 100644 index 0000000..95ad650d --- /dev/null +++ b/chrome/test/data/webui/side_panel/read_anything/update_content_text_direction.js
@@ -0,0 +1,73 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// out/Debug/browser_tests \ +// --gtest_filter=ReadAnythingAppTest.UpdateContent_TextDirection + +const readAnythingApp = document.querySelector('read-anything-app').shadowRoot; +const container = readAnythingApp.getElementById('container'); +let result = true; + +function assertEquals(actual, expected) { + const isEqual = actual === expected; + if (!isEqual) { + console.error( + 'Expected: ' + JSON.stringify(expected) + ', ' + + 'Actual: ' + JSON.stringify(actual)); + } + result = result && isEqual; + return isEqual; +} + +function assertContainerInnerHTML(expected) { + const actual = container.innerHTML; + assertEquals(actual, expected); +} + +// root htmlTag='#document' id=1 +// ++paragraph htmlTag='p' id=2 direction='ltr' +// ++++staticText name='This is left to right writing' id=3 +// ++paragraph htmlTag='p' id=4 direction='rtl' +// ++++staticText name='This is right to left writing' id=4 +const axTree = { + rootId: 1, + nodes: [ + { + id: 1, + role: 'rootWebArea', + htmlTag: '#document', + childIds: [2, 4], + }, + { + id: 2, + role: 'paragraph', + htmlTag: 'p', + direction: 1, + childIds: [3], + }, + { + id: 3, + role: 'staticText', + name: 'This is left to right writing', + }, + { + id: 4, + role: 'paragraph', + htmlTag: 'p', + direction: 2, + childIds: [5], + }, + { + id: 5, + role: 'staticText', + name: 'This is right to left writing', + }, + ], +}; +chrome.readAnything.setContentForTesting(axTree, [2, 4]); +const expected = '<div><p dir="ltr">This is left to right writing</p>' + + '<p dir="rtl">This is right to left writing</p></div>'; +assertContainerInnerHTML(expected); + +domAutomationController.send(result);
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_text_direction_parent_node_diff_dir.js b/chrome/test/data/webui/side_panel/read_anything/update_content_text_direction_parent_node_diff_dir.js new file mode 100644 index 0000000..23b1eee --- /dev/null +++ b/chrome/test/data/webui/side_panel/read_anything/update_content_text_direction_parent_node_diff_dir.js
@@ -0,0 +1,76 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// out/Debug/browser_tests \ +// --gtest_filter=ReadAnythingAppTest.\ +// UpdateContent_TextDirection_ParentNodeDiffDir + +const readAnythingApp = document.querySelector('read-anything-app').shadowRoot; +const container = readAnythingApp.getElementById('container'); +let result = true; + +function assertEquals(actual, expected) { + const isEqual = actual === expected; + if (!isEqual) { + console.error( + 'Expected: ' + JSON.stringify(expected) + ', ' + + 'Actual: ' + JSON.stringify(actual)); + } + result = result && isEqual; + return isEqual; +} + +function assertContainerInnerHTML(expected) { + const actual = container.innerHTML; + assertEquals(actual, expected); +} + +// root htmlTag='#document' id=1 +// ++paragraph htmlTag='p' id=2 direction='ltr' +// ++++staticText name='This is ltr' id=3 +// ++++link htmlTag='a' url='http://www.google.com/' id=4 direction='rtl' +// ++++++staticText name='This link is rtl' id=5 +const axTree = { + rootId: 1, + nodes: [ + { + id: 1, + role: 'rootWebArea', + htmlTag: '#document', + childIds: [2], + }, + { + id: 2, + role: 'paragraph', + htmlTag: 'p', + direction: 1, + childIds: [3, 4], + }, + { + id: 3, + role: 'staticText', + name: 'This is ltr', + }, + { + id: 4, + role: 'link', + htmlTag: 'a', + direction: 2, + url: 'http://www.google.com/', + childIds: [5], + }, + { + id: 5, + role: 'staticText', + name: 'This link is rtl', + }, + ], +}; +chrome.readAnything.setContentForTesting(axTree, [2]); +const expected = '<div><p dir="ltr">This is ltr' + + '<a dir="rtl" href="http://www.google.com/">' + + 'This link is rtl</a></p></div>'; +assertContainerInnerHTML(expected); + +domAutomationController.send(result);
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_text_direction_vertical_dir.js b/chrome/test/data/webui/side_panel/read_anything/update_content_text_direction_vertical_dir.js new file mode 100644 index 0000000..6393691 --- /dev/null +++ b/chrome/test/data/webui/side_panel/read_anything/update_content_text_direction_vertical_dir.js
@@ -0,0 +1,73 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// out/Debug/browser_tests \ +// --gtest_filter=ReadAnythingAppTest.UpdateContent_TextDirection_VerticalDir + +const readAnythingApp = document.querySelector('read-anything-app').shadowRoot; +const container = readAnythingApp.getElementById('container'); +let result = true; + +function assertEquals(actual, expected) { + const isEqual = actual === expected; + if (!isEqual) { + console.error( + 'Expected: ' + JSON.stringify(expected) + ', ' + + 'Actual: ' + JSON.stringify(actual)); + } + result = result && isEqual; + return isEqual; +} + +function assertContainerInnerHTML(expected) { + const actual = container.innerHTML; + assertEquals(actual, expected); +} + +// root htmlTag='#document' id=1 +// ++paragraph htmlTag='p' id=2 direction='ttb' +// ++++staticText name='This should be auto' id=3 +// ++paragraph htmlTag='p' id=4 direction='btt' +// ++++staticText name='This should be also be auto' id=4 +const axTree = { + rootId: 1, + nodes: [ + { + id: 1, + role: 'rootWebArea', + htmlTag: '#document', + childIds: [2, 4], + }, + { + id: 2, + role: 'paragraph', + htmlTag: 'p', + direction: 3, + childIds: [3], + }, + { + id: 3, + role: 'staticText', + name: 'This should be auto', + }, + { + id: 4, + role: 'paragraph', + htmlTag: 'p', + direction: 4, + childIds: [5], + }, + { + id: 5, + role: 'staticText', + name: 'This should be also be auto', + }, + ], +}; +chrome.readAnything.setContentForTesting(axTree, [2, 4]); +const expected = '<div><p dir="auto">This should be auto</p>' + + '<p dir="auto">This should be also be auto</p></div>'; +assertContainerInnerHTML(expected); + +domAutomationController.send(result);
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_text_style_bold.js b/chrome/test/data/webui/side_panel/read_anything/update_content_text_style_bold.js new file mode 100644 index 0000000..62d7f9e --- /dev/null +++ b/chrome/test/data/webui/side_panel/read_anything/update_content_text_style_bold.js
@@ -0,0 +1,86 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// out/Debug/browser_tests \ +// --gtest_filter=ReadAnythingAppTest.UpdateContent_TextStyle_Bold + +const readAnythingApp = document.querySelector('read-anything-app').shadowRoot; +const container = readAnythingApp.getElementById('container'); +let result = true; + +function assertEquals(actual, expected) { + const isEqual = actual === expected; + if (!isEqual) { + console.error( + 'Expected: ' + JSON.stringify(expected) + ', ' + + 'Actual: ' + JSON.stringify(actual)); + } + result = result && isEqual; + return isEqual; +} + +function assertContainerInnerHTML(expected) { + const actual = container.innerHTML; + assertEquals(actual, expected); +} + +// root htmlTag='#document' id=1 +// ++paragraph htmlTag='p' id=2 +// ++++staticText name='Regular text.' id=3 +// ++++staticText name='This should be bolded.' textStyle='underline' id=4 +// ++paragraph htmlTag='p' id=5 +// ++++staticText name='Bolded text.' textStyle='italic' id=6 +// ++++staticText name='Bolded text.' textStyle='bold' id=7 +const axTree = { + rootId: 1, + nodes: [ + { + id: 1, + role: 'rootWebArea', + htmlTag: '#document', + childIds: [2, 5], + }, + { + id: 2, + role: 'paragraph', + htmlTag: 'p', + childIds: [3, 4], + }, + { + id: 3, + role: 'staticText', + name: 'Regular text.', + }, + { + id: 4, + role: 'staticText', + textStyle: 'underline', + name: 'This should be bolded.', + }, + { + id: 5, + role: 'paragraph', + htmlTag: 'p', + childIds: [6, 7], + }, + { + id: 6, + role: 'staticText', + textStyle: 'italic', + name: 'Bolded text.', + }, + { + id: 7, + role: 'staticText', + textStyle: 'bold', + name: 'Bolded text.', + }, + ], +}; +chrome.readAnything.setContentForTesting(axTree, [2, 5]); +const expected = '<div><p>Regular text.<b>This should be bolded.</b></p>' + + '<p><b>Bolded text.</b><b>Bolded text.</b></p></div>'; +assertContainerInnerHTML(expected); + +domAutomationController.send(result);
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_text_style_overline.js b/chrome/test/data/webui/side_panel/read_anything/update_content_text_style_overline.js new file mode 100644 index 0000000..83a2069b --- /dev/null +++ b/chrome/test/data/webui/side_panel/read_anything/update_content_text_style_overline.js
@@ -0,0 +1,74 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// out/Debug/browser_tests \ +// --gtest_filter=ReadAnythingAppTest.UpdateContent_TextStyle_Overline + +const readAnythingApp = document.querySelector('read-anything-app').shadowRoot; +const container = readAnythingApp.getElementById('container'); +let result = true; + +function assertEquals(actual, expected) { + const isEqual = actual === expected; + if (!isEqual) { + console.error( + 'Expected: ' + JSON.stringify(expected) + ', ' + + 'Actual: ' + JSON.stringify(actual)); + } + result = result && isEqual; + return isEqual; +} + +function assertContainerInnerHTML(expected) { + const actual = container.innerHTML; + assertEquals(actual, expected); +} + +// root htmlTag='#document' id=1 +// ++paragraph htmlTag='p' id=2 +// ++++staticText name='This should be overlined.' textStyle='overline' id=3 +// ++++staticText name='Regular text.' id=4 +// ++++staticText name='This is overlined and bolded.' textStyle='overline +// underline'id=5 +const axTree = { + rootId: 1, + nodes: [ + { + id: 1, + role: 'rootWebArea', + htmlTag: '#document', + childIds: [2], + }, + { + id: 2, + role: 'paragraph', + htmlTag: 'p', + childIds: [3, 4, 5], + }, + { + id: 3, + role: 'staticText', + textStyle: 'overline', + name: 'This should be overlined.', + }, + { + id: 4, + role: 'staticText', + name: 'Regular text.', + }, + { + id: 5, + role: 'staticText', + textStyle: 'overline underline', + name: 'This is overlined and bolded.', + }, + ], +}; +chrome.readAnything.setContentForTesting(axTree, [2]); +const expected = '<div><p><span style="text-decoration: overline;">This ' + + 'should be overlined.</span>Regular text.<b style="text-decoration: ' + + 'overline;">This is overlined and bolded.</b></p></div>'; +assertContainerInnerHTML(expected); + +domAutomationController.send(result);
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_theme_background_color.js b/chrome/test/data/webui/side_panel/read_anything/update_theme_background_color.js new file mode 100644 index 0000000..b50487c --- /dev/null +++ b/chrome/test/data/webui/side_panel/read_anything/update_theme_background_color.js
@@ -0,0 +1,21 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// out/Debug/browser_tests \ +// --gtest_filter=ReadAnythingAppTest.UpdateTheme_BackgroundColor + +const readAnythingApp = document.querySelector('read-anything-app').shadowRoot; +const container = readAnythingApp.getElementById('container'); + +chrome.readAnything.setThemeForTesting( + 'f', 1, 0, /* SkColorSetRGB(0xFD, 0xE2, 0x93) = */ 4294828691, 1, 0); +const expected = 'rgb(253, 226, 147)'; // #FDE293 +const actual = getComputedStyle(container).backgroundColor; +const isEqual = actual === expected; +if (!isEqual) { + console.error( + 'Expected: ' + JSON.stringify(expected) + ', ' + + 'Actual: ' + JSON.stringify(actual)); +} +domAutomationController.send(isEqual);
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_theme_font_name.js b/chrome/test/data/webui/side_panel/read_anything/update_theme_font_name.js new file mode 100644 index 0000000..32047586 --- /dev/null +++ b/chrome/test/data/webui/side_panel/read_anything/update_theme_font_name.js
@@ -0,0 +1,45 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// out/Debug/browser_tests \ +// --gtest_filter=ReadAnythingAppTest.UpdateTheme_FontName + +const readAnythingApp = document.querySelector('read-anything-app').shadowRoot; +const container = readAnythingApp.getElementById('container'); +let result = true; + +function assertEquals(actual, expected) { + const isEqual = actual === expected; + if (!isEqual) { + console.error( + 'Expected: ' + JSON.stringify(expected) + ', ' + + 'Actual: ' + JSON.stringify(actual)); + } + result = result && isEqual; + return isEqual; +} + +function assertFontName(expected) { + assertEquals(expected, getComputedStyle(container).fontFamily); +} + +chrome.readAnything.setThemeForTesting('Standard font', 18.0, 0, 0, 1, 0); +assertFontName('"Standard font"'); + +chrome.readAnything.setThemeForTesting('Sans-serif', 18.0, 0, 0, 1, 0); +assertFontName('sans-serif'); + +chrome.readAnything.setThemeForTesting('Serif', 18.0, 0, 0, 1, 0); +assertFontName('serif'); + +chrome.readAnything.setThemeForTesting('Arial', 18.0, 0, 0, 1, 0); +assertFontName('Arial'); + +chrome.readAnything.setThemeForTesting('Comic Sans MS', 18.0, 0, 0, 1, 0); +assertFontName('"Comic Sans MS"'); + +chrome.readAnything.setThemeForTesting('Times New Roman', 18.0, 0, 0, 1, 0); +assertFontName('"Times New Roman"'); + +domAutomationController.send(result);
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_theme_font_size.js b/chrome/test/data/webui/side_panel/read_anything/update_theme_font_size.js new file mode 100644 index 0000000..513a941c --- /dev/null +++ b/chrome/test/data/webui/side_panel/read_anything/update_theme_font_size.js
@@ -0,0 +1,20 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// out/Debug/browser_tests \ +// --gtest_filter=ReadAnythingAppTest.UpdateTheme_FontSize + +const readAnythingApp = document.querySelector('read-anything-app').shadowRoot; +const container = readAnythingApp.getElementById('container'); + +chrome.readAnything.setThemeForTesting('Standard font', 1.0, 0, 0, 1, 0); +const expected = '16px'; // 1em = 16px +const actual = getComputedStyle(container).fontSize; +const isEqual = actual === expected; +if (!isEqual) { + console.error( + 'Expected: ' + JSON.stringify(expected) + ', ' + + 'Actual: ' + JSON.stringify(actual)); +} +domAutomationController.send(isEqual);
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_theme_foreground_color.js b/chrome/test/data/webui/side_panel/read_anything/update_theme_foreground_color.js new file mode 100644 index 0000000..f2f1979 --- /dev/null +++ b/chrome/test/data/webui/side_panel/read_anything/update_theme_foreground_color.js
@@ -0,0 +1,21 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// out/Debug/browser_tests \ +// --gtest_filter=ReadAnythingAppTest.UpdateTheme_ForegroundColor + +const readAnythingApp = document.querySelector('read-anything-app').shadowRoot; +const container = readAnythingApp.getElementById('container'); + +chrome.readAnything.setThemeForTesting( + 'f', 1, /* SkColorSetRGB(0x33, 0x36, 0x39) = */ 4281546297, 0, 1, 0); +const expected = 'rgb(51, 54, 57)'; // #333639 +const actual = getComputedStyle(container).color; +const isEqual = actual === expected; +if (!isEqual) { + console.error( + 'Expected: ' + JSON.stringify(expected) + ', ' + + 'Actual: ' + JSON.stringify(actual)); +} +domAutomationController.send(isEqual);
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_theme_letter_spacing.js b/chrome/test/data/webui/side_panel/read_anything/update_theme_letter_spacing.js new file mode 100644 index 0000000..c8abecb --- /dev/null +++ b/chrome/test/data/webui/side_panel/read_anything/update_theme_letter_spacing.js
@@ -0,0 +1,21 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// out/Debug/browser_tests \ +// --gtest_filter=ReadAnythingAppTest.UpdateTheme_LetterSpacing + +const readAnythingApp = document.querySelector('read-anything-app').shadowRoot; +const container = readAnythingApp.getElementById('container'); + +chrome.readAnything.setThemeForTesting('f', 1, 0, 0, 1, 3); +// Very loose letter letter spacing = 0.1em, font size = 1em = 16px +const expected = '1.6px'; +const actual = getComputedStyle(container).letterSpacing; +const isEqual = actual === expected; +if (!isEqual) { + console.error( + 'Expected: ' + JSON.stringify(expected) + ', ' + + 'Actual: ' + JSON.stringify(actual)); +} +domAutomationController.send(isEqual);
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_theme_line_spacing.js b/chrome/test/data/webui/side_panel/read_anything/update_theme_line_spacing.js new file mode 100644 index 0000000..cd8991c5 --- /dev/null +++ b/chrome/test/data/webui/side_panel/read_anything/update_theme_line_spacing.js
@@ -0,0 +1,20 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// out/Debug/browser_tests \ +// --gtest_filter=ReadAnythingAppTest.UpdateTheme_LineSpacing + +const readAnythingApp = document.querySelector('read-anything-app').shadowRoot; +const container = readAnythingApp.getElementById('container'); + +chrome.readAnything.setThemeForTesting('Standard font', 1.0, 0, 0, 2, 0); +const expected = '24px'; // 1.5 times the 1em (16px) font size +const actual = getComputedStyle(container).lineHeight; +const isEqual = actual === expected; +if (!isEqual) { + console.error( + 'Expected: ' + JSON.stringify(expected) + ', ' + + 'Actual: ' + JSON.stringify(actual)); +} +domAutomationController.send(isEqual);
diff --git a/chrome/updater/app/server/win/com_classes_legacy.cc b/chrome/updater/app/server/win/com_classes_legacy.cc index f562990..7aa163b 100644 --- a/chrome/updater/app/server/win/com_classes_legacy.cc +++ b/chrome/updater/app/server/win/com_classes_legacy.cc
@@ -852,7 +852,7 @@ const std::wstring& command_id) { app_command_runner_ = AppCommandRunner::LoadAppCommand(scope, app_id, command_id); - return app_command_runner_.has_value() ? S_OK : app_command_runner_.error(); + return app_command_runner_.error_or(S_OK); } STDMETHODIMP LegacyAppCommandWebImpl::get_status(UINT* status) {
diff --git a/chrome/updater/util/win_util.cc b/chrome/updater/util/win_util.cc index 70df8c7..794fdb2e 100644 --- a/chrome/updater/util/win_util.cc +++ b/chrome/updater/util/win_util.cc
@@ -61,6 +61,7 @@ #include "chrome/updater/win/scoped_handle.h" #include "chrome/updater/win/user_info.h" #include "chrome/updater/win/win_constants.h" +#include "third_party/abseil-cpp/absl/cleanup/cleanup.h" #include "third_party/abseil-cpp/absl/types/optional.h" namespace updater { @@ -437,8 +438,7 @@ &administrators_group)) { return base::unexpected(HRESULTFromLastError()); } - base::ScopedClosureRunner free_sid( - base::BindOnce([](PSID sid) { ::FreeSid(sid); }, administrators_group)); + absl::Cleanup free_sid = [&] { ::FreeSid(administrators_group); }; BOOL is_member = false; if (!::CheckTokenMembership(token, administrators_group, &is_member)) return base::unexpected(HRESULTFromLastError()); @@ -482,9 +482,7 @@ return base::unexpected(hr); } - base::ScopedClosureRunner co_revert_to_self( - base::BindOnce([]() { ::CoRevertToSelf(); })); - + absl::Cleanup co_revert_to_self = [] { ::CoRevertToSelf(); }; if (!::OpenThreadToken(::GetCurrentThread(), TOKEN_QUERY, TRUE, ScopedKernelHANDLE::Receiver(token).get())) { hr = HRESULTFromLastError(); @@ -507,18 +505,13 @@ // The presence of a split token definitively indicates that UAC is on. But // the absence of the token does not necessarily indicate that UAC is off. HResultOr<bool> is_split_token = IsUserRunningSplitToken(); - if (is_split_token.has_value() && is_split_token.value()) - return true; - - return IsExplorerRunningAtMediumOrLower(); + return (is_split_token.has_value() && is_split_token.value()) || + IsExplorerRunningAtMediumOrLower(); } bool IsElevatedWithUACOn() { HResultOr<bool> is_user_admin = IsUserAdmin(); - if (is_user_admin.has_value() && !is_user_admin.value()) - return false; - - return IsUACOn(); + return (!is_user_admin.has_value() || is_user_admin.value()) && IsUACOn(); } std::string GetUACState() { @@ -529,13 +522,13 @@ base::StringAppendF(&s, "IsUserAdmin: %d, ", is_user_admin.value()); HResultOr<bool> is_user_non_elevated_admin = IsUserNonElevatedAdmin(); - if (is_user_non_elevated_admin.has_value()) + if (is_user_non_elevated_admin.has_value()) { base::StringAppendF(&s, "IsUserNonElevatedAdmin: %d, ", is_user_non_elevated_admin.value()); + } - base::StringAppendF(&s, "IsUACOn: %d, ", IsUACOn()); - base::StringAppendF(&s, "IsElevatedWithUACOn: %d", IsElevatedWithUACOn()); - + base::StringAppendF(&s, "IsUACOn: %d, IsElevatedWithUACOn: %d", IsUACOn(), + IsElevatedWithUACOn()); return s; } @@ -567,12 +560,11 @@ CHECK(!file_path.empty()); const HWND hwnd = CreateForegroundParentWindowForUAC(); - const base::ScopedClosureRunner destroy_window(base::BindOnce( - [](HWND hwnd) { - if (hwnd) - ::DestroyWindow(hwnd); - }, - hwnd)); + const absl::Cleanup destroy_window = [&] { + if (hwnd) { + ::DestroyWindow(hwnd); + } + }; SHELLEXECUTEINFO shell_execute_info = {}; shell_execute_info.cbSize = sizeof(SHELLEXECUTEINFO); @@ -859,9 +851,8 @@ base::ScopedTempDir temp_dir_owner; if (temp_dir_owner.Set(temp_dir)) { return temp_dir_owner; - } else { - return absl::nullopt; } + return absl::nullopt; } base::ScopedClosureRunner SignalShutdownEvent(UpdaterScope scope) {
diff --git a/chrome/updater/win/app_command_runner.cc b/chrome/updater/win/app_command_runner.cc index 4eaff18..bedacea 100644 --- a/chrome/updater/win/app_command_runner.cc +++ b/chrome/updater/win/app_command_runner.cc
@@ -8,6 +8,7 @@ #include <windows.h> #include <string> +#include <utility> #include <vector> #include "base/base_paths_win.h" @@ -181,7 +182,7 @@ HResultOr<AppCommandRunner> runner = LoadAppCommand(scope, app_id, it.Name()); if (runner.has_value()) { - app_command_runners.push_back(*runner); + app_command_runners.push_back(*std::move(runner)); } }
diff --git a/chrome/updater/win/installer/installer.cc b/chrome/updater/win/installer/installer.cc index 7e8a407..69abcf7 100644 --- a/chrome/updater/win/installer/installer.cc +++ b/chrome/updater/win/installer/installer.cc
@@ -284,12 +284,10 @@ // The metainstaller is elevated because unpacking its files and running // updater.exe must happen from a secure directory. - HResultOr<DWORD> result = - RunElevated(command_line.GetProgram(), [&command_line]() { - base::CommandLine elevate_command_line = command_line; - elevate_command_line.AppendSwitchASCII(kCmdLineExpectElevated, {}); - return elevate_command_line.GetArgumentsString(); - }()); + base::CommandLine elevated_command_line = command_line; + elevated_command_line.AppendSwitchASCII(kCmdLineExpectElevated, {}); + HResultOr<DWORD> result = RunElevated( + command_line.GetProgram(), elevated_command_line.GetArgumentsString()); return result.has_value() ? ProcessExitResult(result.value())
diff --git a/chromecast/media/audio/mixer_service/receiver/cma_backend_shim.cc b/chromecast/media/audio/mixer_service/receiver/cma_backend_shim.cc index 2ec2519c..39c7690 100644 --- a/chromecast/media/audio/mixer_service/receiver/cma_backend_shim.cc +++ b/chromecast/media/audio/mixer_service/receiver/cma_backend_shim.cc
@@ -7,7 +7,6 @@ #include <algorithm> #include <utility> -#include "base/cxx17_backports.h" #include "base/functional/bind.h" #include "base/functional/callback_helpers.h" #include "base/location.h" @@ -173,7 +172,7 @@ } void CmaBackendShim::SetVolumeMultiplier(float multiplier) { - multiplier = base::clamp(multiplier, 0.0f, 1.0f); + multiplier = std::clamp(multiplier, 0.0f, 1.0f); POST_MEDIA_TASK(&CmaBackendShim::SetVolumeMultiplierOnMediaThread, multiplier); }
diff --git a/chromecast/media/audio/rate_adjuster.cc b/chromecast/media/audio/rate_adjuster.cc index 4e64be33..df5e523 100644 --- a/chromecast/media/audio/rate_adjuster.cc +++ b/chromecast/media/audio/rate_adjuster.cc
@@ -4,11 +4,11 @@ #include "chromecast/media/audio/rate_adjuster.h" +#include <algorithm> #include <cmath> #include <utility> #include "base/check.h" -#include "base/cxx17_backports.h" namespace chromecast { namespace media { @@ -104,8 +104,8 @@ offset_correction = offset_correction / 4; } offset_correction = - base::clamp(offset_correction, -config_.max_current_error_correction, - config_.max_current_error_correction); + std::clamp(offset_correction, -config_.max_current_error_correction, + config_.max_current_error_correction); double new_rate = (1.0 + slope) + offset_correction; // Only change the clock rate if the difference between the desired rate and
diff --git a/chromecast/media/base/slew_volume.cc b/chromecast/media/base/slew_volume.cc index 23ad05e4..8eb023e 100644 --- a/chromecast/media/base/slew_volume.cc +++ b/chromecast/media/base/slew_volume.cc
@@ -9,7 +9,6 @@ #include <cstring> #include "base/check_op.h" -#include "base/cxx17_backports.h" #include "media/base/vector_math.h" namespace { @@ -185,7 +184,7 @@ for (; slew_frames > 0; --slew_frames) { slew_cos_ -= slew_sin_ * slew_angle_; slew_sin_ += slew_cos_ * slew_angle_; - current_volume_ = base::clamp(slew_offset_ + slew_cos_, 0.0, 1.0); + current_volume_ = std::clamp(slew_offset_ + slew_cos_, 0.0, 1.0); for (int i = 0; i < channels; ++i) { Traits::ProcessSingleDatum(src, current_volume_, dest); ++src;
diff --git a/chromecast/media/cma/backend/alsa/alsa_volume_control.cc b/chromecast/media/cma/backend/alsa/alsa_volume_control.cc index 1239afb..4b91fc61 100644 --- a/chromecast/media/cma/backend/alsa/alsa_volume_control.cc +++ b/chromecast/media/cma/backend/alsa/alsa_volume_control.cc
@@ -4,11 +4,11 @@ #include "chromecast/media/cma/backend/alsa/alsa_volume_control.h" +#include <algorithm> #include <utility> #include "base/check.h" #include "base/command_line.h" -#include "base/cxx17_backports.h" #include "base/location.h" #include "base/logging.h" #include "base/strings/string_split.h" @@ -223,7 +223,7 @@ } long level = 0; // NOLINT(runtime/int) - level = std::round((base::clamp(volume, 0.0f, 1.0f) * + level = std::round((std::clamp(volume, 0.0f, 1.0f) * (volume_range_max_ - volume_range_min_)) + volume_range_min_); return static_cast<float>(level - volume_range_min_) /
diff --git a/chromecast/media/cma/backend/android/audio_sink_android_audiotrack_impl.cc b/chromecast/media/cma/backend/android/audio_sink_android_audiotrack_impl.cc index 5fe7b69..b97d534 100644 --- a/chromecast/media/cma/backend/android/audio_sink_android_audiotrack_impl.cc +++ b/chromecast/media/cma/backend/android/audio_sink_android_audiotrack_impl.cc
@@ -8,7 +8,6 @@ #include <string> #include <vector> -#include "base/cxx17_backports.h" #include "base/functional/bind.h" #include "base/functional/callback_helpers.h" #include "base/logging.h" @@ -431,7 +430,7 @@ float multiplier) { RUN_ON_FEEDER_THREAD(SetLimiterVolumeMultiplier, multiplier); - limiter_volume_multiplier_ = base::clamp(multiplier, 0.0f, 1.0f); + limiter_volume_multiplier_ = std::clamp(multiplier, 0.0f, 1.0f); LOG(INFO) << __func__ << "(" << this << "): device_id_=" << device_id_ << " limiter_multiplier=" << limiter_volume_multiplier_ << " effective=" << EffectiveVolume();
diff --git a/chromecast/media/cma/backend/android/volume_control_android.cc b/chromecast/media/cma/backend/android/volume_control_android.cc index 7a34bda..bc48bf8 100644 --- a/chromecast/media/cma/backend/android/volume_control_android.cc +++ b/chromecast/media/cma/backend/android/volume_control_android.cc
@@ -13,7 +13,6 @@ #include "base/android/build_info.h" #include "base/android/jni_android.h" -#include "base/cxx17_backports.h" #include "base/files/file_util.h" #include "base/functional/bind.h" #include "base/functional/callback_helpers.h" @@ -93,7 +92,7 @@ return; } - level = base::clamp(level, 0.0f, 1.0f); + level = std::clamp(level, 0.0f, 1.0f); // The input level value is in the kMedia (MUSIC) volume table domain. float mapped_level = MapIntoDifferentVolumeTableDomain(AudioContentType::kMedia, type, level); @@ -129,7 +128,7 @@ } // The input limit is in the kMedia (MUSIC) volume table domain. - limit = base::clamp(limit, 0.0f, 1.0f); + limit = std::clamp(limit, 0.0f, 1.0f); float limit_db = VolumeToDbFSCached(AudioContentType::kMedia, limit); AudioSinkManager::Get()->SetOutputLimitDb(type, limit_db); }
diff --git a/chromecast/media/cma/backend/cplay/cplay.cc b/chromecast/media/cma/backend/cplay/cplay.cc index b1d18e60..60173fb 100644 --- a/chromecast/media/cma/backend/cplay/cplay.cc +++ b/chromecast/media/cma/backend/cplay/cplay.cc
@@ -13,7 +13,6 @@ #include <string> #include <vector> -#include "base/cxx17_backports.h" #include "base/files/file.h" #include "base/files/file_path.h" #include "base/files/file_util.h" @@ -204,7 +203,7 @@ clipped_data.size() * sizeof(clipped_data[0])); if (saturate_output) { for (size_t i = 0; i < clipped_data.size(); ++i) { - clipped_data[i] = base::clamp(clipped_data[i], -1.0f, 1.0f); + clipped_data[i] = std::clamp(clipped_data[i], -1.0f, 1.0f); } } wav_file_.WriteAtCurrentPos(reinterpret_cast<char*>(clipped_data.data()),
diff --git a/chromecast/media/cma/backend/desktop/volume_control_desktop.cc b/chromecast/media/cma/backend/desktop/volume_control_desktop.cc index 66b6a78c3..c7e00d7 100644 --- a/chromecast/media/cma/backend/desktop/volume_control_desktop.cc +++ b/chromecast/media/cma/backend/desktop/volume_control_desktop.cc
@@ -10,7 +10,6 @@ #include <vector> #include "base/check.h" -#include "base/cxx17_backports.h" #include "base/functional/bind.h" #include "base/functional/callback_helpers.h" #include "base/location.h" @@ -73,7 +72,7 @@ return; } - level = base::clamp(level, 0.0f, 1.0f); + level = std::clamp(level, 0.0f, 1.0f); thread_.task_runner()->PostTask( FROM_HERE, base::BindOnce(&VolumeControlInternal::SetVolumeOnThread, base::Unretained(this), source, type, level)); @@ -206,13 +205,13 @@ // static float VolumeControl::VolumeToDbFS(float volume) { - volume = base::clamp(volume, 0.0f, 1.0f); + volume = std::clamp(volume, 0.0f, 1.0f); return kMinVolumeDbfs + volume * (kMaxVolumeDbfs - kMinVolumeDbfs); } // static float VolumeControl::DbFSToVolume(float db) { - db = base::clamp(db, kMinVolumeDbfs, kMaxVolumeDbfs); + db = std::clamp(db, kMinVolumeDbfs, kMaxVolumeDbfs); return (db - kMinVolumeDbfs) / (kMaxVolumeDbfs - kMinVolumeDbfs); }
diff --git a/chromecast/media/cma/backend/mixer/audio_output_redirector.cc b/chromecast/media/cma/backend/mixer/audio_output_redirector.cc index 7fea6e9..9cba5a3 100644 --- a/chromecast/media/cma/backend/mixer/audio_output_redirector.cc +++ b/chromecast/media/cma/backend/mixer/audio_output_redirector.cc
@@ -8,7 +8,6 @@ #include <limits> #include <utility> -#include "base/cxx17_backports.h" #include "base/functional/bind.h" #include "base/location.h" #include "base/logging.h" @@ -462,7 +461,7 @@ // Hard limit to [1.0, -1.0]. for (int s = 0; s < config_.num_output_channels * next_num_frames_; ++s) { - current_mix_data_[s] = base::clamp(current_mix_data_[s], -1.0f, 1.0f); + current_mix_data_[s] = std::clamp(current_mix_data_[s], -1.0f, 1.0f); } io_task_runner_->PostTask(
diff --git a/chromecast/media/cma/backend/mixer/filter_group.cc b/chromecast/media/cma/backend/mixer/filter_group.cc index 92c71c1..8ff33d4 100644 --- a/chromecast/media/cma/backend/mixer/filter_group.cc +++ b/chromecast/media/cma/backend/mixer/filter_group.cc
@@ -6,7 +6,6 @@ #include <algorithm> -#include "base/cxx17_backports.h" #include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/strings/string_number_conversions.h" @@ -35,10 +34,10 @@ *min = 0.0f; *max = 1.0f; if (min_value) { - *min = base::clamp(static_cast<float>(min_value.value()), 0.0f, 1.0f); + *min = std::clamp(static_cast<float>(min_value.value()), 0.0f, 1.0f); } if (max_value) { - *max = base::clamp(static_cast<float>(max_value.value()), *min, 1.0f); + *max = std::clamp(static_cast<float>(max_value.value()), *min, 1.0f); } return true; }
diff --git a/chromecast/media/cma/backend/mixer/mixer_input.cc b/chromecast/media/cma/backend/mixer/mixer_input.cc index 05dca35a..ac93676 100644 --- a/chromecast/media/cma/backend/mixer/mixer_input.cc +++ b/chromecast/media/cma/backend/mixer/mixer_input.cc
@@ -10,7 +10,6 @@ #include <cmath> #include <utility> -#include "base/cxx17_backports.h" #include "base/functional/bind.h" #include "base/functional/callback_helpers.h" #include "base/logging.h" @@ -500,13 +499,13 @@ float MixerInput::TargetVolume() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); float output_volume = stream_volume_multiplier_ * type_volume_multiplier_; - float clamped_volume = base::clamp(output_volume, volume_min_, volume_max_); + float clamped_volume = std::clamp(output_volume, volume_min_, volume_max_); float limited_volume = std::min(clamped_volume, output_volume_limit_); float muted_volume = limited_volume * mute_volume_multiplier_; // Volume is clamped after all gains have been multiplied, to avoid clipping. // TODO(kmackay): Consider removing this clamp and use a postprocessor filter // to avoid clipping instead. - return base::clamp(muted_volume, 0.0f, 1.0f); + return std::clamp(muted_volume, 0.0f, 1.0f); } float MixerInput::InstantaneousVolume() {
diff --git a/chromecast/media/cma/backend/mixer/mixer_input_connection.cc b/chromecast/media/cma/backend/mixer/mixer_input_connection.cc index 2400911..341b19c 100644 --- a/chromecast/media/cma/backend/mixer/mixer_input_connection.cc +++ b/chromecast/media/cma/backend/mixer/mixer_input_connection.cc
@@ -12,7 +12,6 @@ #include <utility> #include "base/command_line.h" -#include "base/cxx17_backports.h" #include "base/functional/bind.h" #include "base/location.h" #include "base/logging.h" @@ -1196,8 +1195,8 @@ input_samples_per_second_); const int64_t error = - base::clamp(playout_time - desired_playout_time, -kTimestampErrorLimit, - kTimestampErrorLimit); + std::clamp(playout_time - desired_playout_time, -kTimestampErrorLimit, + kTimestampErrorLimit); if (error < -max_timestamp_error_ || (after_silence && error < -1e6 / (input_samples_per_second_ * playback_rate_))) {
diff --git a/chromecast/media/cma/backend/mixer/stream_mixer.cc b/chromecast/media/cma/backend/mixer/stream_mixer.cc index 38eb2c0..77a0aad 100644 --- a/chromecast/media/cma/backend/mixer/stream_mixer.cc +++ b/chromecast/media/cma/backend/mixer/stream_mixer.cc
@@ -13,7 +13,6 @@ #include <utility> #include "base/compiler_specific.h" -#include "base/cxx17_backports.h" #include "base/functional/bind.h" #include "base/functional/callback_helpers.h" #include "base/json/json_reader.h" @@ -921,7 +920,7 @@ // Hard limit to [1.0, -1.0] for (int i = 0; i < frames * loopback_channel_count; ++i) { // TODO(bshaya): Warn about clipping here. - loopback_data[i] = base::clamp(loopback_data[i], -1.0f, 1.0f); + loopback_data[i] = std::clamp(loopback_data[i], -1.0f, 1.0f); } loopback_handler_->SendData(expected_playback_time, @@ -933,7 +932,7 @@ // Hard limit to [1.0, -1.0]. for (int i = 0; i < frames * num_output_channels_; ++i) { - linearized_data[i] = base::clamp(linearized_data[i], -1.0f, 1.0f); + linearized_data[i] = std::clamp(linearized_data[i], -1.0f, 1.0f); } bool playback_interrupted = false;
diff --git a/chromecast/media/cma/backend/mixer/stream_mixer_unittest.cc b/chromecast/media/cma/backend/mixer/stream_mixer_unittest.cc index cbd5b53..cae9fa7 100644 --- a/chromecast/media/cma/backend/mixer/stream_mixer_unittest.cc +++ b/chromecast/media/cma/backend/mixer/stream_mixer_unittest.cc
@@ -2,12 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <algorithm> #include <cmath> #include <limits> #include <memory> #include <utility> -#include "base/cxx17_backports.h" #include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/ranges/algorithm.h" @@ -298,7 +298,7 @@ } } - *result = base::clamp(*result, -1.0f, 1.0f); + *result = std::clamp(*result, -1.0f, 1.0f); } } return mixed;
diff --git a/chromecast/media/cma/backend/volume_control.cc b/chromecast/media/cma/backend/volume_control.cc index 00e8eaa..53d781c 100644 --- a/chromecast/media/cma/backend/volume_control.cc +++ b/chromecast/media/cma/backend/volume_control.cc
@@ -12,7 +12,6 @@ #include <vector> #include "base/containers/flat_map.h" -#include "base/cxx17_backports.h" #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/files/important_file_writer.h" @@ -131,7 +130,7 @@ return; } - level = base::clamp(level, 0.0f, 1.0f); + level = std::clamp(level, 0.0f, 1.0f); thread_.task_runner()->PostTask( FROM_HERE, base::BindOnce(&VolumeControlInternal::SetVolumeOnThread, base::Unretained(this), source, type, level, @@ -333,7 +332,7 @@ } #if !BUILDFLAG(SYSTEM_OWNS_VOLUME) - limit = base::clamp(limit, 0.0f, 1.0f); + limit = std::clamp(limit, 0.0f, 1.0f); mixer_->SetVolumeLimit(type, DbFsToScale(VolumeControl::VolumeToDbFS(limit)));
diff --git a/chromecast/ui/display_settings/brightness_animation.cc b/chromecast/ui/display_settings/brightness_animation.cc index 50ba193b..9c302337 100644 --- a/chromecast/ui/display_settings/brightness_animation.cc +++ b/chromecast/ui/display_settings/brightness_animation.cc
@@ -4,9 +4,9 @@ #include "chromecast/ui/display_settings/brightness_animation.h" +#include <algorithm> #include <limits> -#include "base/cxx17_backports.h" #include "base/logging.h" #include "base/time/time.h" @@ -42,7 +42,7 @@ void BrightnessAnimation::AnimateToNewValue(float new_target_brightness, base::TimeDelta duration) { start_brightness_ = controller_->GetDisplayBrightness(); - target_brightness_ = base::clamp(new_target_brightness, 0.0f, 1.0f); + target_brightness_ = std::clamp(new_target_brightness, 0.0f, 1.0f); DVLOG(4) << "Animating to new_target_brightness " << new_target_brightness << " from current_brightness_=" << current_brightness_; @@ -60,7 +60,7 @@ } void BrightnessAnimation::AnimateToState(double state) { - state = base::clamp(state, 0.0, 1.0); + state = std::clamp(state, 0.0, 1.0); current_brightness_ = start_brightness_ + (target_brightness_ - start_brightness_) * state; ApplyValuesToDisplay();
diff --git a/chromecast/ui/display_settings/color_temperature_animation.cc b/chromecast/ui/display_settings/color_temperature_animation.cc index a02c215..c63e566 100644 --- a/chromecast/ui/display_settings/color_temperature_animation.cc +++ b/chromecast/ui/display_settings/color_temperature_animation.cc
@@ -4,10 +4,10 @@ #include "chromecast/ui/display_settings/color_temperature_animation.h" +#include <algorithm> #include <limits> #include <vector> -#include "base/cxx17_backports.h" #include "base/time/time.h" #include "ui/compositor/scoped_animation_duration_scale_mode.h" @@ -55,7 +55,7 @@ void ColorTemperatureAnimation::AnimateToNewValue(float new_target_temperature, base::TimeDelta duration) { start_temperature_ = current_temperature_; - target_temperature_ = base::clamp(new_target_temperature, 1000.0f, 20000.0f); + target_temperature_ = std::clamp(new_target_temperature, 1000.0f, 20000.0f); if (ui::ScopedAnimationDurationScaleMode::duration_multiplier() == ui::ScopedAnimationDurationScaleMode::ZERO_DURATION) { @@ -77,7 +77,7 @@ } void ColorTemperatureAnimation::AnimateToState(double state) { - state = base::clamp(state, 0.0, 1.0); + state = std::clamp(state, 0.0, 1.0); current_temperature_ = start_temperature_ + (target_temperature_ - start_temperature_) * state; ApplyValuesToDisplay(); @@ -86,8 +86,8 @@ void ColorTemperatureAnimation::ApplyValuesToDisplay() { // Clamp temperature value to table range. float kelvin = - base::clamp(current_temperature_, config_.temperature_values.front(), - config_.temperature_values.back()); + std::clamp(current_temperature_, config_.temperature_values.front(), + config_.temperature_values.back()); size_t i = 0; // Find greatest index whose value is <= |kelvin|. This is safe since |kelvin| // is clamped to fall within the table range.
diff --git a/chromeos/ash/components/dbus/hermes/fake_hermes_euicc_client.cc b/chromeos/ash/components/dbus/hermes/fake_hermes_euicc_client.cc index 1e2a9a5..e5291f5 100644 --- a/chromeos/ash/components/dbus/hermes/fake_hermes_euicc_client.cc +++ b/chromeos/ash/components/dbus/hermes/fake_hermes_euicc_client.cc
@@ -330,7 +330,7 @@ const std::string& activation_code, bool restore_slot, RefreshSmdxProfilesCallback callback) { - DCHECK(ash::features::IsSmdsSupportEnabled()); + DCHECK(ash::features::IsSmdsDbusMigrationEnabled()); last_restore_slot_arg_ = restore_slot; base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask( FROM_HERE, @@ -504,7 +504,7 @@ const std::string& activation_code, RefreshSmdxProfilesCallback callback) { // Use CHECK() here since the only caller has a DCHECK(). - CHECK(ash::features::IsSmdsSupportEnabled()); + CHECK(ash::features::IsSmdsDbusMigrationEnabled()); DVLOG(1) << "Refresh SM-DX Profiles Requested";
diff --git a/chromeos/ash/components/dbus/hermes/hermes_euicc_client_unittest.cc b/chromeos/ash/components/dbus/hermes/hermes_euicc_client_unittest.cc index 508706d..1b273b0 100644 --- a/chromeos/ash/components/dbus/hermes/hermes_euicc_client_unittest.cc +++ b/chromeos/ash/components/dbus/hermes/hermes_euicc_client_unittest.cc
@@ -349,8 +349,7 @@ TEST_F(HermesEuiccClientTest, TestRefreshSmdxProfiles) { base::test::ScopedFeatureList feature_list; - feature_list.InitWithFeatures( - {{ash::features::kSmdsSupport, ash::features::kSmdsDbusMigration}}, {{}}); + feature_list.InitAndEnableFeature(ash::features::kSmdsDbusMigration); dbus::ObjectPath test_euicc_path(kTestEuiccPath); dbus::MethodCall method_call(hermes::kHermesEuiccInterface,
diff --git a/chromeos/ash/components/install_attributes/install_attributes.h b/chromeos/ash/components/install_attributes/install_attributes.h index 25888bd..22a496cb 100644 --- a/chromeos/ash/components/install_attributes/install_attributes.h +++ b/chromeos/ash/components/install_attributes/install_attributes.h
@@ -107,6 +107,10 @@ bool IsCloudManaged() const; // Checks whether this is an Active Directory managed enterprise device. + // In theory, this can still yield true for a few left-over AD devices. + // However, starting in M114, it is considered safe to assume that this + // function always returns false. + // TODO(b/279364186) Remove. bool IsActiveDirectoryManaged() const; // Checks whether this is a consumer kiosk enabled device.
diff --git a/chromeos/ash/services/cellular_setup/BUILD.gn b/chromeos/ash/services/cellular_setup/BUILD.gn index 287e39c2..0a0c4a5 100644 --- a/chromeos/ash/services/cellular_setup/BUILD.gn +++ b/chromeos/ash/services/cellular_setup/BUILD.gn
@@ -19,6 +19,7 @@ ] deps = [ + "//ash/constants", "//base", "//chromeos/ash/components/dbus/shill", "//chromeos/ash/components/network", @@ -113,6 +114,7 @@ ":cellular_setup", ":esim_manager", ":test_support", + "//ash/constants", "//base", "//base/test:test_support", "//chromeos/ash/components/dbus/hermes",
diff --git a/chromeos/ash/services/cellular_setup/esim_profile.cc b/chromeos/ash/services/cellular_setup/esim_profile.cc index 30f3a47..864c9c5 100644 --- a/chromeos/ash/services/cellular_setup/esim_profile.cc +++ b/chromeos/ash/services/cellular_setup/esim_profile.cc
@@ -272,11 +272,21 @@ weak_ptr_factory_.GetWeakPtr(), std::move(callback)), std::move(inhibit_lock)); } else { - HermesEuiccClient::Get()->RequestPendingProfiles( - euicc_->path(), /*root_smds=*/ESimManager::GetRootSmdsAddress(), - base::BindOnce(&ESimProfile::OnRequestPendingProfiles, - weak_ptr_factory_.GetWeakPtr(), std::move(callback), - std::move(inhibit_lock))); + if (ash::features::IsSmdsDbusMigrationEnabled()) { + HermesEuiccClient::Get()->RefreshSmdxProfiles( + euicc_->path(), + /*activation_code=*/ESimManager::GetRootSmdsAddress(), + /*restore_slot=*/true, + base::BindOnce(&ESimProfile::OnRefreshSmdxProfiles, + weak_ptr_factory_.GetWeakPtr(), std::move(callback), + std::move(inhibit_lock))); + } else { + HermesEuiccClient::Get()->RequestPendingProfiles( + euicc_->path(), /*root_smds=*/ESimManager::GetRootSmdsAddress(), + base::BindOnce(&ESimProfile::OnRequestPendingProfiles, + weak_ptr_factory_.GetWeakPtr(), std::move(callback), + std::move(inhibit_lock))); + } } return; } @@ -296,6 +306,21 @@ OnRequestProfiles(std::move(callback), std::move(inhibit_lock), success); } +void ESimProfile::OnRefreshSmdxProfiles( + EnsureProfileExistsOnEuiccCallback callback, + std::unique_ptr<CellularInhibitor::InhibitLock> inhibit_lock, + HermesResponseStatus status, + const std::vector<dbus::ObjectPath>& profile_paths) { + NET_LOG(EVENT) << "Refresh SM-DX profiles found " << profile_paths.size() + << " available profiles"; + bool success = status == HermesResponseStatus::kSuccess; + if (!success) { + NET_LOG(ERROR) << "Error refreshing SM-DX profiles to ensure profile " + << "exists on Euicc; status: " << status; + } + OnRequestProfiles(std::move(callback), std::move(inhibit_lock), success); +} + void ESimProfile::OnRequestPendingProfiles( EnsureProfileExistsOnEuiccCallback callback, std::unique_ptr<CellularInhibitor::InhibitLock> inhibit_lock,
diff --git a/chromeos/ash/services/cellular_setup/esim_profile.h b/chromeos/ash/services/cellular_setup/esim_profile.h index fbf47c7..09da5e1 100644 --- a/chromeos/ash/services/cellular_setup/esim_profile.h +++ b/chromeos/ash/services/cellular_setup/esim_profile.h
@@ -76,6 +76,11 @@ void OnRequestInstalledProfiles( EnsureProfileExistsOnEuiccCallback callback, std::unique_ptr<CellularInhibitor::InhibitLock> inhibit_lock); + void OnRefreshSmdxProfiles( + EnsureProfileExistsOnEuiccCallback callback, + std::unique_ptr<CellularInhibitor::InhibitLock> inhibit_lock, + HermesResponseStatus status, + const std::vector<dbus::ObjectPath>& profile_paths); void OnRequestPendingProfiles( EnsureProfileExistsOnEuiccCallback callback, std::unique_ptr<CellularInhibitor::InhibitLock> inhibit_lock,
diff --git a/chromeos/ash/services/cellular_setup/esim_profile_unittest.cc b/chromeos/ash/services/cellular_setup/esim_profile_unittest.cc index 2c13dd5..e14b2c4 100644 --- a/chromeos/ash/services/cellular_setup/esim_profile_unittest.cc +++ b/chromeos/ash/services/cellular_setup/esim_profile_unittest.cc
@@ -4,9 +4,11 @@ #include <string> +#include "ash/constants/ash_features.h" #include "base/strings/utf_string_conversions.h" #include "base/test/bind.h" #include "base/test/metrics/histogram_tester.h" +#include "base/test/scoped_feature_list.h" #include "chromeos/ash/components/dbus/hermes/hermes_euicc_client.h" #include "chromeos/ash/components/dbus/hermes/hermes_profile_client.h" #include "chromeos/ash/components/network/fake_network_connection_handler.h" @@ -83,7 +85,13 @@ class ESimProfileTest : public ESimTestBase { public: - ESimProfileTest() = default; + explicit ESimProfileTest(bool enable_dbus_migration) { + if (enable_dbus_migration) { + feature_list_.InitAndEnableFeature(ash::features::kSmdsDbusMigration); + } else { + feature_list_.InitAndDisableFeature(ash::features::kSmdsDbusMigration); + } + } ESimProfileTest(const ESimProfileTest&) = delete; ESimProfileTest& operator=(const ESimProfileTest&) = delete; @@ -162,10 +170,39 @@ } private: + base::test::ScopedFeatureList feature_list_; std::unique_ptr<TestUserManager> test_user_manager_; }; -TEST_F(ESimProfileTest, GetProperties) { +class ESimProfileTest_DBusMigrationDisabled : public ESimProfileTest { + public: + ESimProfileTest_DBusMigrationDisabled( + const ESimProfileTest_DBusMigrationDisabled&) = delete; + ESimProfileTest_DBusMigrationDisabled& operator=( + const ESimProfileTest_DBusMigrationDisabled&) = delete; + + protected: + ESimProfileTest_DBusMigrationDisabled() + : ESimProfileTest( + /*enable_dbus_migration=*/false) {} + ~ESimProfileTest_DBusMigrationDisabled() override = default; +}; + +class ESimProfileTest_DBusMigrationEnabled : public ESimProfileTest { + public: + ESimProfileTest_DBusMigrationEnabled( + const ESimProfileTest_DBusMigrationEnabled&) = delete; + ESimProfileTest_DBusMigrationEnabled& operator=( + const ESimProfileTest_DBusMigrationEnabled&) = delete; + + protected: + ESimProfileTest_DBusMigrationEnabled() + : ESimProfileTest( + /*enable_dbus_migration=*/true) {} + ~ESimProfileTest_DBusMigrationEnabled() override = default; +}; + +TEST_F(ESimProfileTest_DBusMigrationDisabled, GetProperties) { SetIsGuest(false); HermesEuiccClient::TestInterface* euicc_test = @@ -187,7 +224,7 @@ EXPECT_EQ(dbus_properties->iccid().value(), mojo_properties->iccid); } -TEST_F(ESimProfileTest, InstallProfile) { +TEST_F(ESimProfileTest_DBusMigrationDisabled, InstallProfile) { SetIsGuest(false); base::HistogramTester histogram_tester; @@ -243,7 +280,7 @@ /*expected_count=*/1); } -TEST_F(ESimProfileTest, InstallProfileAlreadyConnected) { +TEST_F(ESimProfileTest_DBusMigrationDisabled, InstallProfileAlreadyConnected) { SetIsGuest(false); dbus::ObjectPath profile_path = @@ -267,7 +304,7 @@ EXPECT_EQ(mojom::ProfileInstallResult::kSuccess, install_result); } -TEST_F(ESimProfileTest, InstallConnectFailure) { +TEST_F(ESimProfileTest_DBusMigrationDisabled, InstallConnectFailure) { SetIsGuest(false); HermesEuiccClient::TestInterface* euicc_test = @@ -290,7 +327,7 @@ EXPECT_EQ(mojom::ProfileInstallResult::kSuccess, install_result); } -TEST_F(ESimProfileTest, UninstallProfile) { +TEST_F(ESimProfileTest_DBusMigrationDisabled, UninstallProfile) { SetIsGuest(false); base::HistogramTester histogram_tester; @@ -362,7 +399,7 @@ true, 1); } -TEST_F(ESimProfileTest, CannotUninstallProfileAsGuest) { +TEST_F(ESimProfileTest_DBusMigrationDisabled, CannotUninstallProfileAsGuest) { SetIsGuest(true); HermesEuiccClient::TestInterface* euicc_test = @@ -381,7 +418,7 @@ EXPECT_EQ(mojom::ESimOperationResult::kFailure, result); } -TEST_F(ESimProfileTest, SetProfileNickName) { +TEST_F(ESimProfileTest_DBusMigrationDisabled, SetProfileNickName) { SetIsGuest(false); const std::u16string test_nickname = u"Test nickname"; @@ -432,7 +469,294 @@ EXPECT_EQ(test_nickname, active_profile_mojo_properties->nickname); } -TEST_F(ESimProfileTest, CannotSetProfileNickNameAsGuest) { +TEST_F(ESimProfileTest_DBusMigrationDisabled, CannotSetProfileNickNameAsGuest) { + SetIsGuest(true); + + HermesEuiccClient::TestInterface* euicc_test = + HermesEuiccClient::Get()->GetTestInterface(); + dbus::ObjectPath active_profile_path = euicc_test->AddFakeCarrierProfile( + dbus::ObjectPath(kTestEuiccPath), hermes::profile::State::kActive, "", + HermesEuiccClient::TestInterface::AddCarrierProfileBehavior:: + kAddProfileWithService); + HermesProfileClient::Properties* active_profile_dbus_properties = + HermesProfileClient::Get()->GetProperties(active_profile_path); + mojo::Remote<mojom::ESimProfile> active_esim_profile = GetESimProfileForIccid( + ESimTestBase::kTestEid, active_profile_dbus_properties->iccid().value()); + + mojom::ESimOperationResult result = + SetProfileNickname(active_esim_profile, u"Nickname"); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(mojom::ESimOperationResult::kFailure, result); +} + +TEST_F(ESimProfileTest_DBusMigrationEnabled, GetProperties) { + SetIsGuest(false); + + HermesEuiccClient::TestInterface* euicc_test = + HermesEuiccClient::Get()->GetTestInterface(); + dbus::ObjectPath profile_path = euicc_test->AddFakeCarrierProfile( + dbus::ObjectPath(ESimTestBase::kTestEuiccPath), + hermes::profile::State::kPending, "", + HermesEuiccClient::TestInterface::AddCarrierProfileBehavior:: + kAddProfileWithService); + base::RunLoop().RunUntilIdle(); + HermesProfileClient::Properties* dbus_properties = + HermesProfileClient::Get()->GetProperties(profile_path); + + mojo::Remote<mojom::ESimProfile> esim_profile = GetESimProfileForIccid( + ESimTestBase::kTestEid, dbus_properties->iccid().value()); + ASSERT_TRUE(esim_profile.is_bound()); + mojom::ESimProfilePropertiesPtr mojo_properties = + GetESimProfileProperties(esim_profile); + EXPECT_EQ(dbus_properties->iccid().value(), mojo_properties->iccid); +} + +TEST_F(ESimProfileTest_DBusMigrationEnabled, InstallProfile) { + SetIsGuest(false); + base::HistogramTester histogram_tester; + + HermesEuiccClient::TestInterface* euicc_test = + HermesEuiccClient::Get()->GetTestInterface(); + dbus::ObjectPath profile_path = euicc_test->AddFakeCarrierProfile( + dbus::ObjectPath(ESimTestBase::kTestEuiccPath), + hermes::profile::State::kPending, "", + HermesEuiccClient::TestInterface::AddCarrierProfileBehavior:: + kAddProfileWithService); + base::RunLoop().RunUntilIdle(); + HermesProfileClient::Properties* dbus_properties = + HermesProfileClient::Get()->GetProperties(profile_path); + + // Verify that install errors return error code properly. + euicc_test->QueueHermesErrorStatus( + HermesResponseStatus::kErrorNeedConfirmationCode); + mojo::Remote<mojom::ESimProfile> esim_profile = GetESimProfileForIccid( + ESimTestBase::kTestEid, dbus_properties->iccid().value()); + ASSERT_TRUE(esim_profile.is_bound()); + mojom::ProfileInstallResult install_result = InstallProfile( + esim_profile, /*wait_for_connect=*/false, /*fail_connect=*/false); + EXPECT_EQ(mojom::ProfileInstallResult::kErrorNeedsConfirmationCode, + install_result); + + histogram_tester.ExpectTotalCount(kPendingProfileLatencyHistogram, 0); + histogram_tester.ExpectBucketCount( + kPendingProfileInstallHistogram, + HermesResponseStatus::kErrorNeedConfirmationCode, + /*expected_count=*/1); + + // Adding a pending profile causes a list change. + EXPECT_EQ(1u, observer()->profile_list_change_calls().size()); + + // Verify that installing pending profile returns proper results + // and updates esim_profile properties. + install_result = InstallProfile(esim_profile, /*wait_for_connect=*/true, + /*fail_connect=*/false); + // Wait for property changes to propagate. + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(mojom::ProfileInstallResult::kSuccess, install_result); + mojom::ESimProfilePropertiesPtr mojo_properties = + GetESimProfileProperties(esim_profile); + EXPECT_EQ(dbus_properties->iccid().value(), mojo_properties->iccid); + EXPECT_NE(mojo_properties->state, mojom::ProfileState::kPending); + + // Installing a profile causes a list change. + EXPECT_EQ(2u, observer()->profile_list_change_calls().size()); + + histogram_tester.ExpectTotalCount(kPendingProfileLatencyHistogram, 1); + histogram_tester.ExpectBucketCount(kPendingProfileInstallHistogram, + HermesResponseStatus::kSuccess, + /*expected_count=*/1); +} + +TEST_F(ESimProfileTest_DBusMigrationEnabled, InstallProfileAlreadyConnected) { + SetIsGuest(false); + + dbus::ObjectPath profile_path = + HermesEuiccClient::Get()->GetTestInterface()->AddFakeCarrierProfile( + dbus::ObjectPath(ESimTestBase::kTestEuiccPath), + hermes::profile::State::kPending, /*activation_code=*/std::string(), + HermesEuiccClient::TestInterface::AddCarrierProfileBehavior:: + kAddProfileWithService); + HermesProfileClient::Properties* dbus_properties = + HermesProfileClient::Get()->GetProperties(profile_path); + mojo::Remote<mojom::ESimProfile> esim_profile = GetESimProfileForIccid( + ESimTestBase::kTestEid, dbus_properties->iccid().value()); + + HermesProfileClient::Get()->GetTestInterface()->SetEnableProfileBehavior( + HermesProfileClient::TestInterface::EnableProfileBehavior:: + kConnectableAndConnected); + + mojom::ProfileInstallResult install_result = + InstallProfile(esim_profile, /*wait_for_connect=*/false, + /*fail_connect=*/false); + EXPECT_EQ(mojom::ProfileInstallResult::kSuccess, install_result); +} + +TEST_F(ESimProfileTest_DBusMigrationEnabled, InstallConnectFailure) { + SetIsGuest(false); + + HermesEuiccClient::TestInterface* euicc_test = + HermesEuiccClient::Get()->GetTestInterface(); + dbus::ObjectPath profile_path = euicc_test->AddFakeCarrierProfile( + dbus::ObjectPath(ESimTestBase::kTestEuiccPath), + hermes::profile::State::kPending, "", + HermesEuiccClient::TestInterface::AddCarrierProfileBehavior:: + kAddProfileWithService); + base::RunLoop().RunUntilIdle(); + HermesProfileClient::Properties* dbus_properties = + HermesProfileClient::Get()->GetProperties(profile_path); + mojo::Remote<mojom::ESimProfile> esim_profile = GetESimProfileForIccid( + ESimTestBase::kTestEid, dbus_properties->iccid().value()); + + // Verify that connect failures still return success code. + mojom::ProfileInstallResult install_result = + InstallProfile(esim_profile, /*wait_for_connect=*/true, + /*fail_connect=*/true); + EXPECT_EQ(mojom::ProfileInstallResult::kSuccess, install_result); +} + +TEST_F(ESimProfileTest_DBusMigrationEnabled, UninstallProfile) { + SetIsGuest(false); + + base::HistogramTester histogram_tester; + + HermesEuiccClient::TestInterface* euicc_test = + HermesEuiccClient::Get()->GetTestInterface(); + dbus::ObjectPath active_profile_path = euicc_test->AddFakeCarrierProfile( + dbus::ObjectPath(kTestEuiccPath), hermes::profile::State::kActive, "", + HermesEuiccClient::TestInterface::AddCarrierProfileBehavior:: + kAddProfileWithService); + dbus::ObjectPath pending_profile_path = euicc_test->AddFakeCarrierProfile( + dbus::ObjectPath(kTestEuiccPath), hermes::profile::State::kPending, "", + HermesEuiccClient::TestInterface::AddCarrierProfileBehavior:: + kAddProfileWithService); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(1u, observer()->profile_list_change_calls().size()); + observer()->Reset(); + HermesProfileClient::Properties* pending_profile_dbus_properties = + HermesProfileClient::Get()->GetProperties(pending_profile_path); + HermesProfileClient::Properties* active_profile_dbus_properties = + HermesProfileClient::Get()->GetProperties(active_profile_path); + histogram_tester.ExpectTotalCount(kProfileUninstallationResultHistogram, 0); + + // Verify that uninstall error codes are returned properly. + euicc_test->QueueHermesErrorStatus( + HermesResponseStatus::kErrorInvalidResponse); + mojo::Remote<mojom::ESimProfile> active_esim_profile = GetESimProfileForIccid( + ESimTestBase::kTestEid, active_profile_dbus_properties->iccid().value()); + ASSERT_TRUE(active_esim_profile.is_bound()); + mojom::ESimOperationResult result = UninstallProfile(active_esim_profile); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(mojom::ESimOperationResult::kFailure, result); + EXPECT_EQ(0u, observer()->profile_list_change_calls().size()); + histogram_tester.ExpectTotalCount(kProfileUninstallationResultHistogram, 1); + histogram_tester.ExpectBucketCount(kProfileUninstallationResultHistogram, + false, 1); + + // Verify that pending profiles cannot be uninstalled + observer()->Reset(); + mojo::Remote<mojom::ESimProfile> pending_esim_profile = + GetESimProfileForIccid(ESimTestBase::kTestEid, + pending_profile_dbus_properties->iccid().value()); + ASSERT_TRUE(pending_esim_profile.is_bound()); + result = UninstallProfile(pending_esim_profile); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(mojom::ESimOperationResult::kFailure, result); + EXPECT_EQ(0u, observer()->profile_list_change_calls().size()); + histogram_tester.ExpectTotalCount(kProfileUninstallationResultHistogram, 1); + histogram_tester.ExpectBucketCount(kProfileUninstallationResultHistogram, + false, 1); + + // Verify that uninstall removes the profile and notifies observers properly. + observer()->Reset(); + result = UninstallProfile(active_esim_profile); + + // The state change of the ESim profile from kActive to kInactive causes a + // list change observer event. + ASSERT_EQ(1u, observer()->profile_list_change_calls().size()); + + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(mojom::ESimOperationResult::kSuccess, result); + + // The removal of the ESim profile causes a list change observer event. + ASSERT_EQ(2u, observer()->profile_list_change_calls().size()); + + EXPECT_EQ(1u, GetProfileList(GetEuiccForEid(ESimTestBase::kTestEid)).size()); + histogram_tester.ExpectTotalCount(kProfileUninstallationResultHistogram, 2); + histogram_tester.ExpectBucketCount(kProfileUninstallationResultHistogram, + true, 1); +} + +TEST_F(ESimProfileTest_DBusMigrationEnabled, CannotUninstallProfileAsGuest) { + SetIsGuest(true); + + HermesEuiccClient::TestInterface* euicc_test = + HermesEuiccClient::Get()->GetTestInterface(); + dbus::ObjectPath active_profile_path = euicc_test->AddFakeCarrierProfile( + dbus::ObjectPath(kTestEuiccPath), hermes::profile::State::kActive, "", + HermesEuiccClient::TestInterface::AddCarrierProfileBehavior:: + kAddProfileWithService); + HermesProfileClient::Properties* active_profile_dbus_properties = + HermesProfileClient::Get()->GetProperties(active_profile_path); + mojo::Remote<mojom::ESimProfile> active_esim_profile = GetESimProfileForIccid( + ESimTestBase::kTestEid, active_profile_dbus_properties->iccid().value()); + + mojom::ESimOperationResult result = UninstallProfile(active_esim_profile); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(mojom::ESimOperationResult::kFailure, result); +} + +TEST_F(ESimProfileTest_DBusMigrationEnabled, SetProfileNickName) { + SetIsGuest(false); + + const std::u16string test_nickname = u"Test nickname"; + base::HistogramTester histogram_tester; + + HermesEuiccClient::TestInterface* euicc_test = + HermesEuiccClient::Get()->GetTestInterface(); + dbus::ObjectPath active_profile_path = euicc_test->AddFakeCarrierProfile( + dbus::ObjectPath(kTestEuiccPath), hermes::profile::State::kActive, "", + HermesEuiccClient::TestInterface::AddCarrierProfileBehavior:: + kAddProfileWithService); + dbus::ObjectPath pending_profile_path = euicc_test->AddFakeCarrierProfile( + dbus::ObjectPath(kTestEuiccPath), hermes::profile::State::kPending, "", + HermesEuiccClient::TestInterface::AddCarrierProfileBehavior:: + kAddProfileWithService); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(1u, observer()->profile_list_change_calls().size()); + observer()->Reset(); + HermesProfileClient::Properties* pending_profile_dbus_properties = + HermesProfileClient::Get()->GetProperties(pending_profile_path); + HermesProfileClient::Properties* active_profile_dbus_properties = + HermesProfileClient::Get()->GetProperties(active_profile_path); + + // Verify that pending profiles cannot be modified. + mojo::Remote<mojom::ESimProfile> pending_esim_profile = + GetESimProfileForIccid(ESimTestBase::kTestEid, + pending_profile_dbus_properties->iccid().value()); + ASSERT_TRUE(pending_esim_profile.is_bound()); + mojom::ESimOperationResult result = + SetProfileNickname(pending_esim_profile, test_nickname); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(mojom::ESimOperationResult::kFailure, result); + EXPECT_EQ(0u, observer()->profile_change_calls().size()); + + // Verify that nickname can be set on active profiles. + histogram_tester.ExpectTotalCount(kProfileRenameResultHistogram, 0); + mojo::Remote<mojom::ESimProfile> active_esim_profile = GetESimProfileForIccid( + ESimTestBase::kTestEid, active_profile_dbus_properties->iccid().value()); + ASSERT_TRUE(active_esim_profile.is_bound()); + result = SetProfileNickname(active_esim_profile, test_nickname); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(mojom::ESimOperationResult::kSuccess, result); + histogram_tester.ExpectTotalCount(kProfileRenameResultHistogram, 1); + histogram_tester.ExpectBucketCount(kProfileRenameResultHistogram, true, 1); + + mojom::ESimProfilePropertiesPtr active_profile_mojo_properties = + GetESimProfileProperties(active_esim_profile); + EXPECT_EQ(test_nickname, active_profile_mojo_properties->nickname); +} + +TEST_F(ESimProfileTest_DBusMigrationEnabled, CannotSetProfileNickNameAsGuest) { SetIsGuest(true); HermesEuiccClient::TestInterface* euicc_test =
diff --git a/chromeos/ash/services/cellular_setup/euicc.cc b/chromeos/ash/services/cellular_setup/euicc.cc index c3879a0..96a8dd7e 100644 --- a/chromeos/ash/services/cellular_setup/euicc.cc +++ b/chromeos/ash/services/cellular_setup/euicc.cc
@@ -7,6 +7,7 @@ #include <cstdint> #include <memory> +#include "ash/constants/ash_features.h" #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" #include "base/strings/strcat.h" @@ -265,11 +266,39 @@ } NET_LOG(EVENT) << "Requesting pending profiles"; - HermesEuiccClient::Get()->RequestPendingProfiles( - path_, /*root_smds=*/ESimManager::GetRootSmdsAddress(), - base::BindOnce(&Euicc::OnRequestPendingProfilesResult, - weak_ptr_factory_.GetWeakPtr(), std::move(callback), - std::move(inhibit_lock))); + + if (ash::features::IsSmdsDbusMigrationEnabled()) { + HermesEuiccClient::Get()->RefreshSmdxProfiles( + path_, /*activation_code=*/ESimManager::GetRootSmdsAddress(), + /*restore_slot=*/true, + base::BindOnce(&Euicc::OnRefreshSmdxProfilesResult, + weak_ptr_factory_.GetWeakPtr(), std::move(callback), + std::move(inhibit_lock))); + } else { + HermesEuiccClient::Get()->RequestPendingProfiles( + path_, /*root_smds=*/ESimManager::GetRootSmdsAddress(), + base::BindOnce(&Euicc::OnRequestPendingProfilesResult, + weak_ptr_factory_.GetWeakPtr(), std::move(callback), + std::move(inhibit_lock))); + } +} + +void Euicc::OnRefreshSmdxProfilesResult( + RequestPendingProfilesCallback callback, + std::unique_ptr<CellularInhibitor::InhibitLock> inhibit_lock, + HermesResponseStatus status, + const std::vector<dbus::ObjectPath>& profile_paths) { + NET_LOG(EVENT) << "Refresh SM-DX profiles found " << profile_paths.size() + << " available profiles"; + // TODO(crbug.com/1216693) Update with more robust way of waiting for eSIM + // profile objects to be loaded. + base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask( + FROM_HERE, + base::BindOnce(std::move(callback), + status == HermesResponseStatus::kSuccess + ? mojom::ESimOperationResult::kSuccess + : mojom::ESimOperationResult::kFailure), + kPendingProfileRefreshDelay); } void Euicc::OnRequestPendingProfilesResult(
diff --git a/chromeos/ash/services/cellular_setup/euicc.h b/chromeos/ash/services/cellular_setup/euicc.h index 9c8d6c8..d18899a 100644 --- a/chromeos/ash/services/cellular_setup/euicc.h +++ b/chromeos/ash/services/cellular_setup/euicc.h
@@ -64,7 +64,10 @@ const mojom::EuiccPropertiesPtr& properties() { return properties_; } private: - FRIEND_TEST_ALL_PREFIXES(EuiccTest, RequestPendingProfiles); + FRIEND_TEST_ALL_PREFIXES(EuiccTest, + RequestPendingProfiles_DBusMigrationDisabled); + FRIEND_TEST_ALL_PREFIXES(EuiccTest, + RequestPendingProfiles_DBusMigrationEnabled); // These values are persisted to logs. Entries should not be renumbered and // numeric values should never be reused. @@ -85,6 +88,11 @@ void PerformRequestPendingProfiles( RequestPendingProfilesCallback callback, std::unique_ptr<CellularInhibitor::InhibitLock> inhibit_lock); + void OnRefreshSmdxProfilesResult( + RequestPendingProfilesCallback callback, + std::unique_ptr<CellularInhibitor::InhibitLock> inhibit_lock, + HermesResponseStatus status, + const std::vector<dbus::ObjectPath>& profile_paths); void OnRequestPendingProfilesResult( RequestPendingProfilesCallback callback, std::unique_ptr<CellularInhibitor::InhibitLock> inhibit_lock,
diff --git a/chromeos/ash/services/cellular_setup/euicc_unittest.cc b/chromeos/ash/services/cellular_setup/euicc_unittest.cc index feb005d..9f361bfed 100644 --- a/chromeos/ash/services/cellular_setup/euicc_unittest.cc +++ b/chromeos/ash/services/cellular_setup/euicc_unittest.cc
@@ -6,9 +6,11 @@ #include <utility> +#include "ash/constants/ash_features.h" #include "base/run_loop.h" #include "base/test/bind.h" #include "base/test/metrics/histogram_tester.h" +#include "base/test/scoped_feature_list.h" #include "chromeos/ash/components/dbus/hermes/hermes_euicc_client.h" #include "chromeos/ash/components/dbus/hermes/hermes_profile_client.h" #include "chromeos/ash/components/network/fake_network_connection_handler.h" @@ -232,10 +234,13 @@ EXPECT_EQ(2u, observer()->profile_list_change_calls().size()); } -TEST_F(EuiccTest, RequestPendingProfiles) { +TEST_F(EuiccTest, RequestPendingProfiles_DBusMigrationDisabled) { static const char kOperationResultMetric[] = "Network.Cellular.ESim.RequestPendingProfiles.OperationResult"; base::HistogramTester histogram_tester; + base::test::ScopedFeatureList feature_list; + + feature_list.InitAndDisableFeature(ash::features::kSmdsDbusMigration); mojo::Remote<mojom::Euicc> euicc = GetEuiccForEid(ESimTestBase::kTestEid); ASSERT_TRUE(euicc.is_bound()); @@ -272,6 +277,30 @@ /*expected_count=*/1); } +TEST_F(EuiccTest, RequestPendingProfiles_DBusMigrationEnabled) { + base::test::ScopedFeatureList feature_list; + feature_list.InitAndEnableFeature(ash::features::kSmdsDbusMigration); + + mojo::Remote<mojom::Euicc> euicc = GetEuiccForEid(ESimTestBase::kTestEid); + ASSERT_TRUE(euicc.is_bound()); + + HermesEuiccClient::TestInterface* euicc_test = + HermesEuiccClient::Get()->GetTestInterface(); + // Verify that pending profile request errors are return properly. + euicc_test->QueueHermesErrorStatus(HermesResponseStatus::kErrorNoResponse); + EXPECT_EQ(mojom::ESimOperationResult::kFailure, + RequestPendingProfiles(euicc)); + EXPECT_EQ(0u, observer()->profile_list_change_calls().size()); + + constexpr base::TimeDelta kHermesInteractiveDelay = base::Milliseconds(3000); + HermesEuiccClient::Get()->GetTestInterface()->SetInteractiveDelay( + kHermesInteractiveDelay); + + // Verify that successful request returns correct status code. + EXPECT_EQ(mojom::ESimOperationResult::kSuccess, + RequestPendingProfiles(euicc)); +} + TEST_F(EuiccTest, GetEidQRCode) { mojo::Remote<mojom::Euicc> euicc = GetEuiccForEid(ESimTestBase::kTestEid); ASSERT_TRUE(euicc.is_bound());
diff --git a/chromeos/chromeos_strings.grd b/chromeos/chromeos_strings.grd index e5628e4c..c1ba0f6f 100644 --- a/chromeos/chromeos_strings.grd +++ b/chromeos/chromeos_strings.grd
@@ -3954,94 +3954,94 @@ <message name="IDS_SHORTCUT_CUSTOMIZATION_SUBCATEGORY_ACCESSIBILITY_NAVIGATION" desc="Subcategory named 'AccessibilityNavigation' shown within main shortcuts section"> Accessibility navigation </message> - <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_ARROW_DOWN" desc="The text read aloud by the screen reader describing the keyboard icon 'arrow down'." translateable="false"> + <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_ARROW_DOWN" desc="The text read aloud by the screen reader describing the keyboard icon 'arrow down'."> arrow down </message> - <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_ARROW_LEFT" desc="The text read aloud by the screen reader describing the keyboard icon 'arrow left'." translateable="false"> + <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_ARROW_LEFT" desc="The text read aloud by the screen reader describing the keyboard icon 'arrow left'."> arrow left </message> - <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_ARROW_RIGHT" desc="The text read aloud by the screen reader describing the keyboard icon 'arrow right'." translateable="false"> + <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_ARROW_RIGHT" desc="The text read aloud by the screen reader describing the keyboard icon 'arrow right'."> arrow right </message> - <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_ARROW_UP" desc="The text read aloud by the screen reader describing the keyboard icon 'arrow up'." translateable="false"> + <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_ARROW_UP" desc="The text read aloud by the screen reader describing the keyboard icon 'arrow up'."> arrow up </message> - <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_AUDIO_VOLUME_DOWN" desc="The text read aloud by the screen reader describing the keyboard icon 'volume down'." translateable="false"> + <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_AUDIO_VOLUME_DOWN" desc="The text read aloud by the screen reader describing the keyboard icon 'volume down'."> volume down </message> - <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_AUDIO_VOLUME_MUTE" desc="The text read aloud by the screen reader describing the keyboard icon 'volume mute'." translateable="false"> + <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_AUDIO_VOLUME_MUTE" desc="The text read aloud by the screen reader describing the keyboard icon 'volume mute'."> volume mute </message> - <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_AUDIO_VOLUME_UP" desc="The text read aloud by the screen reader describing the keyboard icon 'volume up'." translateable="false"> + <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_AUDIO_VOLUME_UP" desc="The text read aloud by the screen reader describing the keyboard icon 'volume up'."> volume up </message> - <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_BRIGHTNESS_DOWN" desc="The text read aloud by the screen reader describing the keyboard icon 'brightness down'." translateable="false"> + <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_BRIGHTNESS_DOWN" desc="The text read aloud by the screen reader describing the keyboard icon 'brightness down'."> brightness down </message> - <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_BRIGHTNESS_UP" desc="The text read aloud by the screen reader describing the keyboard icon 'brightness up'." translateable="false"> + <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_BRIGHTNESS_UP" desc="The text read aloud by the screen reader describing the keyboard icon 'brightness up'."> brightness up </message> - <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_BROWSER_BACK" desc="The text read aloud by the screen reader describing the keyboard icon 'back'." translateable="false"> + <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_BROWSER_BACK" desc="The text read aloud by the screen reader describing the keyboard icon 'back'."> back </message> <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_BROWSER_FORWARD" desc="The text read aloud by the screen reader describing the keyboard icon 'forward'." translateable="false"> forward </message> - <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_BROWSER_REFRESH" desc="The text read aloud by the screen reader describing the keyboard icon 'refresh'." translateable="false"> + <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_BROWSER_REFRESH" desc="The text read aloud by the screen reader describing the keyboard icon 'refresh'."> refresh </message> <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_BROWSER_SEARCH" desc="The text read aloud by the screen reader describing the keyboard icon 'search'." translateable="false"> search </message> - <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_TOGGLE_DICTATION" desc="The text read aloud by the screen reader describing the keyboard icon 'toggle dictation'." translateable="false"> + <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_TOGGLE_DICTATION" desc="The text read aloud by the screen reader describing the keyboard icon 'toggle dictation'."> toggle dictation </message> - <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_EMOJI_PICKER" desc="The text read aloud by the screen reader describing the keyboard icon 'emoji picker'." translateable="false"> + <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_EMOJI_PICKER" desc="The text read aloud by the screen reader describing the keyboard icon 'emoji picker'."> emoji picker </message> - <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_KEYBOARD_BACKLIGHT_TOGGLE" desc="The text read aloud by the screen reader describing the keyboard icon 'toggle keyboard backlight'." translateable="false"> + <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_KEYBOARD_BACKLIGHT_TOGGLE" desc="The text read aloud by the screen reader describing the keyboard icon 'toggle keyboard backlight'."> toggle keyboard backlight </message> - <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_KEYBOARD_BRIGHTNESS_UP" desc="The text read aloud by the screen reader describing the keyboard icon 'keyboard brightness up'." translateable="false"> + <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_KEYBOARD_BRIGHTNESS_UP" desc="The text read aloud by the screen reader describing the keyboard icon 'keyboard brightness up'."> keyboard brightness up </message> - <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_KEYBOARD_BRIGHTNESS_DOWN" desc="The text read aloud by the screen reader describing the keyboard icon 'keyboard brightness down'." translateable="false"> + <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_KEYBOARD_BRIGHTNESS_DOWN" desc="The text read aloud by the screen reader describing the keyboard icon 'keyboard brightness down'."> keyboard brightness down </message> - <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_LAUNCH_APPLICATION1" desc="The text read aloud by the screen reader describing the keyboard icon 'overview'." translateable="false"> - overview + <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_LAUNCH_APPLICATION1" desc="The text read aloud by the screen reader describing the keyboard icon 'show windows'."> + show windows </message> - <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_LAUNCH_APPLICATION2" desc="The text read aloud by the screen reader describing the keyboard icon 'open calculator'." translateable="false"> - open calculator + <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_LAUNCH_APPLICATION2" desc="The text read aloud by the screen reader describing the keyboard icon 'calculator app'."> + calculator app </message> - <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_LAUNCH_ASSISTANT" desc="The text read aloud by the screen reader describing the keyboard icon 'assistant'." translateable="false"> - assistant + <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_LAUNCH_ASSISTANT" desc="The text read aloud by the screen reader describing the keyboard icon 'Google Assistant'."> + Google Assistant </message> - <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_MEDIA_FAST_FORWARD" desc="The text read aloud by the screen reader describing the keyboard icon 'fast forward media'." translateable="false"> + <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_MEDIA_FAST_FORWARD" desc="The text read aloud by the screen reader describing the keyboard icon 'fast forward media'."> fast forward media </message> - <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_MEDIA_PAUSE" desc="The text read aloud by the screen reader describing the keyboard icon 'pause media'." translateable="false"> + <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_MEDIA_PAUSE" desc="The text read aloud by the screen reader describing the keyboard icon 'pause media'."> pause media </message> - <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_MEDIA_PLAY" desc="The text read aloud by the screen reader describing the keyboard icon 'play media'." translateable="false"> + <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_MEDIA_PLAY" desc="The text read aloud by the screen reader describing the keyboard icon 'play media'."> play media </message> - <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_MEDIA_PLAY_PAUSE" desc="The text read aloud by the screen reader describing the keyboard icon 'play pause'." translateable="false"> - play pause + <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_MEDIA_PLAY_PAUSE" desc="The text read aloud by the screen reader describing the keyboard icon 'play or pause media'."> + play or pause media </message> - <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_MEDIA_TRACK_NEXT" desc="The text read aloud by the screen reader describing the keyboard icon 'next track'." translateable="false"> + <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_MEDIA_TRACK_NEXT" desc="The text read aloud by the screen reader describing the keyboard icon 'next track'."> next track </message> - <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_MEDIA_TRACK_PREVIOUS" desc="The text read aloud by the screen reader describing the keyboard icon 'previous track'." translateable="false"> + <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_MEDIA_TRACK_PREVIOUS" desc="The text read aloud by the screen reader describing the keyboard icon 'previous track'."> previous track </message> <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_MENU" desc="The text read aloud by the screen reader describing the keyboard icon 'menu." translateable="false"> menu </message> - <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_MICROPHONE_MUTE_TOGGLE" desc="The text read aloud by the screen reader describing the keyboard icon 'toggle microphone mute'." translateable="false"> + <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_MICROPHONE_MUTE_TOGGLE" desc="The text read aloud by the screen reader describing the keyboard icon 'toggle microphone mute'."> toggle microphone mute </message> - <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_MODE_CHANGE" desc="The text read aloud by the screen reader describing the keyboard icon 'mode change'." translateable="false"> + <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_MODE_CHANGE" desc="The text read aloud by the screen reader describing the keyboard icon 'mode change'."> mode change </message> <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_OPEN_LAUNCHER" desc="The text read aloud by the screen reader describing the keyboard icon 'launcher'." translateable="false"> @@ -4050,16 +4050,16 @@ <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_POWER" desc="The text read aloud by the screen reader describing the keyboard icon 'power'." translateable="false"> power </message> - <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_PRINT_SCREEN" desc="The text read aloud by the screen reader describing the keyboard icon 'screenshot'." translateable="false"> - screenshot + <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_PRINT_SCREEN" desc="The text read aloud by the screen reader describing the keyboard icon 'take screenshot'."> + take screenshot </message> - <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_PRIVACY_SCREEN_TOGGLE" desc="The text read aloud by the screen reader describing the keyboard icon 'toggle privacy screen'." translateable="false"> + <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_PRIVACY_SCREEN_TOGGLE" desc="The text read aloud by the screen reader describing the keyboard icon 'toggle privacy screen'."> toggle privacy screen </message> - <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_SETTINGS" desc="The text read aloud by the screen reader describing the keyboard icon 'settings'." translateable="false"> + <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_SETTINGS" desc="The text read aloud by the screen reader describing the keyboard icon 'settings'."> settings </message> - <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_ZOOM_TOGGLE" desc="The text read aloud by the screen reader describing the keyboard icon 'full screen'." translateable="false"> + <message name="IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_ZOOM_TOGGLE" desc="The text read aloud by the screen reader describing the keyboard icon 'full screen'."> full screen </message> <!-- End of Shortcut Customization -->
diff --git a/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_ARROW_DOWN.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_ARROW_DOWN.png.sha1 new file mode 100644 index 0000000..4242ae3 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_ARROW_DOWN.png.sha1
@@ -0,0 +1 @@ +873f094578767d71d0f6525a7561e012f74a6e1f \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_ARROW_LEFT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_ARROW_LEFT.png.sha1 new file mode 100644 index 0000000..4242ae3 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_ARROW_LEFT.png.sha1
@@ -0,0 +1 @@ +873f094578767d71d0f6525a7561e012f74a6e1f \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_ARROW_RIGHT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_ARROW_RIGHT.png.sha1 new file mode 100644 index 0000000..4242ae3 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_ARROW_RIGHT.png.sha1
@@ -0,0 +1 @@ +873f094578767d71d0f6525a7561e012f74a6e1f \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_ARROW_UP.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_ARROW_UP.png.sha1 new file mode 100644 index 0000000..4242ae3 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_ARROW_UP.png.sha1
@@ -0,0 +1 @@ +873f094578767d71d0f6525a7561e012f74a6e1f \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_AUDIO_VOLUME_DOWN.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_AUDIO_VOLUME_DOWN.png.sha1 new file mode 100644 index 0000000..2210f1e3 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_AUDIO_VOLUME_DOWN.png.sha1
@@ -0,0 +1 @@ +1fef844ff76039d3308b126d70a46f949183b6cc \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_AUDIO_VOLUME_MUTE.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_AUDIO_VOLUME_MUTE.png.sha1 new file mode 100644 index 0000000..2210f1e3 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_AUDIO_VOLUME_MUTE.png.sha1
@@ -0,0 +1 @@ +1fef844ff76039d3308b126d70a46f949183b6cc \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_AUDIO_VOLUME_UP.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_AUDIO_VOLUME_UP.png.sha1 new file mode 100644 index 0000000..2210f1e3 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_AUDIO_VOLUME_UP.png.sha1
@@ -0,0 +1 @@ +1fef844ff76039d3308b126d70a46f949183b6cc \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_BRIGHTNESS_DOWN.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_BRIGHTNESS_DOWN.png.sha1 new file mode 100644 index 0000000..44e0483 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_BRIGHTNESS_DOWN.png.sha1
@@ -0,0 +1 @@ +77a9ac0d2d6da74a7a14c1845f74f4a312b36b9b \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_BRIGHTNESS_UP.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_BRIGHTNESS_UP.png.sha1 new file mode 100644 index 0000000..44e0483 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_BRIGHTNESS_UP.png.sha1
@@ -0,0 +1 @@ +77a9ac0d2d6da74a7a14c1845f74f4a312b36b9b \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_BROWSER_BACK.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_BROWSER_BACK.png.sha1 new file mode 100644 index 0000000..b2d98679 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_BROWSER_BACK.png.sha1
@@ -0,0 +1 @@ +bd16de91bb5de5a6f4cdbf5864972ed66b379ab1 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_BROWSER_REFRESH.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_BROWSER_REFRESH.png.sha1 new file mode 100644 index 0000000..75c5f8d6 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_BROWSER_REFRESH.png.sha1
@@ -0,0 +1 @@ +795b7bfa7fa6910321a192f2fdff87f0f30b8cb9 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_EMOJI_PICKER.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_EMOJI_PICKER.png.sha1 new file mode 100644 index 0000000..251a0a7 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_EMOJI_PICKER.png.sha1
@@ -0,0 +1 @@ +1a240e4f9ca0b8857da3a521426e7fac0972ca12 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_KEYBOARD_BACKLIGHT_TOGGLE.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_KEYBOARD_BACKLIGHT_TOGGLE.png.sha1 new file mode 100644 index 0000000..44e0483 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_KEYBOARD_BACKLIGHT_TOGGLE.png.sha1
@@ -0,0 +1 @@ +77a9ac0d2d6da74a7a14c1845f74f4a312b36b9b \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_KEYBOARD_BRIGHTNESS_DOWN.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_KEYBOARD_BRIGHTNESS_DOWN.png.sha1 new file mode 100644 index 0000000..44e0483 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_KEYBOARD_BRIGHTNESS_DOWN.png.sha1
@@ -0,0 +1 @@ +77a9ac0d2d6da74a7a14c1845f74f4a312b36b9b \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_KEYBOARD_BRIGHTNESS_UP.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_KEYBOARD_BRIGHTNESS_UP.png.sha1 new file mode 100644 index 0000000..44e0483 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_KEYBOARD_BRIGHTNESS_UP.png.sha1
@@ -0,0 +1 @@ +77a9ac0d2d6da74a7a14c1845f74f4a312b36b9b \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_LAUNCH_APPLICATION1.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_LAUNCH_APPLICATION1.png.sha1 new file mode 100644 index 0000000..9d00adbd --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_LAUNCH_APPLICATION1.png.sha1
@@ -0,0 +1 @@ +be3236842ee6fecebaf0997814a0411a5226d8d9 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_LAUNCH_APPLICATION2.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_LAUNCH_APPLICATION2.png.sha1 new file mode 100644 index 0000000..86a7633 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_LAUNCH_APPLICATION2.png.sha1
@@ -0,0 +1 @@ +4396c1d289b2af57c6682346896c5ced7f5381c1 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_LAUNCH_ASSISTANT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_LAUNCH_ASSISTANT.png.sha1 new file mode 100644 index 0000000..86a7633 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_LAUNCH_ASSISTANT.png.sha1
@@ -0,0 +1 @@ +4396c1d289b2af57c6682346896c5ced7f5381c1 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_MEDIA_FAST_FORWARD.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_MEDIA_FAST_FORWARD.png.sha1 new file mode 100644 index 0000000..2210f1e3 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_MEDIA_FAST_FORWARD.png.sha1
@@ -0,0 +1 @@ +1fef844ff76039d3308b126d70a46f949183b6cc \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_MEDIA_PAUSE.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_MEDIA_PAUSE.png.sha1 new file mode 100644 index 0000000..2210f1e3 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_MEDIA_PAUSE.png.sha1
@@ -0,0 +1 @@ +1fef844ff76039d3308b126d70a46f949183b6cc \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_MEDIA_PLAY.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_MEDIA_PLAY.png.sha1 new file mode 100644 index 0000000..2210f1e3 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_MEDIA_PLAY.png.sha1
@@ -0,0 +1 @@ +1fef844ff76039d3308b126d70a46f949183b6cc \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_MEDIA_PLAY_PAUSE.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_MEDIA_PLAY_PAUSE.png.sha1 new file mode 100644 index 0000000..2210f1e3 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_MEDIA_PLAY_PAUSE.png.sha1
@@ -0,0 +1 @@ +1fef844ff76039d3308b126d70a46f949183b6cc \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_MEDIA_TRACK_NEXT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_MEDIA_TRACK_NEXT.png.sha1 new file mode 100644 index 0000000..2210f1e3 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_MEDIA_TRACK_NEXT.png.sha1
@@ -0,0 +1 @@ +1fef844ff76039d3308b126d70a46f949183b6cc \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_MEDIA_TRACK_PREVIOUS.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_MEDIA_TRACK_PREVIOUS.png.sha1 new file mode 100644 index 0000000..2210f1e3 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_MEDIA_TRACK_PREVIOUS.png.sha1
@@ -0,0 +1 @@ +1fef844ff76039d3308b126d70a46f949183b6cc \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_MICROPHONE_MUTE_TOGGLE.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_MICROPHONE_MUTE_TOGGLE.png.sha1 new file mode 100644 index 0000000..2210f1e3 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_MICROPHONE_MUTE_TOGGLE.png.sha1
@@ -0,0 +1 @@ +1fef844ff76039d3308b126d70a46f949183b6cc \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_MODE_CHANGE.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_MODE_CHANGE.png.sha1 new file mode 100644 index 0000000..44e0483 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_MODE_CHANGE.png.sha1
@@ -0,0 +1 @@ +77a9ac0d2d6da74a7a14c1845f74f4a312b36b9b \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_PRINT_SCREEN.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_PRINT_SCREEN.png.sha1 new file mode 100644 index 0000000..9d00adbd --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_PRINT_SCREEN.png.sha1
@@ -0,0 +1 @@ +be3236842ee6fecebaf0997814a0411a5226d8d9 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_PRIVACY_SCREEN_TOGGLE.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_PRIVACY_SCREEN_TOGGLE.png.sha1 new file mode 100644 index 0000000..75c5f8d6 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_PRIVACY_SCREEN_TOGGLE.png.sha1
@@ -0,0 +1 @@ +795b7bfa7fa6910321a192f2fdff87f0f30b8cb9 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_SETTINGS.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_SETTINGS.png.sha1 new file mode 100644 index 0000000..9d00adbd --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_SETTINGS.png.sha1
@@ -0,0 +1 @@ +be3236842ee6fecebaf0997814a0411a5226d8d9 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_TOGGLE_DICTATION.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_TOGGLE_DICTATION.png.sha1 new file mode 100644 index 0000000..86a7633 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_TOGGLE_DICTATION.png.sha1
@@ -0,0 +1 @@ +4396c1d289b2af57c6682346896c5ced7f5381c1 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_ZOOM_TOGGLE.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_ZOOM_TOGGLE.png.sha1 new file mode 100644 index 0000000..75c5f8d6 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_ICON_LABEL_ZOOM_TOGGLE.png.sha1
@@ -0,0 +1 @@ +795b7bfa7fa6910321a192f2fdff87f0f30b8cb9 \ No newline at end of file
diff --git a/chromeos/components/quick_answers/quick_answers_client.cc b/chromeos/components/quick_answers/quick_answers_client.cc index 4d48bf0..6fdacd7 100644 --- a/chromeos/components/quick_answers/quick_answers_client.cc +++ b/chromeos/components/quick_answers/quick_answers_client.cc
@@ -98,10 +98,10 @@ } void QuickAnswersClient::OnQuickAnswerReceived( - std::unique_ptr<QuickAnswer> quick_answer) { + std::unique_ptr<QuickAnswersSession> quick_answers_session) { DCHECK(delegate_); quick_answer_received_time_ = base::TimeTicks::Now(); - delegate_->OnQuickAnswerReceived(std::move(quick_answer)); + delegate_->OnQuickAnswerReceived(std::move(quick_answers_session)); } void QuickAnswersClient::SendRequestInternal(
diff --git a/chromeos/components/quick_answers/quick_answers_client.h b/chromeos/components/quick_answers/quick_answers_client.h index c60786b..b180dd9 100644 --- a/chromeos/components/quick_answers/quick_answers_client.h +++ b/chromeos/components/quick_answers/quick_answers_client.h
@@ -22,7 +22,6 @@ namespace quick_answers { class SpellChecker; -struct QuickAnswer; struct QuickAnswersRequest; struct IntentInfo; enum class IntentType; @@ -34,10 +33,11 @@ QuickAnswersDelegate(const QuickAnswersDelegate&) = delete; QuickAnswersDelegate& operator=(const QuickAnswersDelegate&) = delete; - // Invoked when the |quick_answer| is received. Note that |quick_answer| may - // be |nullptr| if no answer found for the selected content. + // Invoked when the `quick_answers_session` is received. Note that + // `quick_answers_session` may be `nullptr` if no answer found for the + // selected content. virtual void OnQuickAnswerReceived( - std::unique_ptr<QuickAnswer> quick_answer) {} + std::unique_ptr<QuickAnswersSession> quick_answers_session) {} // Invoked when the query is rewritten. virtual void OnRequestPreprocessFinished( @@ -76,7 +76,7 @@ // ResultLoaderDelegate: void OnNetworkError() override; void OnQuickAnswerReceived( - std::unique_ptr<QuickAnswer> quick_answer) override; + std::unique_ptr<QuickAnswersSession> quick_answers_session) override; // Send a quick answer request for preprocessing only. void SendRequestForPreprocessing(
diff --git a/chromeos/components/quick_answers/quick_answers_client_unittest.cc b/chromeos/components/quick_answers/quick_answers_client_unittest.cc index 6b72c85..a227b64 100644 --- a/chromeos/components/quick_answers/quick_answers_client_unittest.cc +++ b/chromeos/components/quick_answers/quick_answers_client_unittest.cc
@@ -191,9 +191,14 @@ std::unique_ptr<QuickAnswer> quick_answer = std::make_unique<QuickAnswer>(); quick_answer->first_answer_row.push_back( std::make_unique<QuickAnswerResultText>("answer")); - EXPECT_CALL(*mock_delegate_, - OnQuickAnswerReceived(QuickAnswerEqual(&(*quick_answer)))); - client_->OnQuickAnswerReceived(std::move(quick_answer)); + + std::unique_ptr<QuickAnswersSession> quick_answers_session = + std::make_unique<QuickAnswersSession>(); + quick_answers_session->quick_answer = std::move(quick_answer); + + EXPECT_CALL(*mock_delegate_, OnQuickAnswerReceived(testing::Pointer( + testing::Eq(quick_answers_session.get())))); + client_->OnQuickAnswerReceived(std::move(quick_answers_session)); } TEST_F(QuickAnswersClientTest, SendRequestForPreprocessing) {
diff --git a/chromeos/components/quick_answers/quick_answers_model.cc b/chromeos/components/quick_answers/quick_answers_model.cc index 7793461..2ef886f 100644 --- a/chromeos/components/quick_answers/quick_answers_model.cc +++ b/chromeos/components/quick_answers/quick_answers_model.cc
@@ -36,4 +36,13 @@ default; QuickAnswersRequest::~QuickAnswersRequest() = default; +TranslationResult::TranslationResult() = default; +TranslationResult::~TranslationResult() = default; + +StructuredResult::StructuredResult() = default; +StructuredResult::~StructuredResult() = default; + +QuickAnswersSession::QuickAnswersSession() = default; +QuickAnswersSession::~QuickAnswersSession() = default; + } // namespace quick_answers
diff --git a/chromeos/components/quick_answers/quick_answers_model.h b/chromeos/components/quick_answers/quick_answers_model.h index 032a291..b45b9bf 100644 --- a/chromeos/components/quick_answers/quick_answers_model.h +++ b/chromeos/components/quick_answers/quick_answers_model.h
@@ -224,6 +224,57 @@ // links, etc). }; +// `TranslationResult` holds result for translation intent. +// `TranslationResult` must be copyable as it can be copied to a view. +struct TranslationResult { + public: + TranslationResult(); + ~TranslationResult(); + + std::u16string text_to_translate; + std::u16string translated_text; + std::string source_locale; + std::string target_locale; +}; + +// `StructuredResult` is NOT copyable as it's not trivial to make a class with +// unique_ptr to copyable. +class StructuredResult { + public: + StructuredResult(); + ~StructuredResult(); + StructuredResult(const StructuredResult&) = delete; + StructuredResult& operator=(const StructuredResult) = delete; + + // Result type specific structs must be copyable. + std::unique_ptr<TranslationResult> translation_result; +}; + +// `QuickAnswersSession` holds states related to a single Quick Answer session. +// +// This class currently holds results in `QuickAnswer` and `StructuredResult`. +// `QuickAnswer` field is used by `QuickAnswersView`. Rich Answers will read +// `StructuredResult`. Note that `QuickAnswer` is populated by using information +// in `StructuredResult`, i.e. `StructuredResult` is a super-set of +// `QuickAnswer`. +// +// Longer term plan is to migrate other states to this class, e.g. intent. +// +// `QuickAnswersSession` is NOT copyable as it's not trivial to make a class +// with unique_ptr to copyable. +class QuickAnswersSession { + public: + QuickAnswersSession(); + ~QuickAnswersSession(); + QuickAnswersSession(const QuickAnswersSession&) = delete; + QuickAnswersSession& operator=(const QuickAnswersSession) = delete; + + // TODO(b/278929409): Once we migrate all result types to `StructuredResult`, + // populate `QuickAnswer` outside of ResultParsers. + std::unique_ptr<QuickAnswer> quick_answer; + std::unique_ptr<StructuredResult> structured_result; +}; + } // namespace quick_answers #endif // CHROMEOS_COMPONENTS_QUICK_ANSWERS_QUICK_ANSWERS_MODEL_H_
diff --git a/chromeos/components/quick_answers/result_loader.cc b/chromeos/components/quick_answers/result_loader.cc index df01587..ce8396d 100644 --- a/chromeos/components/quick_answers/result_loader.cc +++ b/chromeos/components/quick_answers/result_loader.cc
@@ -142,13 +142,17 @@ } void ResultLoader::OnResultParserComplete( - std::unique_ptr<QuickAnswer> quick_answer) { + std::unique_ptr<QuickAnswersSession> quick_answers_session) { + raw_ptr<QuickAnswer> quick_answer = + quick_answers_session ? quick_answers_session->quick_answer.get() + : nullptr; // Record quick answer result. base::TimeDelta duration = base::TimeTicks::Now() - fetch_start_time_; RecordLoadingStatus( quick_answer ? LoadStatus::kSuccess : LoadStatus::kNoResult, duration); RecordResult(quick_answer ? quick_answer->result_type : ResultType::kNoResult, duration); - delegate_->OnQuickAnswerReceived(std::move(quick_answer)); + + delegate_->OnQuickAnswerReceived(std::move(quick_answers_session)); } } // namespace quick_answers
diff --git a/chromeos/components/quick_answers/result_loader.h b/chromeos/components/quick_answers/result_loader.h index b5c3666..35670fc 100644 --- a/chromeos/components/quick_answers/result_loader.h +++ b/chromeos/components/quick_answers/result_loader.h
@@ -37,20 +37,21 @@ // Invoked when there is a network error. virtual void OnNetworkError() {} - // Invoked when the |quick_answer| is received. Note that |quick_answer| may - // be |nullptr| if no answer found for the selected content. + // Invoked when the `quick_answers_session` is received. Note that + // `quick_answers_session` may be `nullptr` if no answer found for the + // selected content. virtual void OnQuickAnswerReceived( - std::unique_ptr<QuickAnswer> quick_answer) {} + std::unique_ptr<QuickAnswersSession> quick_answers_session) {} protected: ResultLoaderDelegate() = default; virtual ~ResultLoaderDelegate() = default; }; - // Callback used when parsing of |quick_answer| is complete. Note that - // |quick_answer| may be |nullptr|. - using ResponseParserCallback = - base::OnceCallback<void(std::unique_ptr<QuickAnswer> quick_answer)>; + // Callback used when parsing for `quick_answers_session` is complete. Note + // that `quick_answers_session` may be `nullptr`. + using ResponseParserCallback = base::OnceCallback<void( + std::unique_ptr<QuickAnswersSession> quick_answers_session)>; using BuildRequestCallback = base::OnceCallback<void( std::unique_ptr<network::ResourceRequest> resource_request, @@ -101,7 +102,8 @@ const std::string& request_body); void OnSimpleURLLoaderComplete(const PreprocessedOutput& preprocessed_output, std::unique_ptr<std::string> response_body); - void OnResultParserComplete(std::unique_ptr<QuickAnswer> quick_answer); + void OnResultParserComplete( + std::unique_ptr<QuickAnswersSession> quick_answers_session); // Time when the query is issued. base::TimeTicks fetch_start_time_;
diff --git a/chromeos/components/quick_answers/search_result_loader.cc b/chromeos/components/quick_answers/search_result_loader.cc index aa9462c..84d5f28 100644 --- a/chromeos/components/quick_answers/search_result_loader.cc +++ b/chromeos/components/quick_answers/search_result_loader.cc
@@ -6,6 +6,7 @@ #include <utility> +#include "base/functional/bind.h" #include "base/json/json_writer.h" #include "base/strings/escape.h" #include "chromeos/components/quick_answers/quick_answers_model.h" @@ -111,8 +112,30 @@ std::unique_ptr<std::string> response_body, ResponseParserCallback complete_callback) { search_response_parser_ = - std::make_unique<SearchResponseParser>(std::move(complete_callback)); + std::make_unique<SearchResponseParser>(base::BindOnce( + &SearchResultLoader::OnSearchResponseParsed, + weak_ptr_factory_.GetWeakPtr(), std::move(complete_callback))); search_response_parser_->ProcessResponse(std::move(response_body)); } +void SearchResultLoader::OnSearchResponseParsed( + ResponseParserCallback complete_callback, + std::unique_ptr<QuickAnswer> quick_answer) { + // If no `QuickAnswer` is returned, e.g. parse failure, return nullptr instead + // of an empty `QuickAnswersSession`. `SearchResultLoaderTest.EmptyResponse` + // expects this behavior. For longer term, migrate to an empty `quick_answer` + // field in `QuickAnswersSession` as `QuickAnswersSession` will hold more + // information, e.g. intent. + if (!quick_answer) { + std::move(complete_callback).Run(nullptr); + return; + } + + // TODO(b/278929409) Fill structured_result field. + std::unique_ptr<QuickAnswersSession> quick_answers_session = + std::make_unique<QuickAnswersSession>(); + quick_answers_session->quick_answer = std::move(quick_answer); + std::move(complete_callback).Run(std::move(quick_answers_session)); +} + } // namespace quick_answers
diff --git a/chromeos/components/quick_answers/search_result_loader.h b/chromeos/components/quick_answers/search_result_loader.h index d3b19c34..5c93cee 100644 --- a/chromeos/components/quick_answers/search_result_loader.h +++ b/chromeos/components/quick_answers/search_result_loader.h
@@ -9,6 +9,7 @@ #include <string> #include "base/memory/scoped_refptr.h" +#include "base/memory/weak_ptr.h" #include "chromeos/components/quick_answers/result_loader.h" #include "chromeos/components/quick_answers/search_result_parsers/search_response_parser.h" @@ -37,7 +38,11 @@ ResponseParserCallback complete_callback) override; private: + void OnSearchResponseParsed(ResponseParserCallback complete_callback, + std::unique_ptr<QuickAnswer> quick_answer); + std::unique_ptr<SearchResponseParser> search_response_parser_; + base::WeakPtrFactory<SearchResultLoader> weak_ptr_factory_{this}; }; } // namespace quick_answers
diff --git a/chromeos/components/quick_answers/search_result_loader_unittest.cc b/chromeos/components/quick_answers/search_result_loader_unittest.cc index 538b235..565ef6cf 100644 --- a/chromeos/components/quick_answers/search_result_loader_unittest.cc +++ b/chromeos/components/quick_answers/search_result_loader_unittest.cc
@@ -8,6 +8,7 @@ #include <string> #include "base/memory/scoped_refptr.h" +#include "base/run_loop.h" #include "base/test/task_environment.h" #include "chromeos/components/quick_answers/public/cpp/quick_answers_prefs.h" #include "chromeos/components/quick_answers/quick_answers_model.h" @@ -79,14 +80,15 @@ }; TEST_F(SearchResultLoaderTest, Success) { - std::unique_ptr<QuickAnswer> expected_quick_answer = - std::make_unique<QuickAnswer>(); - expected_quick_answer->first_answer_row.push_back( - std::make_unique<QuickAnswerResultText>("9.055 inches")); - - EXPECT_CALL( - *mock_delegate_, - OnQuickAnswerReceived(QuickAnswerEqual(expected_quick_answer.get()))); + base::RunLoop run_loop; + std::unique_ptr<QuickAnswersSession> session; + ON_CALL(*mock_delegate_, OnQuickAnswerReceived) + .WillByDefault( + [&session, &run_loop]( + std::unique_ptr<QuickAnswersSession> quick_answers_session) { + session = std::move(quick_answers_session); + run_loop.Quit(); + }); EXPECT_CALL(*mock_delegate_, OnNetworkError()).Times(0); fake_quick_answers_state_.SetConsentStatus( @@ -96,7 +98,12 @@ test_url_loader_factory_.SimulateResponseForPendingRequest( chromeos::assistant::kKnowledgeApiEndpoint, kValidResponse, net::HTTP_OK, network::TestURLLoaderFactory::ResponseMatchFlags::kUrlMatchPrefix); - base::RunLoop().RunUntilIdle(); + + run_loop.Run(); + ASSERT_TRUE(session); + ASSERT_TRUE(session->quick_answer); + EXPECT_EQ("9.055 inches", GetQuickAnswerTextForTesting( + session->quick_answer->first_answer_row)); } TEST_F(SearchResultLoaderTest, NetworkError) {
diff --git a/chromeos/components/quick_answers/test/test_helpers.h b/chromeos/components/quick_answers/test/test_helpers.h index e9ca727..089fb5a0 100644 --- a/chromeos/components/quick_answers/test/test_helpers.h +++ b/chromeos/components/quick_answers/test/test_helpers.h
@@ -25,7 +25,8 @@ MockQuickAnswersDelegate& operator=(const MockQuickAnswersDelegate&) = delete; // QuickAnswersClient::QuickAnswersDelegate: - MOCK_METHOD1(OnQuickAnswerReceived, void(std::unique_ptr<QuickAnswer>)); + MOCK_METHOD1(OnQuickAnswerReceived, + void(std::unique_ptr<QuickAnswersSession>)); MOCK_METHOD1(OnRequestPreprocessFinished, void(const QuickAnswersRequest&)); MOCK_METHOD0(OnNetworkError, void()); }; @@ -41,7 +42,8 @@ // ResultLoader::ResultLoaderDelegate: MOCK_METHOD0(OnNetworkError, void()); - MOCK_METHOD1(OnQuickAnswerReceived, void(std::unique_ptr<QuickAnswer>)); + MOCK_METHOD1(OnQuickAnswerReceived, + void(std::unique_ptr<QuickAnswersSession>)); }; MATCHER_P(QuickAnswerEqual, quick_answer, "") {
diff --git a/chromeos/components/quick_answers/translation_response_parser.cc b/chromeos/components/quick_answers/translation_response_parser.cc index c93d3ae..06515589 100644 --- a/chromeos/components/quick_answers/translation_response_parser.cc +++ b/chromeos/components/quick_answers/translation_response_parser.cc
@@ -7,7 +7,9 @@ #include <utility> #include "base/functional/bind.h" +#include "base/strings/utf_string_conversions.h" #include "base/values.h" +#include "chromeos/components/quick_answers/quick_answers_model.h" #include "chromeos/components/quick_answers/search_result_parsers/result_parser.h" #include "chromeos/components/quick_answers/utils/quick_answers_utils.h" @@ -23,16 +25,14 @@ } void TranslationResponseParser::ProcessResponse( - std::unique_ptr<std::string> response_body, - const std::string& title_text) { + std::unique_ptr<std::string> response_body) { data_decoder::DataDecoder::ParseJsonIsolated( response_body->c_str(), base::BindOnce(&TranslationResponseParser::OnJsonParsed, - weak_factory_.GetWeakPtr(), title_text)); + weak_factory_.GetWeakPtr())); } void TranslationResponseParser::OnJsonParsed( - const std::string& title_text, data_decoder::DataDecoder::ValueOrError result) { DCHECK(complete_callback_); @@ -50,7 +50,7 @@ return; } - DCHECK(translations->size() == 1); + DCHECK_EQ(translations->size(), 1ul); const std::string* translated_text_ptr = translations->front().GetDict().FindStringByDottedPath("translatedText"); @@ -59,15 +59,12 @@ std::move(complete_callback_).Run(nullptr); return; } - auto translated_text = UnescapeStringForHTML(*translated_text_ptr); + std::string translated_text = UnescapeStringForHTML(*translated_text_ptr); - auto quick_answer = std::make_unique<QuickAnswer>(); - quick_answer->result_type = ResultType::kTranslationResult; - quick_answer->title.push_back(std::make_unique<QuickAnswerText>(title_text)); - quick_answer->first_answer_row.push_back( - std::make_unique<QuickAnswerResultText>(translated_text)); - - std::move(complete_callback_).Run(std::move(quick_answer)); + std::unique_ptr<TranslationResult> translation_result = + std::make_unique<TranslationResult>(); + translation_result->translated_text = base::UTF8ToUTF16(translated_text); + std::move(complete_callback_).Run(std::move(translation_result)); } } // namespace quick_answers
diff --git a/chromeos/components/quick_answers/translation_response_parser.h b/chromeos/components/quick_answers/translation_response_parser.h index 740abe7..fd0156c 100644 --- a/chromeos/components/quick_answers/translation_response_parser.h +++ b/chromeos/components/quick_answers/translation_response_parser.h
@@ -10,20 +10,19 @@ #include "base/functional/callback.h" #include "base/memory/weak_ptr.h" +#include "chromeos/components/quick_answers/quick_answers_model.h" #include "services/data_decoder/public/cpp/data_decoder.h" namespace quick_answers { -struct QuickAnswer; - // Parser for extracting quick answer result out of the cloud translation // response. class TranslationResponseParser { public: - // Callback used when parsing of |quick_answer| is complete. Note that - // |quick_answer| may be |nullptr|. - using TranslationResponseParserCallback = - base::OnceCallback<void(std::unique_ptr<QuickAnswer> quick_answer)>; + // Callback used when parsing for `translation_result` is complete. Note that + // `translation_result` may be `nullptr`. + using TranslationResponseParserCallback = base::OnceCallback<void( + std::unique_ptr<TranslationResult> translation_result)>; explicit TranslationResponseParser( TranslationResponseParserCallback complete_callback); @@ -34,12 +33,10 @@ delete; // Starts processing the search response. - void ProcessResponse(std::unique_ptr<std::string> response_body, - const std::string& title_text); + void ProcessResponse(std::unique_ptr<std::string> response_body); private: - void OnJsonParsed(const std::string& title_text, - data_decoder::DataDecoder::ValueOrError result); + void OnJsonParsed(data_decoder::DataDecoder::ValueOrError result); TranslationResponseParserCallback complete_callback_;
diff --git a/chromeos/components/quick_answers/translation_response_parser_unittest.cc b/chromeos/components/quick_answers/translation_response_parser_unittest.cc index 138a882..7963d50a 100644 --- a/chromeos/components/quick_answers/translation_response_parser_unittest.cc +++ b/chromeos/components/quick_answers/translation_response_parser_unittest.cc
@@ -34,8 +34,8 @@ } void TranslationResponseParserCallback( - std::unique_ptr<QuickAnswer> quick_answer) { - quick_answer_ = std::move(quick_answer); + std::unique_ptr<TranslationResult> translation_result) { + translation_result_ = std::move(translation_result); run_loop_->Quit(); } @@ -47,7 +47,7 @@ protected: base::test::SingleThreadTaskEnvironment task_environment_; std::unique_ptr<TranslationResponseParser> translation_response_parser_; - std::unique_ptr<QuickAnswer> quick_answer_; + std::unique_ptr<TranslationResult> translation_result_; data_decoder::test::InProcessDataDecoder in_process_data_decoder_; std::unique_ptr<base::RunLoop> run_loop_; }; @@ -64,16 +64,11 @@ } } )"; - constexpr char kTranslationTitle[] = "testo tradotto · Italian"; translation_response_parser_->ProcessResponse( - std::make_unique<std::string>(kTranslationResponse), kTranslationTitle); + std::make_unique<std::string>(kTranslationResponse)); WaitForResponse(); - EXPECT_TRUE(quick_answer_); - EXPECT_EQ("translated text", - GetQuickAnswerTextForTesting(quick_answer_->first_answer_row)); - EXPECT_EQ(kTranslationTitle, - GetQuickAnswerTextForTesting(quick_answer_->title)); - EXPECT_EQ(ResultType::kTranslationResult, quick_answer_->result_type); + ASSERT_TRUE(translation_result_); + EXPECT_EQ(u"translated text", translation_result_->translated_text); } TEST_F(TranslationResponseParserTest, @@ -89,17 +84,12 @@ } } )"; - constexpr char kTranslationTitle[] = "non scherzare con me · Italian"; translation_response_parser_->ProcessResponse( - std::make_unique<std::string>(kTranslationResponse), kTranslationTitle); + std::make_unique<std::string>(kTranslationResponse)); WaitForResponse(); - EXPECT_TRUE(quick_answer_); + ASSERT_TRUE(translation_result_); // Should correctly unescape ampersand character codes. - EXPECT_EQ("don't mess with me", - GetQuickAnswerTextForTesting(quick_answer_->first_answer_row)); - EXPECT_EQ(kTranslationTitle, - GetQuickAnswerTextForTesting(quick_answer_->title)); - EXPECT_EQ(ResultType::kTranslationResult, quick_answer_->result_type); + EXPECT_EQ(u"don't mess with me", translation_result_->translated_text); } TEST_F(TranslationResponseParserTest, ProcessResponseNoResults) { @@ -107,16 +97,16 @@ {} )"; translation_response_parser_->ProcessResponse( - std::make_unique<std::string>(kTranslationResponse), std::string()); + std::make_unique<std::string>(kTranslationResponse)); WaitForResponse(); - EXPECT_FALSE(quick_answer_); + EXPECT_FALSE(translation_result_); } TEST_F(TranslationResponseParserTest, ProcessResponseInvalidResponse) { translation_response_parser_->ProcessResponse( - std::make_unique<std::string>("results {}"), std::string()); + std::make_unique<std::string>("results {}")); WaitForResponse(); - EXPECT_FALSE(quick_answer_); + EXPECT_FALSE(translation_result_); } } // namespace quick_answers
diff --git a/chromeos/components/quick_answers/translation_result_loader.cc b/chromeos/components/quick_answers/translation_result_loader.cc index 9b8557c..03b186954 100644 --- a/chromeos/components/quick_answers/translation_result_loader.cc +++ b/chromeos/components/quick_answers/translation_result_loader.cc
@@ -8,6 +8,7 @@ #include "base/json/json_writer.h" #include "base/strings/escape.h" +#include "base/strings/utf_string_conversions.h" #include "chromeos/components/quick_answers/quick_answers_model.h" #include "chromeos/components/quick_answers/utils/quick_answers_utils.h" #include "chromeos/services/assistant/public/shared/constants.h" @@ -85,11 +86,52 @@ const PreprocessedOutput& preprocessed_output, std::unique_ptr<std::string> response_body, ResponseParserCallback complete_callback) { + if (translation_response_parser_) { + DCHECK(false) << "translation_response_parser_ must be nullptr"; + std::move(complete_callback).Run(nullptr); + return; + } + translation_response_parser_ = - std::make_unique<TranslationResponseParser>(std::move(complete_callback)); - translation_response_parser_->ProcessResponse( - std::move(response_body), - BuildTranslationTitleText(preprocessed_output.intent_info)); + std::make_unique<TranslationResponseParser>(base::BindOnce( + &TranslationResultLoader::ProcessParsedResponse, + weak_ptr_factory_.GetWeakPtr(), preprocessed_output.intent_info, + std::move(complete_callback))); + translation_response_parser_->ProcessResponse(std::move(response_body)); +} + +void TranslationResultLoader::ProcessParsedResponse( + IntentInfo intent_info, + ResponseParserCallback complete_callback, + std::unique_ptr<TranslationResult> translation_result) { + translation_response_parser_.reset(); + + if (!translation_result || translation_result->translated_text.empty()) { + std::move(complete_callback).Run(nullptr); + return; + } + + translation_result->text_to_translate = + base::UTF8ToUTF16(intent_info.intent_text); + translation_result->source_locale = intent_info.source_language; + translation_result->target_locale = intent_info.device_language; + + std::unique_ptr<QuickAnswer> quick_answer = std::make_unique<QuickAnswer>(); + quick_answer->result_type = ResultType::kTranslationResult; + quick_answer->title.push_back(std::make_unique<QuickAnswerText>( + BuildTranslationTitleText(intent_info))); + quick_answer->first_answer_row.push_back( + std::make_unique<QuickAnswerResultText>( + base::UTF16ToUTF8(translation_result->translated_text))); + + std::unique_ptr<QuickAnswersSession> session = + std::make_unique<QuickAnswersSession>(); + session->structured_result = std::make_unique<StructuredResult>(); + session->structured_result->translation_result = + std::move(translation_result); + session->quick_answer = std::move(quick_answer); + + std::move(complete_callback).Run(std::move(session)); } } // namespace quick_answers
diff --git a/chromeos/components/quick_answers/translation_result_loader.h b/chromeos/components/quick_answers/translation_result_loader.h index 0ce9218..59bd83c 100644 --- a/chromeos/components/quick_answers/translation_result_loader.h +++ b/chromeos/components/quick_answers/translation_result_loader.h
@@ -9,6 +9,8 @@ #include <string> #include "base/memory/scoped_refptr.h" +#include "base/memory/weak_ptr.h" +#include "chromeos/components/quick_answers/quick_answers_model.h" #include "chromeos/components/quick_answers/result_loader.h" #include "chromeos/components/quick_answers/translation_response_parser.h" @@ -37,7 +39,13 @@ ResponseParserCallback complete_callback) override; private: + void ProcessParsedResponse( + IntentInfo intent_info, + ResponseParserCallback complete_callback, + std::unique_ptr<TranslationResult> translation_result); std::unique_ptr<TranslationResponseParser> translation_response_parser_; + + base::WeakPtrFactory<TranslationResultLoader> weak_ptr_factory_{this}; }; } // namespace quick_answers
diff --git a/chromeos/components/quick_answers/translation_result_loader_unittest.cc b/chromeos/components/quick_answers/translation_result_loader_unittest.cc index 74b95cf0..c3c8aff 100644 --- a/chromeos/components/quick_answers/translation_result_loader_unittest.cc +++ b/chromeos/components/quick_answers/translation_result_loader_unittest.cc
@@ -8,6 +8,7 @@ #include <string> #include "base/memory/scoped_refptr.h" +#include "base/strings/utf_string_conversions.h" #include "base/test/task_environment.h" #include "chromeos/components/quick_answers/public/cpp/quick_answers_prefs.h" #include "chromeos/components/quick_answers/quick_answers_model.h" @@ -90,24 +91,47 @@ }; TEST_F(TranslationResultLoaderTest, Success) { - std::unique_ptr<QuickAnswer> expected_quick_answer = - std::make_unique<QuickAnswer>(); - expected_quick_answer->first_answer_row.push_back( - std::make_unique<QuickAnswerResultText>(kTestTranslationResult)); - expected_quick_answer->title.push_back( - std::make_unique<QuickAnswerText>(kTestTranslationTitle)); test_url_loader_factory_.AddResponse(CreateTranslationRequest().spec(), kValidResponse); - EXPECT_CALL( - *mock_delegate_, - OnQuickAnswerReceived(QuickAnswerEqual(expected_quick_answer.get()))); + base::RunLoop run_loop; + std::unique_ptr<QuickAnswersSession> session; + ON_CALL(*mock_delegate_, OnQuickAnswerReceived) + .WillByDefault( + [&session, &run_loop]( + std::unique_ptr<QuickAnswersSession> quick_answers_session) { + session = std::move(quick_answers_session); + run_loop.Quit(); + }); + EXPECT_CALL(*mock_delegate_, OnNetworkError()).Times(0); fake_quick_answers_state_.SetConsentStatus( quick_answers::prefs::ConsentStatus::kAccepted); loader_->Fetch(PreprocessRequest(kTestTranslationIntent)); - base::RunLoop().RunUntilIdle(); + run_loop.Run(); + + ASSERT_TRUE(session); + ASSERT_TRUE(session->quick_answer); + EXPECT_EQ(ResultType::kTranslationResult, session->quick_answer->result_type); + EXPECT_EQ( + kTestTranslationResult, + GetQuickAnswerTextForTesting(session->quick_answer->first_answer_row)); + EXPECT_EQ(kTestTranslationTitle, + GetQuickAnswerTextForTesting(session->quick_answer->title)); + + ASSERT_TRUE(session->structured_result); + ASSERT_TRUE(session->structured_result->translation_result); + raw_ptr<TranslationResult> translation_result = + session->structured_result->translation_result.get(); + EXPECT_EQ(kTestTranslationIntent.intent_text, + base::UTF16ToUTF8(translation_result->text_to_translate)); + EXPECT_EQ(kTestTranslationResult, + base::UTF16ToUTF8(translation_result->translated_text)); + EXPECT_EQ(kTestTranslationIntent.device_language, + translation_result->target_locale); + EXPECT_EQ(kTestTranslationIntent.source_language, + translation_result->source_locale); } TEST_F(TranslationResultLoaderTest, NetworkError) {
diff --git a/chromeos/ui/frame/multitask_menu/multitask_menu.cc b/chromeos/ui/frame/multitask_menu/multitask_menu.cc index 2d7de62..f9cc80a 100644 --- a/chromeos/ui/frame/multitask_menu/multitask_menu.cc +++ b/chromeos/ui/frame/multitask_menu/multitask_menu.cc
@@ -11,6 +11,7 @@ #include "chromeos/ui/frame/multitask_menu/float_controller_base.h" #include "chromeos/ui/frame/multitask_menu/multitask_menu_view.h" #include "chromeos/ui/wm/window_util.h" +#include "ui/aura/window.h" #include "ui/base/metadata/metadata_impl_macros.h" #include "ui/display/screen.h" #include "ui/display/tablet_state.h" @@ -93,7 +94,6 @@ kButtonHeight); display_observer_.emplace(this); - parent_window_observation_.Observe(parent_window()); } MultitaskMenu::~MultitaskMenu() = default; @@ -109,27 +109,6 @@ widget->CloseWithReason(views::Widget::ClosedReason::kUnspecified); } -void MultitaskMenu::OnWindowDestroying(aura::Window* parent_window) { - DCHECK(parent_window_observation_.IsObservingSource(parent_window)); - HideBubble(); -} - -void MultitaskMenu::OnWindowBoundsChanged(aura::Window* window, - const gfx::Rect& old_bounds, - const gfx::Rect& new_bounds, - ui::PropertyChangeReason reason) { - DCHECK(parent_window_observation_.IsObservingSource(window)); - HideBubble(); -} - -void MultitaskMenu::OnWindowVisibilityChanging(aura::Window* window, - bool visible) { - DCHECK(parent_window_observation_.IsObservingSource(window)); - if (!visible) { - HideBubble(); - } -} - void MultitaskMenu::OnDisplayTabletStateChanged(display::TabletState state) { if (state == display::TabletState::kEnteringTabletMode) HideBubble();
diff --git a/chromeos/ui/frame/multitask_menu/multitask_menu.h b/chromeos/ui/frame/multitask_menu/multitask_menu.h index 9464bdc..32d09c6 100644 --- a/chromeos/ui/frame/multitask_menu/multitask_menu.h +++ b/chromeos/ui/frame/multitask_menu/multitask_menu.h
@@ -8,8 +8,6 @@ #include "base/memory/raw_ptr.h" #include "chromeos/ui/frame/caption_buttons/snap_controller.h" #include "chromeos/ui/frame/multitask_menu/multitask_menu_view.h" -#include "ui/aura/window.h" -#include "ui/aura/window_observer.h" #include "ui/base/metadata/metadata_header_macros.h" #include "ui/display/display_observer.h" #include "ui/views/bubble/bubble_dialog_delegate_view.h" @@ -25,7 +23,6 @@ // MultitaskMenu is the window layout menu attached to frame size button. class COMPONENT_EXPORT(CHROMEOS_UI_FRAME) MultitaskMenu : public views::BubbleDialogDelegateView, - public aura::WindowObserver, public display::DisplayObserver { public: METADATA_HEADER(MultitaskMenu); @@ -43,14 +40,6 @@ void HideBubble(); - // aura::WindowObserver: - void OnWindowDestroying(aura::Window* parent_window) override; - void OnWindowBoundsChanged(aura::Window* window, - const gfx::Rect& old_bounds, - const gfx::Rect& new_bounds, - ui::PropertyChangeReason reason) override; - void OnWindowVisibilityChanging(aura::Window* window, bool visible) override; - // display::DisplayObserver: void OnDisplayMetricsChanged(const display::Display& display, uint32_t changed_metrics) override; @@ -61,9 +50,6 @@ raw_ptr<MultitaskMenuView> multitask_menu_view_ = nullptr; - base::ScopedObservation<aura::Window, aura::WindowObserver> - parent_window_observation_{this}; - absl::optional<display::ScopedDisplayObserver> display_observer_; };
diff --git a/chromeos/ui/frame/multitask_menu/multitask_menu_view.cc b/chromeos/ui/frame/multitask_menu/multitask_menu_view.cc index 30f71fd..fc2c0b6 100644 --- a/chromeos/ui/frame/multitask_menu/multitask_menu_view.cc +++ b/chromeos/ui/frame/multitask_menu/multitask_menu_view.cc
@@ -169,6 +169,8 @@ DCHECK(close_callback_); SetUseDefaultFillLayout(true); + window_observation_.Observe(window); + // The display orientation. This determines whether menu is in // landscape/portrait mode. const bool is_portrait_mode = !chromeos::IsDisplayLayoutHorizontal( @@ -281,6 +283,30 @@ ui::kColorMultitaskFeedbackButtonLabelForeground))); } +void MultitaskMenuView::OnWindowDestroying(aura::Window* window) { + CHECK(window_observation_.IsObservingSource(window)); + + window_observation_.Reset(); + window_ = nullptr; + close_callback_.Run(); +} + +void MultitaskMenuView::OnWindowBoundsChanged(aura::Window* window, + const gfx::Rect& old_bounds, + const gfx::Rect& new_bounds, + ui::PropertyChangeReason reason) { + CHECK(window_observation_.IsObservingSource(window)); + close_callback_.Run(); +} + +void MultitaskMenuView::OnWindowVisibilityChanging(aura::Window* window, + bool visible) { + CHECK(window_observation_.IsObservingSource(window)); + if (!visible) { + close_callback_.Run(); + } +} + // static void MultitaskMenuView::SetSkipMouseOutDelayForTesting(bool val) { g_skip_mouse_out_delay_for_testing = val;
diff --git a/chromeos/ui/frame/multitask_menu/multitask_menu_view.h b/chromeos/ui/frame/multitask_menu/multitask_menu_view.h index 74c616cb..3b69cae 100644 --- a/chromeos/ui/frame/multitask_menu/multitask_menu_view.h +++ b/chromeos/ui/frame/multitask_menu/multitask_menu_view.h
@@ -7,6 +7,7 @@ #include "base/memory/raw_ptr.h" #include "chromeos/ui/frame/caption_buttons/snap_controller.h" +#include "ui/aura/window_observer.h" #include "ui/base/metadata/metadata_header_macros.h" #include "ui/views/controls/button/label_button.h" #include "ui/views/view.h" @@ -25,7 +26,8 @@ // contains a separate button to open a dogfood feedback page, to be removed in // M114/launch. class COMPONENT_EXPORT(CHROMEOS_UI_FRAME) MultitaskMenuView - : public views::View { + : public views::View, + public aura::WindowObserver { public: METADATA_HEADER(MultitaskMenuView); @@ -41,7 +43,7 @@ // should be passed when we want the functionality of auto-closing the menu // when the mouse moves out of the menu or the anchor. MultitaskMenuView(aura::Window* window, - base::RepeatingClosure on_any_button_pressed, + base::RepeatingClosure close_callback, uint8_t buttons, views::View* anchor_view); @@ -57,6 +59,14 @@ void AddedToWidget() override; void OnThemeChanged() override; + // aura::WindowObserver: + void OnWindowDestroying(aura::Window* parent_window) override; + void OnWindowBoundsChanged(aura::Window* window, + const gfx::Rect& old_bounds, + const gfx::Rect& new_bounds, + ui::PropertyChangeReason reason) override; + void OnWindowVisibilityChanging(aura::Window* window, bool visible) override; + // If the menu is opened because of mouse hover, moving the mouse outside the // menu for 3 seconds will result in it auto closing. This function reduces // that 3 second dealy to @@ -90,19 +100,23 @@ raw_ptr<MultitaskButton> full_button_for_testing_ = nullptr; raw_ptr<MultitaskButton> float_button_for_testing_ = nullptr; - // The window which the buttons act on. It is guaranteed to outlive `this`. - const raw_ptr<aura::Window, ExperimentalAsh> window_; + // The window which the buttons act on. + raw_ptr<aura::Window, ExperimentalAsh> window_; // The view the menu is anchored to if any. This is only passed if we want to // close the menu when the mouse moves out of the multitask menu or its anchor // view. const raw_ptr<views::View, ExperimentalAsh> anchor_view_; - // Runs after any of the buttons are pressed, or a press out of the menu + // Runs when the widget which contains `this` should be destroyed. For + // example, after any of the buttons are pressed, or a press out of the menu // bounds. base::RepeatingClosure close_callback_; std::unique_ptr<MenuPreTargetHandler> event_handler_; + + base::ScopedObservation<aura::Window, aura::WindowObserver> + window_observation_{this}; }; } // namespace chromeos
diff --git a/chromeos/ui/wm/window_util.cc b/chromeos/ui/wm/window_util.cc index 2863312..d35ba69 100644 --- a/chromeos/ui/wm/window_util.cc +++ b/chromeos/ui/wm/window_util.cc
@@ -134,6 +134,12 @@ return false; } #endif + + if (window->GetProperty(aura::client::kZOrderingKey) != + ui::ZOrderLevel::kNormal) { + return false; + } + return TabletState::Get()->InTabletMode() ? CanFloatWindowInTablet(window) : CanFloatWindowInClamshell(window); }
diff --git a/components/autofill/core/browser/address_profile_save_manager.cc b/components/autofill/core/browser/address_profile_save_manager.cc index 0c41552b..9e2616df 100644 --- a/components/autofill/core/browser/address_profile_save_manager.cc +++ b/components/autofill/core/browser/address_profile_save_manager.cc
@@ -15,19 +15,15 @@ namespace { -// When multi-step complements are enabled, sufficiently complete profiles are -// added as to `form_data_importer`s multi-step import candidates. This -// enables complementing them in later steps with additional optional -// information. +// Sufficiently complete profiles are added to the `form_data_importer`s +// multi-step import candidates. This enables complementing them in later steps +// with additional optional information. // This function adds the imported profile as a candidate. This is only done // after the user decision to incorporate manual edits. void AddMultiStepComplementCandidate(FormDataImporter* form_data_importer, const AutofillProfile& profile, const url::Origin& origin) { - if (!base::FeatureList::IsEnabled( - features::kAutofillEnableMultiStepImports) || - !features::kAutofillEnableMultiStepImportComplements.Get() || - !form_data_importer) { + if (!form_data_importer) { return; } // Metrics depending on `import_process.import_metadata()` are collected
diff --git a/components/autofill/core/browser/form_data_importer_unittest.cc b/components/autofill/core/browser/form_data_importer_unittest.cc index cc682d2..0ec19d3 100644 --- a/components/autofill/core/browser/form_data_importer_unittest.cc +++ b/components/autofill/core/browser/form_data_importer_unittest.cc
@@ -4142,10 +4142,6 @@ // Tests a 2-page multi-step extraction. TEST_P(FormDataImporterTest, MultiStepImport) { - base::test::ScopedFeatureList multistep_import_feature; - multistep_import_feature.InitAndEnableFeature( - features::kAutofillEnableMultiStepImports); - std::unique_ptr<FormStructure> form_structure = ConstructSplitDefaultProfileFormStructure(/*part=*/1); ExtractAddressProfilesAndVerifyExpectation(*form_structure, {}); @@ -4156,9 +4152,6 @@ // Tests that a complemented country is discarded in favour of an observed one. TEST_P(FormDataImporterTest, MultiStepImport_ComplementCountryEarly) { - base::test::ScopedFeatureList feature; - feature.InitAndEnableFeature(features::kAutofillEnableMultiStepImports); - // Import a profile fragment with country information. TypeValuePairs type_value_pairs = GetSplitDefaultProfileTypeValuePairs(/*part=*/1); @@ -4184,11 +4177,6 @@ // import was accepted are added as a multi-step candidate. This enables // complementing the profile with additional information on further pages. TEST_P(FormDataImporterTest, MultiStepImport_Complement) { - base::test::ScopedFeatureList multistep_import_with_complement_feature; - multistep_import_with_complement_feature.InitAndEnableFeatureWithParameters( - features::kAutofillEnableMultiStepImports, - {{features::kAutofillEnableMultiStepImportComplements.name, "true"}}); - // Extract the default profile without an email address. TypeValuePairs type_value_pairs = GetDefaultProfileTypeValuePairs(); SetValueForType(type_value_pairs, EMAIL_ADDRESS, ""); @@ -4212,11 +4200,6 @@ // via the settings), the multi-step complement candidate is updated accordingly // and the correct profile update occurs. TEST_P(FormDataImporterTest, MultiStepImport_Complement_ExternalUpdate) { - base::test::ScopedFeatureList multistep_import_with_complement_feature; - multistep_import_with_complement_feature.InitAndEnableFeatureWithParameters( - features::kAutofillEnableMultiStepImports, - {{features::kAutofillEnableMultiStepImportComplements.name, "true"}}); - // Extract the default profile without an email address. TypeValuePairs type_value_pairs = GetDefaultProfileTypeValuePairs(); SetValueForType(type_value_pairs, EMAIL_ADDRESS, ""); @@ -4246,11 +4229,6 @@ // via the settings), the multi-step complement candidate is removed and no // further updates related to it are offered. TEST_P(FormDataImporterTest, MultiStepImport_Complement_ExternalRemove) { - base::test::ScopedFeatureList multistep_import_with_complement_feature; - multistep_import_with_complement_feature.InitAndEnableFeatureWithParameters( - features::kAutofillEnableMultiStepImports, - {{features::kAutofillEnableMultiStepImportComplements.name, "true"}}); - // Extract the default profile without an email address. TypeValuePairs type_value_pairs = GetDefaultProfileTypeValuePairs(); SetValueForType(type_value_pairs, EMAIL_ADDRESS, ""); @@ -4273,10 +4251,6 @@ // Tests that multi-step candidate profiles from different origins are not // merged. TEST_P(FormDataImporterTest, MultiStepImport_DifferentOrigin) { - base::test::ScopedFeatureList multistep_import_feature; - multistep_import_feature.InitAndEnableFeature( - features::kAutofillEnableMultiStepImports); - FormData form = ConstructSplitDefaultFormData(/*part=*/1); form.url = GURL("https://www.foo.com"); std::unique_ptr<FormStructure> form_structure = @@ -4291,17 +4265,13 @@ // Tests that multi-step candidates profiles are invalidated after some TTL. TEST_P(FormDataImporterTest, MultiStepImport_TTL) { - base::test::ScopedFeatureList multistep_import_feature_set_ttl; - multistep_import_feature_set_ttl.InitAndEnableFeatureWithParameters( - features::kAutofillEnableMultiStepImports, - {{features::kAutofillMultiStepImportCandidateTTL.name, "30m"}}); TestAutofillClock test_clock; std::unique_ptr<FormStructure> form_structure = ConstructSplitDefaultProfileFormStructure(/*part=*/1); ExtractAddressProfilesAndVerifyExpectation(*form_structure, {}); - test_clock.Advance(base::Minutes(31)); + test_clock.Advance(kMultiStepImportTTL + base::Minutes(1)); form_structure = ConstructSplitDefaultProfileFormStructure(/*part=*/2); ImportAddressProfileAndVerifyImportOfNoProfile(*form_structure); @@ -4310,10 +4280,6 @@ // Tests that multi-step candidates profiles are cleared if the browsing history // is deleted. TEST_P(FormDataImporterTest, MultiStepImport_DeleteOnBrowsingHistoryCleared) { - base::test::ScopedFeatureList multistep_import_feature; - multistep_import_feature.InitAndEnableFeature( - features::kAutofillEnableMultiStepImports); - std::unique_ptr<FormStructure> form_structure = ConstructSplitDefaultProfileFormStructure(/*part=*/1); ExtractAddressProfilesAndVerifyExpectation(*form_structure, {});
diff --git a/components/autofill/core/browser/form_data_importer_utils.cc b/components/autofill/core/browser/form_data_importer_utils.cc index b7ff614..c3ff6b1 100644 --- a/components/autofill/core/browser/form_data_importer_utils.cc +++ b/components/autofill/core/browser/form_data_importer_utils.cc
@@ -208,14 +208,8 @@ void MultiStepImportMerger::ProcessMultiStepImport( AutofillProfile& profile, ProfileImportMetadata& import_metadata) { - if (!base::FeatureList::IsEnabled( - features::kAutofillEnableMultiStepImports)) { - return; - } - - multistep_candidates_.RemoveOutdatedItems( - features::kAutofillMultiStepImportCandidateTTL.Get(), - import_metadata.origin); + multistep_candidates_.RemoveOutdatedItems(kMultiStepImportTTL, + import_metadata.origin); bool has_min_address_requirements = MergeProfileWithMultiStepCandidates(profile, import_metadata); if (!has_min_address_requirements) { @@ -336,13 +330,6 @@ void MultiStepImportMerger::OnPersonalDataChanged( PersonalDataManager& personal_data_manager) { - // Complete profiles are only stored if multi-step complements are enabled. - if (!base::FeatureList::IsEnabled( - features::kAutofillEnableMultiStepImports) || - !features::kAutofillEnableMultiStepImportComplements.Get()) { - return; - } - auto it = multistep_candidates_.begin(); while (it != multistep_candidates_.end()) { // `it` might get erased, so `it++` at the end of the loop doesn't suffice.
diff --git a/components/autofill/core/browser/form_data_importer_utils.h b/components/autofill/core/browser/form_data_importer_utils.h index bd9072a..03422fe7 100644 --- a/components/autofill/core/browser/form_data_importer_utils.h +++ b/components/autofill/core/browser/form_data_importer_utils.h
@@ -146,7 +146,6 @@ // candidates and potentially stores it as a multi-step candidate itself. // `profile` and `import_metadata` are updated accordingly, if the profile // can be merged. See `MergeProfileWithMultiStepCandidates()` for details. - // Only applicable when `kAutofillEnableMultiStepImports` is enabled. void ProcessMultiStepImport(AutofillProfile& profile, ProfileImportMetadata& import_metadata); @@ -183,12 +182,11 @@ AutofillProfile& profile, ProfileImportMetadata& import_metadata); - // With AutofillComplementCountryEarly, merging can fail if one profile - // fragment contains an observed country and the complemented country of the - // other profile disagrees with it. This function attempts to make `profile_a` - // and `profile_b` mergeable by removing the complemented country. + // Merging can fail if one profile fragment contains an observed country and + // the complemented country of the other profile disagrees with it. + // This function attempts to make `profile_a` and `profile_b` mergeable by + // removing the complemented country. // If successful, true is returned and the complemented country removed. - // TODO(crbug.com/1287498): Remove AutofillComplementCountryEarly reference. bool MergeableByRemovingIncorrectlyComplementedCountry( AutofillProfile& profile_a, bool& complemented_profile_a,
diff --git a/components/autofill/core/browser/webdata/autofill_table.cc b/components/autofill/core/browser/webdata/autofill_table.cc index 54a5354..7b44b12 100644 --- a/components/autofill/core/browser/webdata/autofill_table.cc +++ b/components/autofill/core/browser/webdata/autofill_table.cc
@@ -1201,10 +1201,6 @@ InitVirtualCardUsageDataTable(); } -bool AutofillTable::IsSyncable() { - return true; -} - bool AutofillTable::MigrateToVersion(int version, bool* update_compatible_version) { if (!db_->is_open()) {
diff --git a/components/autofill/core/browser/webdata/autofill_table.h b/components/autofill/core/browser/webdata/autofill_table.h index e6298ef..ea33068 100644 --- a/components/autofill/core/browser/webdata/autofill_table.h +++ b/components/autofill/core/browser/webdata/autofill_table.h
@@ -520,7 +520,6 @@ // WebDatabaseTable: WebDatabaseTable::TypeKey GetTypeKey() const override; bool CreateTablesIfNecessary() override; - bool IsSyncable() override; bool MigrateToVersion(int version, bool* update_compatible_version) override; // Records the form elements in |elements| in the database in the
diff --git a/components/autofill/core/common/autofill_constants.h b/components/autofill/core/common/autofill_constants.h index 49d31b31..bfc9a235 100644 --- a/components/autofill/core/common/autofill_constants.h +++ b/components/autofill/core/common/autofill_constants.h
@@ -78,6 +78,10 @@ constexpr base::TimeDelta kDisusedDataModelTimeDelta = base::Days(180); constexpr base::TimeDelta kDisusedDataModelDeletionTimeDelta = base::Days(395); +// Defines for how long recently submitted profile fragments are retained in +// memory for multi-step imports. +constexpr base::TimeDelta kMultiStepImportTTL = base::Minutes(5); + // Returns if the entry with the given |use_date| is deletable? (i.e. has not // been used for a long time). bool IsAutofillEntryWithUseDateDeletable(const base::Time& use_date);
diff --git a/components/autofill/core/common/autofill_features.cc b/components/autofill/core/common/autofill_features.cc index 0aa2d76..3dc6299 100644 --- a/components/autofill/core/common/autofill_features.cc +++ b/components/autofill/core/common/autofill_features.cc
@@ -228,22 +228,6 @@ "AutofillEnableImportWhenMultiplePhoneNumbers", base::FEATURE_DISABLED_BY_DEFAULT); -// When enabled, candidate profiles are temporary stored on import, and merged -// with future candidate profiles, to create an importable profile. This makes -// importing from multi-step input flows possible. -BASE_FEATURE(kAutofillEnableMultiStepImports, - "AutofillEnableMultiStepImports", - base::FEATURE_ENABLED_BY_DEFAULT); -// When enabled, imported profiles are stored as multi-step candidates too, -// which enables complementing a recently imported profile during later steps of -// a multi-step input flow. -const base::FeatureParam<bool> kAutofillEnableMultiStepImportComplements{ - &kAutofillEnableMultiStepImports, "enable_multistep_complement", true}; -// Configures the TTL of multi-step import candidates. -const base::FeatureParam<base::TimeDelta> kAutofillMultiStepImportCandidateTTL{ - &kAutofillEnableMultiStepImports, "multistep_candidate_ttl", - base::Minutes(5)}; - // When enabled, phone number local heuristics match empty labels when looking // for composite phone number inputs. E.g. Phone number <input><input>. BASE_FEATURE(kAutofillEnableParsingEmptyPhoneNumberLabels,
diff --git a/components/autofill/core/common/autofill_features.h b/components/autofill/core/common/autofill_features.h index d7f80e0..edccb06 100644 --- a/components/autofill/core/common/autofill_features.h +++ b/components/autofill/core/common/autofill_features.h
@@ -71,13 +71,6 @@ COMPONENT_EXPORT(AUTOFILL) BASE_DECLARE_FEATURE(kAutofillEnableImportWhenMultiplePhoneNumbers); COMPONENT_EXPORT(AUTOFILL) -BASE_DECLARE_FEATURE(kAutofillEnableMultiStepImports); -COMPONENT_EXPORT(AUTOFILL) -extern const base::FeatureParam<bool> kAutofillEnableMultiStepImportComplements; -COMPONENT_EXPORT(AUTOFILL) -extern const base::FeatureParam<base::TimeDelta> - kAutofillMultiStepImportCandidateTTL; -COMPONENT_EXPORT(AUTOFILL) BASE_DECLARE_FEATURE(kAutofillEnableParsingEmptyPhoneNumberLabels); COMPONENT_EXPORT(AUTOFILL) BASE_DECLARE_FEATURE(kAutofillEnableRankingFormulaAddressProfiles);
diff --git a/components/exo/wayland/zcr_remote_shell_impl.cc b/components/exo/wayland/zcr_remote_shell_impl.cc index 929c38a4..67779c8 100644 --- a/components/exo/wayland/zcr_remote_shell_impl.cc +++ b/components/exo/wayland/zcr_remote_shell_impl.cc
@@ -1026,6 +1026,9 @@ caption_button_icon_mask |= 1 << views::CAPTION_BUTTON_ICON_ZOOM; if (mask & ZCR_REMOTE_SURFACE_V1_FRAME_BUTTON_TYPE_CENTER) caption_button_icon_mask |= 1 << views::CAPTION_BUTTON_ICON_CENTER; + if (mask & ZCR_REMOTE_SURFACE_V2_FRAME_BUTTON_TYPE_FLOAT) { + caption_button_icon_mask |= 1 << views::CAPTION_BUTTON_ICON_FLOAT; + } return caption_button_icon_mask; }
diff --git a/components/history/core/browser/history_service.cc b/components/history/core/browser/history_service.cc index 67f1ec3..cf2b4ac 100644 --- a/components/history/core/browser/history_service.cc +++ b/components/history/core/browser/history_service.cc
@@ -1378,6 +1378,7 @@ TRACE_EVENT0("browser", "HistoryService::ScheduleTask"); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); CHECK(backend_task_runner_); + CHECK(!task.is_null()); // TODO(brettw): Do prioritization. // NOTE(mastiz): If this implementation changes, be cautious with implications // for sync, because a) the sync engine (sync thread) post tasks directly to
diff --git a/components/password_manager/core/browser/import/password_importer.cc b/components/password_manager/core/browser/import/password_importer.cc index 546f9db..6408c324 100644 --- a/components/password_manager/core/browser/import/password_importer.cc +++ b/components/password_manager/core/browser/import/password_importer.cc
@@ -518,6 +518,9 @@ conflicts_cache_->start_time, conflicts_cache_->conflicts.size()); conflicts_cache_.reset(); + + base::UmaHistogramCounts1M("PasswordManager.Import.PerFile.ConflictsResolved", + selected_ids.size()); } void PasswordImporter::ConsumePasswords(
diff --git a/components/password_manager/core/browser/import/password_importer_unittest.cc b/components/password_manager/core/browser/import/password_importer_unittest.cc index 078ee87..ff306212 100644 --- a/components/password_manager/core/browser/import/password_importer_unittest.cc +++ b/components/password_manager/core/browser/import/password_importer_unittest.cc
@@ -752,6 +752,8 @@ "PasswordManager.ImportedPasswordsPerUserInCSV", 2, 1); histogram_tester.ExpectUniqueSample( "PasswordManager.Import.PerFile.Conflicts", 1, 1); + histogram_tester.ExpectUniqueSample( + "PasswordManager.Import.PerFile.ConflictsResolved", 1, 1); const password_manager::ImportResults& results = GetImportResults();
diff --git a/components/password_manager/core/browser/leak_detection/leak_detection_check_impl_unittest.cc b/components/password_manager/core/browser/leak_detection/leak_detection_check_impl_unittest.cc index a0a37f4..ec0012f 100644 --- a/components/password_manager/core/browser/leak_detection/leak_detection_check_impl_unittest.cc +++ b/components/password_manager/core/browser/leak_detection/leak_detection_check_impl_unittest.cc
@@ -94,7 +94,7 @@ identity_env().SetCookieAccounts({{info.email, info.gaia}}); identity_env().SetRefreshTokenForAccount(info.account_id); } - leak_check_ = absl::make_unique<LeakDetectionCheckImpl>( + leak_check_ = std::make_unique<LeakDetectionCheckImpl>( &delegate_, identity_test_env_.identity_manager(), base::MakeRefCounted<network::TestSharedURLLoaderFactory>(), api_key); auto mock_request_factory =
diff --git a/components/password_manager/core/browser/password_manager_metrics_util.cc b/components/password_manager/core/browser/password_manager_metrics_util.cc index c0922c2..df6d09b 100644 --- a/components/password_manager/core/browser/password_manager_metrics_util.cc +++ b/components/password_manager/core/browser/password_manager_metrics_util.cc
@@ -359,7 +359,7 @@ if (base::RandInt(0, 9) == 0) { log_value = !is_password_protected; } - base::UmaHistogramBoolean("PasswordManager.IsPasswordProtected", log_value); + base::UmaHistogramBoolean("PasswordManager.IsPasswordProtected2", log_value); } void LogProtectedPasswordHashCounts(size_t gaia_hash_count,
diff --git a/components/password_manager/core/browser/password_manager_metrics_util.h b/components/password_manager/core/browser/password_manager_metrics_util.h index 1fc2e67..7227005 100644 --- a/components/password_manager/core/browser/password_manager_metrics_util.h +++ b/components/password_manager/core/browser/password_manager_metrics_util.h
@@ -652,6 +652,18 @@ kMaxValue = kCredentialRowWithNoteClicked, }; +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. +enum class PasswordManagerShortcutMetric { + // User clicked "Add shortcut" from the UI. + kAddShortcutClicked = 0, + // Shortcut was successfully installed . + kShortcutInstalled = 1, + // User switched profile in the standalone password manager app. + kProfileSwitched = 2, + kMaxValue = kProfileSwitched, +}; + std::string GetPasswordAccountStorageUsageLevelHistogramSuffix( PasswordAccountStorageUsageLevel usage_level);
diff --git a/components/password_manager/core/browser/password_manager_metrics_util_unittest.cc b/components/password_manager/core/browser/password_manager_metrics_util_unittest.cc index 7686edc..e48cc338 100644 --- a/components/password_manager/core/browser/password_manager_metrics_util_unittest.cc +++ b/components/password_manager/core/browser/password_manager_metrics_util_unittest.cc
@@ -99,7 +99,7 @@ LogIsPasswordProtected(false); // Not testing individual bucket counts since we have 10% random noise - histogram_tester.ExpectTotalCount("PasswordManager.IsPasswordProtected", 2); + histogram_tester.ExpectTotalCount("PasswordManager.IsPasswordProtected2", 2); } } // namespace password_manager::metrics_util
diff --git a/components/password_manager/core/browser/store_metrics_reporter.cc b/components/password_manager/core/browser/store_metrics_reporter.cc index f69bd10..aaba0d2 100644 --- a/components/password_manager/core/browser/store_metrics_reporter.cc +++ b/components/password_manager/core/browser/store_metrics_reporter.cc
@@ -424,9 +424,11 @@ void ReportPasswordProtectedMetrics( const std::vector<std::unique_ptr<PasswordForm>>& forms) { for (const std::unique_ptr<PasswordForm>& form : forms) { - metrics_util::LogIsPasswordProtected( - form->password_value.size() >= - password_manager::kMinPasswordLengthToCheck); + if (!form->blocked_by_user && form->password_value.size() > 0) { + metrics_util::LogIsPasswordProtected( + form->password_value.size() >= + password_manager::kMinPasswordLengthToCheck); + } } }
diff --git a/components/password_manager/core/browser/store_metrics_reporter_unittest.cc b/components/password_manager/core/browser/store_metrics_reporter_unittest.cc index 97cb499..b244be95 100644 --- a/components/password_manager/core/browser/store_metrics_reporter_unittest.cc +++ b/components/password_manager/core/browser/store_metrics_reporter_unittest.cc
@@ -19,6 +19,7 @@ #include "components/password_manager/core/browser/password_form.h" #include "components/password_manager/core/browser/password_manager_features_util.h" #include "components/password_manager/core/browser/password_manager_metrics_util.h" +#include "components/password_manager/core/browser/password_manager_util.h" #include "components/password_manager/core/browser/stub_password_manager_client.h" #include "components/password_manager/core/browser/sync_username_test_base.h" #include "components/password_manager/core/browser/test_password_store.h" @@ -428,19 +429,19 @@ // Since there is 10% noise in this histogram, we can't deterministically say // what the exact sample count for each bucket will be. Instead, test that the // number of samples is within a reasonable range. - histogram_tester.ExpectTotalCount("PasswordManager.IsPasswordProtected", + histogram_tester.ExpectTotalCount("PasswordManager.IsPasswordProtected2", kTotalAccountAndProfileLogins); EXPECT_GE(histogram_tester.GetBucketCount( - "PasswordManager.IsPasswordProtected", true), + "PasswordManager.IsPasswordProtected2", true), 0.4 * kTotalAccountAndProfileLogins); EXPECT_LE(histogram_tester.GetBucketCount( - "PasswordManager.IsPasswordProtected", true), + "PasswordManager.IsPasswordProtected2", true), 0.6 * kTotalAccountAndProfileLogins); EXPECT_GE(histogram_tester.GetBucketCount( - "PasswordManager.IsPasswordProtected", false), + "PasswordManager.IsPasswordProtected2", false), 0.4 * kTotalAccountAndProfileLogins); EXPECT_LE(histogram_tester.GetBucketCount( - "PasswordManager.IsPasswordProtected", false), + "PasswordManager.IsPasswordProtected2", false), 0.6 * kTotalAccountAndProfileLogins); profile_store->ShutdownOnUIThread(); @@ -450,6 +451,52 @@ RunUntilIdle(); } +TEST_F(StoreMetricsReporterTest, + ReportPasswordProtectedMetricsTestWithBlockedPasswords) { + // Set up custom preferences for this test because we want safe browsing + // enabled + prefs_.SetBoolean(::prefs::kSafeBrowsingEnabled, true); + + // Add both non-blocking and blocking credentials to stores + const std::string kRealm1 = "https://example1.com"; + const std::string kRealm2 = "https://example2.com"; + const std::string kRealm3 = "https://example3.com"; + auto profile_store = + base::MakeRefCounted<TestPasswordStore>(IsAccountStore(false)); + profile_store->Init(&prefs_, + /*affiliated_match_helper=*/nullptr); + profile_store->AddLogin(CreateForm(kRealm1, "aprofileuser", "aprofilepass")); + profile_store->AddLogin(password_manager_util::MakeNormalizedBlocklistedForm( + PasswordFormDigest(PasswordForm::Scheme::kHtml, kRealm2, GURL(kRealm2)))); + auto account_store = + base::MakeRefCounted<TestPasswordStore>(IsAccountStore(true)); + account_store->Init(&prefs_, + /*affiliated_match_helper=*/nullptr); + account_store->AddLogin( + CreateForm(kRealm1, "anaccountuser", "anaccountpass")); + account_store->AddLogin(password_manager_util::MakeNormalizedBlocklistedForm( + PasswordFormDigest(PasswordForm::Scheme::kHtml, kRealm3, GURL(kRealm3)))); + + base::HistogramTester histogram_tester; + StoreMetricsReporter reporter(profile_store.get(), account_store.get(), + sync_service(), identity_manager(), &prefs_, + /*password_reuse_manager=*/nullptr, + /*is_under_advanced_protection=*/false, + /*done_callback*/ base::DoNothing()); + // Wait for the metrics to get reported, which involves queries to the + // stores, i.e. to background task runners. + RunUntilIdle(); + + // We expect that our histogram logs for only non-blocking credentials. + histogram_tester.ExpectTotalCount("PasswordManager.IsPasswordProtected2", 2); + + profile_store->ShutdownOnUIThread(); + account_store->ShutdownOnUIThread(); + // Make sure the PasswordStore destruction parts on the background sequence + // finish, otherwise we get memory leak reports. + RunUntilIdle(); +} + TEST_F(StoreMetricsReporterTest, ReportTotalAccountsHiResMetricsTest) { auto profile_store = base::MakeRefCounted<TestPasswordStore>(IsAccountStore(false));
diff --git a/components/payments/content/payment_method_manifest_table.cc b/components/payments/content/payment_method_manifest_table.cc index 960988b..3546e52a 100644 --- a/components/payments/content/payment_method_manifest_table.cc +++ b/components/payments/content/payment_method_manifest_table.cc
@@ -90,10 +90,6 @@ return true; } -bool PaymentMethodManifestTable::IsSyncable() { - return false; -} - bool PaymentMethodManifestTable::MigrateToVersion( int version, bool* update_compatible_version) {
diff --git a/components/payments/content/payment_method_manifest_table.h b/components/payments/content/payment_method_manifest_table.h index 9cb09b74d..1354662 100644 --- a/components/payments/content/payment_method_manifest_table.h +++ b/components/payments/content/payment_method_manifest_table.h
@@ -59,7 +59,6 @@ // WebDatabaseTable: WebDatabaseTable::TypeKey GetTypeKey() const override; bool CreateTablesIfNecessary() override; - bool IsSyncable() override; bool MigrateToVersion(int version, bool* update_compatible_version) override; // Remove expired data.
diff --git a/components/payments/content/web_app_manifest_section_table.cc b/components/payments/content/web_app_manifest_section_table.cc index 6506fd09..17fc754 100644 --- a/components/payments/content/web_app_manifest_section_table.cc +++ b/components/payments/content/web_app_manifest_section_table.cc
@@ -91,10 +91,6 @@ return true; } -bool WebAppManifestSectionTable::IsSyncable() { - return false; -} - bool WebAppManifestSectionTable::MigrateToVersion( int version, bool* update_compatible_version) {
diff --git a/components/payments/content/web_app_manifest_section_table.h b/components/payments/content/web_app_manifest_section_table.h index 24d37fd..3f83488 100644 --- a/components/payments/content/web_app_manifest_section_table.h +++ b/components/payments/content/web_app_manifest_section_table.h
@@ -45,7 +45,6 @@ // WebDatabaseTable: WebDatabaseTable::TypeKey GetTypeKey() const override; bool CreateTablesIfNecessary() override; - bool IsSyncable() override; bool MigrateToVersion(int version, bool* update_compatible_version) override; // Remove expired data.
diff --git a/components/permissions/permission_request.cc b/components/permissions/permission_request.cc index 10f2d44..2d2d18f 100644 --- a/components/permissions/permission_request.cc +++ b/components/permissions/permission_request.cc
@@ -235,6 +235,10 @@ } #endif +bool PermissionRequest::ShouldUseTwoOriginPrompt() const { + return request_type_ == RequestType::kStorageAccess; +} + void PermissionRequest::PermissionGranted(bool is_one_time) { std::move(permission_decided_callback_) .Run(CONTENT_SETTING_ALLOW, is_one_time,
diff --git a/components/permissions/permission_request.h b/components/permissions/permission_request.h index 0328b53..2198968c 100644 --- a/components/permissions/permission_request.h +++ b/components/permissions/permission_request.h
@@ -109,6 +109,10 @@ virtual std::u16string GetMessageTextFragment() const; #endif + // Returns true if the request has two origins and should use the two origin + // prompt. Returns false otherwise. + bool ShouldUseTwoOriginPrompt() const; + // Called when the user has granted the requested permission. // If |is_one_time| is true the permission will last until all tabs of // |origin| are closed or navigated away from, and then the permission will
diff --git a/components/permissions/test/mock_permission_prompt.cc b/components/permissions/test/mock_permission_prompt.cc index 5e5594b8..578fea33 100644 --- a/components/permissions/test/mock_permission_prompt.cc +++ b/components/permissions/test/mock_permission_prompt.cc
@@ -60,6 +60,8 @@ EXPECT_FALSE(request->GetMessageTextFragment().empty()); EXPECT_FALSE(permissions::GetIconId(request_type).is_empty()); #endif + EXPECT_EQ(request->ShouldUseTwoOriginPrompt(), + request_type == permissions::RequestType::kStorageAccess); } }
diff --git a/components/policy/resources/templates/policy_definitions/Network/DnsOverHttpsTemplatesWithIdentifiers.yaml b/components/policy/resources/templates/policy_definitions/Network/DnsOverHttpsTemplatesWithIdentifiers.yaml index e2efeb5..75cd9841 100644 --- a/components/policy/resources/templates/policy_definitions/Network/DnsOverHttpsTemplatesWithIdentifiers.yaml +++ b/components/policy/resources/templates/policy_definitions/Network/DnsOverHttpsTemplatesWithIdentifiers.yaml
@@ -8,7 +8,7 @@ If the URI template contains a <ph name="HTTP_VARIABLE_DNS">dns</ph> variable, requests to the resolver will use <ph name="HTTP_METHOD_GET">GET</ph>; otherwise requests will use <ph name="HTTP_METHOD_POST">POST</ph>. - In version 114 and later, <ph name="DOH_SALT_POLICY_NAME">DnsOverHttpsSalt</ph>is optional if this policy is set. + In version 114 and later, <ph name="DOH_SALT_POLICY_NAME">DnsOverHttpsSalt</ph> is optional if this policy is set. example_value: https://dns.example.net/dns-query{?dns} features: dynamic_refresh: true
diff --git a/components/reading_list/core/BUILD.gn b/components/reading_list/core/BUILD.gn index e9330eb7..836a1a680 100644 --- a/components/reading_list/core/BUILD.gn +++ b/components/reading_list/core/BUILD.gn
@@ -73,6 +73,7 @@ ":test_support", "//base", "//base/test:test_support", + "//components/reading_list/features:flags", "//components/sync", "//components/sync:test_support", "//testing/gtest",
diff --git a/components/reading_list/core/dual_reading_list_model.cc b/components/reading_list/core/dual_reading_list_model.cc index c6a5eed..088a5a47 100644 --- a/components/reading_list/core/dual_reading_list_model.cc +++ b/components/reading_list/core/dual_reading_list_model.cc
@@ -222,9 +222,11 @@ DCHECK(!local_or_syncable_model_->IsTrackingSyncMetadata() || !account_model_->IsTrackingSyncMetadata()); - return account_model_->IsTrackingSyncMetadata() && + return !local_or_syncable_model_->IsTrackingSyncMetadata() && local_or_syncable_model_->GetEntryByURL(url) != nullptr && - account_model_->GetEntryByURL(url) == nullptr; + account_model_->GetEntryByURL(url) == nullptr && + base::FeatureList::IsEnabled( + switches::kReadingListEnableSyncTransportModeUponSignIn); } const ReadingListEntry& DualReadingListModel::AddOrReplaceEntry(
diff --git a/components/reading_list/core/dual_reading_list_model_unittest.cc b/components/reading_list/core/dual_reading_list_model_unittest.cc index 1cb051ad..b3998a2 100644 --- a/components/reading_list/core/dual_reading_list_model_unittest.cc +++ b/components/reading_list/core/dual_reading_list_model_unittest.cc
@@ -6,12 +6,14 @@ #include "base/files/file_path.h" #include "base/memory/scoped_refptr.h" +#include "base/test/scoped_feature_list.h" #include "base/test/simple_test_clock.h" #include "base/time/time.h" #include "components/reading_list/core/fake_reading_list_model_storage.h" #include "components/reading_list/core/mock_reading_list_model_observer.h" #include "components/reading_list/core/reading_list_entry.h" #include "components/reading_list/core/reading_list_model_impl.h" +#include "components/reading_list/features/reading_list_switches.h" #include "components/sync/base/storage_type.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" @@ -655,18 +657,26 @@ } TEST_F(DualReadingListModelTest, NeedsExplicitUploadToSyncServerWhenSignedOut) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature( + switches::kReadingListEnableSyncTransportModeUponSignIn); + ASSERT_TRUE(ResetStorageAndMimicSignedOut(/*initial_local_entries_builders=*/{ TestEntryBuilder(kUrl, clock_.Now())})); ASSERT_EQ(dual_model_->GetStorageStateForURLForTesting(kUrl), StorageStateForTesting::kExistsInLocalOrSyncableModelOnly); - EXPECT_FALSE(dual_model_->NeedsExplicitUploadToSyncServer(kUrl)); + EXPECT_TRUE(dual_model_->NeedsExplicitUploadToSyncServer(kUrl)); EXPECT_FALSE(dual_model_->NeedsExplicitUploadToSyncServer( GURL("http://non_existing_url.com/"))); } TEST_F(DualReadingListModelTest, NeedsExplicitUploadToSyncServerWhenSignedInSyncDisabled) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature( + switches::kReadingListEnableSyncTransportModeUponSignIn); + const GURL kLocalURL("http://local_url.com/"); const GURL kAccountURL("http://account_url.com/"); const GURL kCommonURL("http://common_url.com/"); @@ -694,6 +704,10 @@ TEST_F(DualReadingListModelTest, NeedsExplicitUploadToSyncServerWhenSyncEnabled) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature( + switches::kReadingListEnableSyncTransportModeUponSignIn); + ASSERT_TRUE( ResetStorageAndMimicSyncEnabled(/*initial_syncable_entries_builders=*/{ TestEntryBuilder(kUrl, clock_.Now())}));
diff --git a/components/search_engines/keyword_table.cc b/components/search_engines/keyword_table.cc index b32e1f6..ad6afc9 100644 --- a/components/search_engines/keyword_table.cc +++ b/components/search_engines/keyword_table.cc
@@ -228,10 +228,6 @@ "enforced_by_policy INTEGER DEFAULT 0)"); } -bool KeywordTable::IsSyncable() { - return true; -} - bool KeywordTable::MigrateToVersion(int version, bool* update_compatible_version) { // Migrate if necessary.
diff --git a/components/search_engines/keyword_table.h b/components/search_engines/keyword_table.h index dd9c45b5..952d9e1 100644 --- a/components/search_engines/keyword_table.h +++ b/components/search_engines/keyword_table.h
@@ -109,7 +109,6 @@ WebDatabaseTable::TypeKey GetTypeKey() const override; bool CreateTablesIfNecessary() override; - bool IsSyncable() override; bool MigrateToVersion(int version, bool* update_compatible_version) override; // Performs an arbitrary number of Add/Remove/Update operations as a single
diff --git a/components/segmentation_platform/embedder/default_model/device_switcher_result_dispatcher.h b/components/segmentation_platform/embedder/default_model/device_switcher_result_dispatcher.h index 1ff20bc..05e2181 100644 --- a/components/segmentation_platform/embedder/default_model/device_switcher_result_dispatcher.h +++ b/components/segmentation_platform/embedder/default_model/device_switcher_result_dispatcher.h
@@ -39,12 +39,13 @@ // Called to get the classification result synchronously. If none, returns // empty result. - ClassificationResult GetCachedClassificationResult(); + virtual ClassificationResult GetCachedClassificationResult(); // Called to get the classification results from prefs if it exists, else it // will wait for results and return when available. Handles only one request // at a time. - void WaitForClassificationResult(ClassificationResultCallback callback); + virtual void WaitForClassificationResult( + ClassificationResultCallback callback); // Registers preferences used by this class in the provided |registry|. static void RegisterProfilePrefs(PrefRegistrySimple* registry);
diff --git a/components/signin/public/webdata/token_service_table.cc b/components/signin/public/webdata/token_service_table.cc index 62e1de7..0467e4e 100644 --- a/components/signin/public/webdata/token_service_table.cc +++ b/components/signin/public/webdata/token_service_table.cc
@@ -53,10 +53,6 @@ return true; } -bool TokenServiceTable::IsSyncable() { - return true; -} - bool TokenServiceTable::MigrateToVersion(int version, bool* update_compatible_version) { return true;
diff --git a/components/signin/public/webdata/token_service_table.h b/components/signin/public/webdata/token_service_table.h index b3c0e58..9a0d5364 100644 --- a/components/signin/public/webdata/token_service_table.h +++ b/components/signin/public/webdata/token_service_table.h
@@ -34,7 +34,6 @@ WebDatabaseTable::TypeKey GetTypeKey() const override; bool CreateTablesIfNecessary() override; - bool IsSyncable() override; bool MigrateToVersion(int version, bool* update_compatible_version) override; // Remove all tokens previously set with SetTokenForService.
diff --git a/components/sync/BUILD.gn b/components/sync/BUILD.gn index 990f9aba..4abd44ac 100644 --- a/components/sync/BUILD.gn +++ b/components/sync/BUILD.gn
@@ -150,6 +150,10 @@ "//components/prefs:test_support", "//components/signin/public/base", "//components/signin/public/identity_manager:test_support", + + # TODO(crbug.com/1423343): remove dependency on trusted_vault/proto once + # FakeSecurityDomainsServer is moved under trusted_vault. + "//components/trusted_vault/proto", "//components/version_info", "//components/version_info:generate_version_info", "//google_apis",
diff --git a/components/sync/base/sync_prefs.cc b/components/sync/base/sync_prefs.cc index a573563..3b2ecd888 100644 --- a/components/sync/base/sync_prefs.cc +++ b/components/sync/base/sync_prefs.cc
@@ -36,10 +36,6 @@ prefs::kSyncFirstSetupComplete, pref_service_, base::BindRepeating(&SyncPrefs::OnFirstSetupCompletePrefChange, base::Unretained(this))); - pref_sync_requested_.Init( - prefs::kSyncRequested, pref_service_, - base::BindRepeating(&SyncPrefs::OnSyncRequestedPrefChange, - base::Unretained(this))); // Cache the value of the kEnableLocalSyncBackend pref to avoid it flipping // during the lifetime of the service. @@ -118,14 +114,12 @@ pref_service_->SetBoolean(prefs::kSyncRequested, is_requested); } -void SyncPrefs::SetSyncRequestedIfNotSetExplicitly() { +bool SyncPrefs::IsSyncRequestedSetExplicitly() const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // GetUserPrefValue() returns nullptr if there is no user-set value for this // pref (there might still be a non-default value, e.g. from a policy, but we // explicitly don't care about that here). - if (!pref_service_->GetUserPrefValue(prefs::kSyncRequested)) { - pref_service_->SetBoolean(prefs::kSyncRequested, true); - } + return pref_service_->GetUserPrefValue(prefs::kSyncRequested) != nullptr; } bool SyncPrefs::HasKeepEverythingSynced() const { @@ -307,12 +301,6 @@ observer.OnFirstSetupCompletePrefChange(*pref_first_setup_complete_); } -void SyncPrefs::OnSyncRequestedPrefChange() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - for (SyncPrefObserver& observer : sync_pref_observers_) - observer.OnSyncRequestedPrefChange(*pref_sync_requested_); -} - // static void SyncPrefs::RegisterTypeSelectedPref(PrefRegistrySimple* registry, UserSelectableType type) {
diff --git a/components/sync/base/sync_prefs.h b/components/sync/base/sync_prefs.h index e2146c78..002cbb4b 100644 --- a/components/sync/base/sync_prefs.h +++ b/components/sync/base/sync_prefs.h
@@ -28,7 +28,6 @@ public: virtual void OnSyncManagedPrefChange(bool is_sync_managed) = 0; virtual void OnFirstSetupCompletePrefChange(bool is_first_setup_complete) = 0; - virtual void OnSyncRequestedPrefChange(bool is_sync_requested) = 0; virtual void OnPreferredDataTypesPrefChange() = 0; protected: @@ -60,9 +59,15 @@ void SetFirstSetupComplete(); void ClearFirstSetupComplete(); + // Whether the user wants Sync to run. This is false by default, but gets set + // to true early in the Sync setup flow, after the user has pressed "turn on + // Sync" but before they have actually confirmed the settings (that's + // IsFirstSetupComplete()). After Sync is enabled, this can get set to false + // via signout (which also clears IsFirstSetupComplete) or, on ChromeOS Ash, + // when Sync gets reset from the dashboard. bool IsSyncRequested() const; void SetSyncRequested(bool is_requested); - void SetSyncRequestedIfNotSetExplicitly(); + bool IsSyncRequestedSetExplicitly() const; bool HasKeepEverythingSynced() const; @@ -127,7 +132,6 @@ void OnSyncManagedPrefChanged(); void OnFirstSetupCompletePrefChange(); - void OnSyncRequestedPrefChange(); // Never null. const raw_ptr<PrefService> pref_service_; @@ -140,8 +144,6 @@ BooleanPrefMember pref_first_setup_complete_; - BooleanPrefMember pref_sync_requested_; - bool local_sync_enabled_; SEQUENCE_CHECKER(sequence_checker_);
diff --git a/components/sync/base/sync_prefs_unittest.cc b/components/sync/base/sync_prefs_unittest.cc index 490a8767..76c93706 100644 --- a/components/sync/base/sync_prefs_unittest.cc +++ b/components/sync/base/sync_prefs_unittest.cc
@@ -49,7 +49,6 @@ public: MOCK_METHOD(void, OnSyncManagedPrefChange, (bool), (override)); MOCK_METHOD(void, OnFirstSetupCompletePrefChange, (bool), (override)); - MOCK_METHOD(void, OnSyncRequestedPrefChange, (bool), (override)); MOCK_METHOD(void, OnPreferredDataTypesPrefChange, (), (override)); }; @@ -60,8 +59,6 @@ EXPECT_CALL(mock_sync_pref_observer, OnSyncManagedPrefChange(false)); EXPECT_CALL(mock_sync_pref_observer, OnFirstSetupCompletePrefChange(true)); EXPECT_CALL(mock_sync_pref_observer, OnFirstSetupCompletePrefChange(false)); - EXPECT_CALL(mock_sync_pref_observer, OnSyncRequestedPrefChange(true)); - EXPECT_CALL(mock_sync_pref_observer, OnSyncRequestedPrefChange(false)); ASSERT_FALSE(sync_prefs_->IsSyncClientDisabledByPolicy()); ASSERT_FALSE(sync_prefs_->IsFirstSetupComplete());
diff --git a/components/sync/driver/sync_service_impl.cc b/components/sync/driver/sync_service_impl.cc index 86ddd9be..927f968 100644 --- a/components/sync/driver/sync_service_impl.cc +++ b/components/sync/driver/sync_service_impl.cc
@@ -158,7 +158,6 @@ base::BindRepeating(&CreateHttpBridgeFactory)), start_behavior_(init_params.start_behavior), is_regular_profile_for_uma_(init_params.is_regular_profile_for_uma), - is_setting_sync_requested_(false), should_record_trusted_vault_error_shown_on_startup_(true), #if BUILDFLAG(IS_ANDROID) sessions_invalidations_enabled_(false) { @@ -254,8 +253,9 @@ // Local Sync bypasses the IsSyncRequested() check, so no need to set it in // that case. // TODO(crbug.com/920158): Get rid of AUTO_START and remove this workaround. - if (start_behavior_ == AUTO_START && !IsLocalSyncEnabled()) { - sync_prefs_.SetSyncRequestedIfNotSetExplicitly(); + if (start_behavior_ == AUTO_START && !IsLocalSyncEnabled() && + !sync_prefs_.IsSyncRequestedSetExplicitly()) { + SetSyncFeatureRequested(); } bool force_immediate = (start_behavior_ == AUTO_START && !HasDisableReason(DISABLE_REASON_USER_CHOICE) && @@ -600,6 +600,18 @@ void SyncServiceImpl::SetSyncFeatureRequested() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); sync_prefs_.SetSyncRequested(true); + + // If the Sync engine was already initialized (probably running in transport + // mode), just reconfigure. + if (engine_ && engine_->IsInitialized()) { + ReconfigureDatatypeManager(/*bypass_setup_in_progress_check=*/false); + } else { + // Otherwise try to start up. Note that there might still be other disable + // reasons remaining, in which case this will effectively do nothing. + startup_controller_->TryStart(/*force_immediate=*/true); + } + + NotifyObservers(); } SyncUserSettings* SyncServiceImpl::GetUserSettings() { @@ -628,7 +640,7 @@ if (!IsSignedIn()) { result.Put(DISABLE_REASON_NOT_SIGNED_IN); } - if (!user_settings_->IsSyncRequested()) { + if (!sync_prefs_.IsSyncRequested()) { result.Put(DISABLE_REASON_USER_CHOICE); } } @@ -1550,34 +1562,6 @@ } } -void SyncServiceImpl::OnSyncRequestedPrefChange(bool is_sync_requested) { - // Ignore the notification if the service itself set the pref. - if (is_setting_sync_requested_) { - is_setting_sync_requested_ = false; - return; - } - - if (is_sync_requested) { - // If the Sync engine was already initialized (probably running in transport - // mode), just reconfigure. - if (engine_ && engine_->IsInitialized()) { - ReconfigureDatatypeManager(/*bypass_setup_in_progress_check=*/false); - } else { - // Otherwise try to start up. Note that there might still be other disable - // reasons remaining, in which case this will effectively do nothing. - startup_controller_->TryStart(/*force_immediate=*/true); - } - - NotifyObservers(); - } else { - // This will notify the observers. - // TODO(crbug.com/856179): Evaluate whether we can get away without a - // full restart in this case (i.e. just reconfigure). - ResetEngine(ShutdownReason::STOP_SYNC_AND_KEEP_DATA, - ResetEngineReason::kRequestedPrefChange); - } -} - void SyncServiceImpl::OnAccountsInCookieUpdated( const signin::AccountsInCookieJarInfo& accounts_in_cookie_jar_info, const GoogleServiceAuthError& error) { @@ -1796,18 +1780,7 @@ // will need to reenter it if sync gets re-enabled. sync_prefs_.ClearEncryptionBootstrapToken(); - // Clear the sync-requested bit, but avoid side effects in - // OnSyncRequestedPrefChange() by leveraging |is_setting_sync_requested_|. - // - // For a no-op, OnSyncRequestedPrefChange() wouldn't be called and - // |is_setting_sync_requested_| wouldn't get reset, so check. - if (user_settings_->IsSyncRequested()) { - CHECK(!is_setting_sync_requested_); - is_setting_sync_requested_ = true; - user_settings_->ClearSyncRequested(); - // OnSyncRequestedPrefChange() should have cleared the flag. - CHECK(!is_setting_sync_requested_); - } + sync_prefs_.SetSyncRequested(false); // Also let observers know that Sync-the-feature is now fully disabled // (before it possibly starts up again in transport-only mode).
diff --git a/components/sync/driver/sync_service_impl.h b/components/sync/driver/sync_service_impl.h index 40e7bac..222e5db 100644 --- a/components/sync/driver/sync_service_impl.h +++ b/components/sync/driver/sync_service_impl.h
@@ -198,7 +198,6 @@ // SyncPrefObserver implementation. void OnSyncManagedPrefChange(bool is_sync_managed) override; void OnFirstSetupCompletePrefChange(bool is_first_setup_complete) override; - void OnSyncRequestedPrefChange(bool is_sync_requested) override; void OnPreferredDataTypesPrefChange() override; // KeyedService implementation. This must be called exactly @@ -446,10 +445,6 @@ // lockscreen profiles on Ash. const bool is_regular_profile_for_uma_; - // Used in OnSyncRequestedPrefChange() to know whether the notification was - // caused by the service itself setting the pref. - bool is_setting_sync_requested_; - // Used for UMA to determine whether TrustedVaultErrorShownOnStartup // histogram needs to recorded. Set to false iff histogram was already // recorded or trusted vault passphrase type wasn't used on startup.
diff --git a/components/sync/driver/sync_user_settings_impl.cc b/components/sync/driver/sync_user_settings_impl.cc index b0beec2..845d2d6 100644 --- a/components/sync/driver/sync_user_settings_impl.cc +++ b/components/sync/driver/sync_user_settings_impl.cc
@@ -70,10 +70,6 @@ SyncUserSettingsImpl::~SyncUserSettingsImpl() = default; -bool SyncUserSettingsImpl::IsSyncRequested() const { - return prefs_->IsSyncRequested(); -} - bool SyncUserSettingsImpl::IsFirstSetupComplete() const { return prefs_->IsFirstSetupComplete(); } @@ -252,10 +248,6 @@ return crypto_->GetDecryptionNigoriKey(); } -void SyncUserSettingsImpl::ClearSyncRequested() { - prefs_->SetSyncRequested(false); -} - ModelTypeSet SyncUserSettingsImpl::GetPreferredDataTypes() const { ModelTypeSet types = UserSelectableTypesToModelTypes(GetSelectedTypes()); types.PutAll(AlwaysPreferredUserTypes());
diff --git a/components/sync/driver/sync_user_settings_impl.h b/components/sync/driver/sync_user_settings_impl.h index dc45b4a9..75919c34 100644 --- a/components/sync/driver/sync_user_settings_impl.h +++ b/components/sync/driver/sync_user_settings_impl.h
@@ -68,17 +68,6 @@ void SetDecryptionNigoriKey(std::unique_ptr<Nigori> nigori) override; std::unique_ptr<Nigori> GetDecryptionNigoriKey() const override; - // Whether the user wants Sync to run. This is false by default, but gets set - // to true early in the Sync setup flow, after the user has pressed "turn on - // Sync" but before they have actually confirmed the settings (that's - // IsFirstSetupComplete()). After Sync is enabled, this can get set to false - // via signout (which also clears IsFirstSetupComplete) or, on ChromeOS Ash, - // when Sync gets reset from the dashboard. - // - // This maps to DISABLE_REASON_USER_CHOICE. - bool IsSyncRequested() const; - void ClearSyncRequested(); - ModelTypeSet GetPreferredDataTypes() const; bool IsEncryptedDatatypeEnabled() const;
diff --git a/components/sync/protocol/protocol_sources.gni b/components/sync/protocol/protocol_sources.gni index 877ac18..094bfdb 100644 --- a/components/sync/protocol/protocol_sources.gni +++ b/components/sync/protocol/protocol_sources.gni
@@ -32,7 +32,6 @@ "history_delete_directive_specifics.proto", "history_specifics.proto", "history_status.proto", - "local_trusted_vault.proto", "loopback_server.proto", "managed_user_setting_specifics.proto", "managed_user_shared_setting_specifics.proto",
diff --git a/components/sync/protocol/vault.proto b/components/sync/protocol/vault.proto index 71c3b8c1..0ef126e5 100644 --- a/components/sync/protocol/vault.proto +++ b/components/sync/protocol/vault.proto
@@ -4,6 +4,9 @@ // Trusted vault protos to communicate with backend written in proto3 to avoid // subtle differences between enum fields. + +// TODO(crbug.com/1423343): Delete this file once downstream references are +// updated to use components/trusted_vault/proto. syntax = "proto3"; option java_multiple_files = true;
diff --git a/components/sync/test/fake_security_domains_server.cc b/components/sync/test/fake_security_domains_server.cc index 8f57902..b2f5fc4 100644 --- a/components/sync/test/fake_security_domains_server.cc +++ b/components/sync/test/fake_security_domains_server.cc
@@ -29,8 +29,8 @@ std::unique_ptr<net::test_server::HttpResponse> CreateHttpResponseForSuccessfulJoinSecurityDomainsRequest(int current_epoch) { - sync_pb::JoinSecurityDomainsResponse response_proto; - sync_pb::SecurityDomain* security_domain = + trusted_vault_pb::JoinSecurityDomainsResponse response_proto; + trusted_vault_pb::SecurityDomain* security_domain = response_proto.mutable_security_domain(); security_domain->set_name(kSyncSecurityDomainName); security_domain->set_current_epoch(current_epoch); @@ -43,7 +43,7 @@ // Returns whether |request| satisfies protocol expectations. bool ValidateJoinSecurityDomainsRequest( - const sync_pb::JoinSecurityDomainsRequest& request) { + const trusted_vault_pb::JoinSecurityDomainsRequest& request) { if (request.security_domain().name() != kSyncSecurityDomainName) { DVLOG(1) << "JoinSecurityDomains request has unexpected security domain name: " @@ -51,7 +51,7 @@ return false; } - const sync_pb::SecurityDomainMember& member = + const trusted_vault_pb::SecurityDomainMember& member = request.security_domain_member(); if (member.public_key().empty()) { DVLOG(1) << "JoinSecurityDomains request has empty member public key"; @@ -80,7 +80,7 @@ DVLOG(1) << "JoinSecurityDomains request has no shared keys"; return false; } - for (const sync_pb::SharedMemberKey& shared_key : + for (const trusted_vault_pb::SharedMemberKey& shared_key : request.shared_member_key()) { if (shared_key.wrapped_key().empty()) { DVLOG(1) << "JoinSecurityDomains request has shared key with empty " @@ -101,7 +101,7 @@ // Verifies that shared keys passed as part of the |request| match // |trusted_vault_keys|. bool VerifySharedKeys( - const sync_pb::JoinSecurityDomainsRequest& request, + const trusted_vault_pb::JoinSecurityDomainsRequest& request, const std::vector<std::vector<uint8_t>>& trusted_vault_keys) { if (request.shared_member_key_size() != static_cast<int>(trusted_vault_keys.size())) { @@ -225,7 +225,7 @@ SecureBoxPublicKey::CreateByImport(ProtoStringToBytes(member)); DCHECK(member_public_key); - sync_pb::SharedMemberKey new_shared_key; + trusted_vault_pb::SharedMemberKey new_shared_key; new_shared_key.set_epoch(state_.current_epoch); AssignBytesToProtoString(ComputeTrustedVaultWrappedKey( *member_public_key, new_trusted_vault_key), @@ -235,7 +235,7 @@ new_shared_key.mutable_member_proof()); shared_key.push_back(new_shared_key); - sync_pb::RotationProof rotation_proof; + trusted_vault_pb::RotationProof rotation_proof; rotation_proof.set_new_epoch(state_.current_epoch); AssignBytesToProtoString( ComputeRotationProofForTesting( @@ -284,7 +284,7 @@ SecureBoxPublicKey::CreateByImport(ProtoStringToBytes(public_key)); DCHECK(member_public_key); - for (const sync_pb::SharedMemberKey& shared_key : shared_keys) { + for (const trusted_vault_pb::SharedMemberKey& shared_key : shared_keys) { // Member has |trusted_vault_key| if there is a member proof signed by // |trusted_vault_key|. if (VerifyMemberProof(*member_public_key, trusted_vault_key, @@ -333,7 +333,7 @@ // TODO(crbug.com/1113599): consider verifying content type and access token // headers. - sync_pb::JoinSecurityDomainsRequest deserialized_content; + trusted_vault_pb::JoinSecurityDomainsRequest deserialized_content; if (!deserialized_content.ParseFromString(http_request.content)) { DVLOG(1) << "Failed to deserialize JoinSecurityDomains request content"; state_.received_invalid_request = true; @@ -345,7 +345,7 @@ return CreateErrorResponse(net::HTTP_BAD_REQUEST); } - const sync_pb::SecurityDomainMember& member = + const trusted_vault_pb::SecurityDomainMember& member = deserialized_content.security_domain_member(); if (state_.public_key_to_shared_keys.count(member.public_key()) != 0) { // Member already exists. @@ -376,7 +376,7 @@ } state_.public_key_to_shared_keys[member.public_key()] = - std::vector<sync_pb::SharedMemberKey>( + std::vector<trusted_vault_pb::SharedMemberKey>( deserialized_content.shared_member_key().begin(), deserialized_content.shared_member_key().end()); return CreateHttpResponseForSuccessfulJoinSecurityDomainsRequest( @@ -400,7 +400,7 @@ DVLOG(1) << "Member requested in GetSecurityDomainMemberRequest not found"; return CreateErrorResponse(net::HTTP_NOT_FOUND); } - sync_pb::SecurityDomainMember member; + trusted_vault_pb::SecurityDomainMember member; std::string encoded_public_key; base::Base64UrlEncode(member_public_key, @@ -410,20 +410,20 @@ member.set_name(kSecurityDomainMemberNamePrefix + encoded_public_key); member.set_public_key(member_public_key); - sync_pb::SecurityDomainMember::SecurityDomainMembership* membership = + trusted_vault_pb::SecurityDomainMember::SecurityDomainMembership* membership = member.add_memberships(); membership->set_security_domain(kSyncSecurityDomainName); - for (const sync_pb::SharedMemberKey& shared_key : + for (const trusted_vault_pb::SharedMemberKey& shared_key : state_.public_key_to_shared_keys[member_public_key]) { *membership->add_keys() = shared_key; } - for (const sync_pb::RotationProof& rotation_proof : + for (const trusted_vault_pb::RotationProof& rotation_proof : state_.public_key_to_rotation_proofs[member_public_key]) { *membership->add_rotation_proofs() = rotation_proof; } member.set_member_type( - sync_pb::SecurityDomainMember::MEMBER_TYPE_PHYSICAL_DEVICE); + trusted_vault_pb::SecurityDomainMember::MEMBER_TYPE_PHYSICAL_DEVICE); auto response = std::make_unique<net::test_server::BasicHttpResponse>(); response->set_code(net::HTTP_OK); response->set_content(member.SerializeAsString()); @@ -433,7 +433,7 @@ std::unique_ptr<net::test_server::HttpResponse> FakeSecurityDomainsServer::HandleGetSecurityDomainRequest( const net::test_server::HttpRequest& http_request) { - sync_pb::SecurityDomain security_domain; + trusted_vault_pb::SecurityDomain security_domain; security_domain.mutable_security_domain_details() ->mutable_sync_details() ->set_degraded_recoverability(IsRecoverabilityDegraded());
diff --git a/components/sync/test/fake_security_domains_server.h b/components/sync/test/fake_security_domains_server.h index 978f05b..a800b6561 100644 --- a/components/sync/test/fake_security_domains_server.h +++ b/components/sync/test/fake_security_domains_server.h
@@ -14,7 +14,7 @@ #include "base/observer_list_threadsafe.h" #include "base/synchronization/lock.h" #include "base/thread_annotations.h" -#include "components/sync/protocol/vault.pb.h" +#include "components/trusted_vault/proto/vault.pb.h" #include "net/test/embedded_test_server/http_request.h" #include "net/test/embedded_test_server/http_response.h" #include "url/gurl.h" @@ -23,6 +23,7 @@ // Mimics behavior of the security domains server. This class is designed to be // used with EmbeddedTestServer via registration of HandleRequest() method. +// TODO(crbug.com/1423343): move under components/trusted_vault. class FakeSecurityDomainsServer { public: class Observer : public base::CheckedObserver { @@ -98,10 +99,10 @@ bool received_invalid_request = false; // Maps members public key to shared keys that belong to this member. - std::map<std::string, std::vector<sync_pb::SharedMemberKey>> + std::map<std::string, std::vector<trusted_vault_pb::SharedMemberKey>> public_key_to_shared_keys; // Maps members public key to rotation proofs of members shared keys. - std::map<std::string, std::vector<sync_pb::RotationProof>> + std::map<std::string, std::vector<trusted_vault_pb::RotationProof>> public_key_to_rotation_proofs; // Zero epoch is used when there are no members in the security domain, once
diff --git a/components/trusted_vault/BUILD.gn b/components/trusted_vault/BUILD.gn index acf178e..b22a67d 100644 --- a/components/trusted_vault/BUILD.gn +++ b/components/trusted_vault/BUILD.gn
@@ -45,7 +45,7 @@ "//components/os_crypt/sync", "//components/signin/public/identity_manager", "//components/sync/base", - "//components/sync/protocol", + "//components/trusted_vault/proto", "//crypto", "//google_apis", "//net", @@ -77,6 +77,7 @@ "//components/os_crypt/sync", "//components/os_crypt/sync:test_support", "//components/signin/public/identity_manager:test_support", + "//components/trusted_vault/proto", "//google_apis", "//google_apis:test_support", "//testing/gmock",
diff --git a/components/trusted_vault/DEPS b/components/trusted_vault/DEPS index 88a1d0d..821bfab 100644 --- a/components/trusted_vault/DEPS +++ b/components/trusted_vault/DEPS
@@ -5,7 +5,6 @@ "+components/sync/base", "+components/sync/driver", "+components/sync/engine", - "+components/sync/protocol", "+crypto", "+google_apis", "+net",
diff --git a/components/trusted_vault/download_keys_response_handler.cc b/components/trusted_vault/download_keys_response_handler.cc index 8954351..16c85af 100644 --- a/components/trusted_vault/download_keys_response_handler.cc +++ b/components/trusted_vault/download_keys_response_handler.cc
@@ -8,7 +8,7 @@ #include <utility> #include "base/ranges/algorithm.h" -#include "components/sync/protocol/vault.pb.h" +#include "components/trusted_vault/proto/vault.pb.h" #include "components/trusted_vault/proto_string_bytes_conversion.h" #include "components/trusted_vault/securebox.h" #include "components/trusted_vault/trusted_vault_connection.h" @@ -26,8 +26,8 @@ std::vector<uint8_t> rotation_proof; }; -const sync_pb::SecurityDomainMember::SecurityDomainMembership* -FindSyncMembership(const sync_pb::SecurityDomainMember& member) { +const trusted_vault_pb::SecurityDomainMember::SecurityDomainMembership* +FindSyncMembership(const trusted_vault_pb::SecurityDomainMember& member) { for (const auto& membership : member.memberships()) { if (membership.security_domain() == kSyncSecurityDomainName) { return &membership; @@ -40,10 +40,12 @@ // keys from |membership| and sorts them by version. In case of decryption // errors it returns nullopt. absl::optional<std::vector<ExtractedSharedKey>> ExtractAndSortSharedKeys( - const sync_pb::SecurityDomainMember::SecurityDomainMembership& membership, + const trusted_vault_pb::SecurityDomainMember::SecurityDomainMembership& + membership, const SecureBoxPrivateKey& member_private_key) { std::map<int, ExtractedSharedKey> epoch_to_extracted_key; - for (const sync_pb::SharedMemberKey& shared_key : membership.keys()) { + for (const trusted_vault_pb::SharedMemberKey& shared_key : + membership.keys()) { absl::optional<std::vector<uint8_t>> decrypted_key = DecryptTrustedVaultWrappedKey( member_private_key, ProtoStringToBytes(shared_key.wrapped_key())); @@ -55,7 +57,7 @@ epoch_to_extracted_key[shared_key.epoch()].trusted_vault_key = *decrypted_key; } - for (const sync_pb::RotationProof& rotation_proof : + for (const trusted_vault_pb::RotationProof& rotation_proof : membership.rotation_proofs()) { if (epoch_to_extracted_key.count(rotation_proof.new_epoch()) == 0) { // There is no shared key corresponding to rotation proof. In theory it @@ -185,15 +187,15 @@ return ProcessedResponse(*error_from_http_status); } - sync_pb::SecurityDomainMember member; + trusted_vault_pb::SecurityDomainMember member; if (!member.ParseFromString(response_body)) { return ProcessedResponse( /*status=*/TrustedVaultDownloadKeysStatus::kOtherError); } // TODO(crbug.com/1113598): consider validation of member public key. - const sync_pb::SecurityDomainMember::SecurityDomainMembership* membership = - FindSyncMembership(member); + const trusted_vault_pb::SecurityDomainMember::SecurityDomainMembership* + membership = FindSyncMembership(member); if (!membership) { // Member is not in sync security domain. return ProcessedResponse(
diff --git a/components/trusted_vault/download_keys_response_handler_unittest.cc b/components/trusted_vault/download_keys_response_handler_unittest.cc index 68a22c5..669aa6a 100644 --- a/components/trusted_vault/download_keys_response_handler_unittest.cc +++ b/components/trusted_vault/download_keys_response_handler_unittest.cc
@@ -7,7 +7,7 @@ #include <vector> #include "base/strings/string_number_conversions.h" -#include "components/sync/protocol/vault.pb.h" +#include "components/trusted_vault/proto/vault.pb.h" #include "components/trusted_vault/proto_string_bytes_conversion.h" #include "components/trusted_vault/securebox.h" #include "components/trusted_vault/trusted_vault_connection.h" @@ -40,23 +40,23 @@ const std::vector<std::vector<uint8_t>>& trusted_vault_keys, const std::vector<int>& trusted_vault_keys_versions, const std::vector<std::vector<uint8_t>>& signing_keys, - sync_pb::SecurityDomainMember* member) { + trusted_vault_pb::SecurityDomainMember* member) { DCHECK(member); DCHECK_EQ(trusted_vault_keys.size(), trusted_vault_keys_versions.size()); DCHECK_EQ(trusted_vault_keys.size(), signing_keys.size()); - sync_pb::SecurityDomainMember::SecurityDomainMembership* membership = + trusted_vault_pb::SecurityDomainMember::SecurityDomainMembership* membership = member->add_memberships(); membership->set_security_domain(security_domain_name); for (size_t i = 0; i < trusted_vault_keys.size(); ++i) { - sync_pb::SharedMemberKey* shared_key = membership->add_keys(); + trusted_vault_pb::SharedMemberKey* shared_key = membership->add_keys(); shared_key->set_epoch(trusted_vault_keys_versions[i]); AssignBytesToProtoString( ComputeTrustedVaultWrappedKey(member_public_key, trusted_vault_keys[i]), shared_key->mutable_wrapped_key()); if (!signing_keys[i].empty()) { - sync_pb::RotationProof* rotation_proof = + trusted_vault_pb::RotationProof* rotation_proof = membership->add_rotation_proofs(); rotation_proof->set_new_epoch(trusted_vault_keys_versions[i]); AssignBytesToProtoString(ComputeRotationProofForTesting( @@ -71,7 +71,7 @@ const std::vector<std::vector<uint8_t>>& trusted_vault_keys, const std::vector<int>& trusted_vault_keys_versions, const std::vector<std::vector<uint8_t>>& signing_keys) { - sync_pb::SecurityDomainMember member; + trusted_vault_pb::SecurityDomainMember member; AddSecurityDomainMembership( kSyncSecurityDomainName, MakeTestKeyPair()->public_key(), trusted_vault_keys, trusted_vault_keys_versions, signing_keys, &member); @@ -272,7 +272,7 @@ // should return kMembershipCorrupted to allow client to restore the member by // re-registration. TEST_F(DownloadKeysResponseHandlerTest, ShouldHandleUndecryptableKey) { - sync_pb::SecurityDomainMember member; + trusted_vault_pb::SecurityDomainMember member; AddSecurityDomainMembership( kSyncSecurityDomainName, MakeTestKeyPair()->public_key(), /*trusted_vault_keys=*/{kKnownTrustedVaultKey, kTrustedVaultKey1}, @@ -367,7 +367,7 @@ EXPECT_THAT(handler() .ProcessResponse( /*http_status=*/TrustedVaultRequest::HttpStatus::kSuccess, - /*response_body=*/sync_pb::SecurityDomainMember() + /*response_body=*/trusted_vault_pb::SecurityDomainMember() .SerializeAsString()) .status, Eq(TrustedVaultDownloadKeysStatus::kMembershipNotFound)); @@ -375,7 +375,7 @@ // Same as above, but there is a different security domain membership. TEST_F(DownloadKeysResponseHandlerTest, ShouldHandleAbsenseOfSyncMembership) { - sync_pb::SecurityDomainMember member; + trusted_vault_pb::SecurityDomainMember member; AddSecurityDomainMembership( "other_domain", MakeTestKeyPair()->public_key(), /*trusted_vault_keys=*/{kTrustedVaultKey1}, @@ -391,7 +391,7 @@ } TEST_F(DownloadKeysResponseHandlerTest, ShouldHandleEmptyMembership) { - sync_pb::SecurityDomainMember member; + trusted_vault_pb::SecurityDomainMember member; AddSecurityDomainMembership(kSyncSecurityDomainName, MakeTestKeyPair()->public_key(), /*trusted_vault_keys=*/{}, @@ -408,7 +408,7 @@ // Tests handling presence of other security domain memberships. TEST_F(DownloadKeysResponseHandlerTest, ShouldHandleMultipleSecurityDomains) { - sync_pb::SecurityDomainMember member; + trusted_vault_pb::SecurityDomainMember member; AddSecurityDomainMembership( "other_domain", MakeTestKeyPair()->public_key(), /*trusted_vault_keys=*/{kTrustedVaultKey1},
diff --git a/components/trusted_vault/proto/BUILD.gn b/components/trusted_vault/proto/BUILD.gn new file mode 100644 index 0000000..d8aba1b --- /dev/null +++ b/components/trusted_vault/proto/BUILD.gn
@@ -0,0 +1,23 @@ +# Copyright 2023 The Chromium Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//third_party/protobuf/proto_library.gni") + +proto_library("proto") { + sources = [ + "local_trusted_vault.proto", + "vault.proto", + ] + + extra_configs = [ "//build/config/compiler:wexit_time_destructors" ] +} + +if (is_android) { + import("//build/config/android/rules.gni") + + proto_java_library("proto_java") { + proto_path = "//" + sources = [ "vault.proto" ] + } +}
diff --git a/components/sync/protocol/local_trusted_vault.proto b/components/trusted_vault/proto/local_trusted_vault.proto similarity index 98% rename from components/sync/protocol/local_trusted_vault.proto rename to components/trusted_vault/proto/local_trusted_vault.proto index 0c9fb30da..f6955cdf 100644 --- a/components/sync/protocol/local_trusted_vault.proto +++ b/components/trusted_vault/proto/local_trusted_vault.proto
@@ -6,8 +6,7 @@ option optimize_for = LITE_RUNTIME; -option java_package = "sync_pb"; -package sync_pb; +package trusted_vault_pb; // This enum is used in histograms. These values are persisted to logs. Entries // should not be renumbered and numeric values should never be reused, only add @@ -112,4 +111,4 @@ // MD5 digest of `serialized_local_trusted_vault` formatted as hexadecimal // string. optional string md5_digest_hex_string = 2; -} \ No newline at end of file +}
diff --git a/components/trusted_vault/proto/vault.proto b/components/trusted_vault/proto/vault.proto new file mode 100644 index 0000000..cabb030c4 --- /dev/null +++ b/components/trusted_vault/proto/vault.proto
@@ -0,0 +1,86 @@ +// Copyright 2020 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Trusted vault protos to communicate with backend written in proto3 to avoid +// subtle differences between enum fields. +syntax = "proto3"; + +option java_multiple_files = true; +option java_package = "org.chromium.components.trusted_vault.proto"; + +option optimize_for = LITE_RUNTIME; + +package trusted_vault_pb; + +message SharedMemberKey { + int32 epoch = 1; + bytes wrapped_key = 2; + bytes member_proof = 3; +} + +message RotationProof { + int32 new_epoch = 1; + bytes rotation_proof = 2; +} + +message SecurityDomainDetails { + message SyncDetails { + bool degraded_recoverability = 1; + } + + SyncDetails sync_details = 1; +} + +message SecurityDomain { + string name = 1; + int32 current_epoch = 2; + SecurityDomainDetails security_domain_details = 3; +} + +message SecurityDomainMember { + string name = 1; + bytes public_key = 2; + + message SecurityDomainMembership { + string security_domain = 1; + repeated SharedMemberKey keys = 3; + repeated RotationProof rotation_proofs = 4; + } + + repeated SecurityDomainMembership memberships = 3; + + enum MemberType { + MEMBER_TYPE_UNSPECIFIED = 0; + MEMBER_TYPE_PHYSICAL_DEVICE = 1; + } + + MemberType member_type = 4; +} + +message JoinSecurityDomainsRequest { + SecurityDomain security_domain = 1; + SecurityDomainMember security_domain_member = 2; + repeated SharedMemberKey shared_member_key = 3; + int32 member_type_hint = 4; +} + +message JoinSecurityDomainsResponse { + SecurityDomain security_domain = 1; +} + +message JoinSecurityDomainsErrorDetail { + JoinSecurityDomainsResponse already_exists_response = 1; +} + +// TODO(crbug.com/1234719): figure out how to link google.protobuf.Any and use +// it instead. +message Proto3Any { + string type_url = 1; + bytes value = 2; +} + +// Forked version of google.rpc.Status. +message RPCStatus { + repeated Proto3Any details = 3; +}
diff --git a/components/trusted_vault/standalone_trusted_vault_backend.cc b/components/trusted_vault/standalone_trusted_vault_backend.cc index 1260b821..e92d3a15 100644 --- a/components/trusted_vault/standalone_trusted_vault_backend.cc +++ b/components/trusted_vault/standalone_trusted_vault_backend.cc
@@ -31,7 +31,8 @@ #include "components/signin/public/identity_manager/accounts_in_cookie_jar_info.h" #include "components/sync/base/features.h" #include "components/sync/base/time.h" -#include "components/sync/protocol/local_trusted_vault.pb.h" +#include "components/sync/driver/trusted_vault_histograms.h" +#include "components/trusted_vault/proto/local_trusted_vault.pb.h" #include "components/trusted_vault/proto_string_bytes_conversion.h" #include "components/trusted_vault/securebox.h" #include "components/trusted_vault/trusted_vault_connection.h" @@ -48,8 +49,9 @@ constexpr int kCurrentDeviceRegistrationVersion = 1; constexpr base::TimeDelta kVerifyDeviceRegistrationDelay = base::Seconds(10); -sync_pb::LocalTrustedVault ReadEncryptedFile(const base::FilePath& file_path) { - sync_pb::LocalTrustedVault proto; +trusted_vault_pb::LocalTrustedVault ReadEncryptedFile( + const base::FilePath& file_path) { + trusted_vault_pb::LocalTrustedVault proto; std::string ciphertext; std::string decrypted_content; if (!base::ReadFileToString(file_path, &ciphertext)) { @@ -67,10 +69,11 @@ return proto; } -sync_pb::LocalTrustedVault ReadMD5HashedFile(const base::FilePath& file_path) { +trusted_vault_pb::LocalTrustedVault ReadMD5HashedFile( + const base::FilePath& file_path) { std::string file_content; - sync_pb::LocalTrustedVault data_proto; + trusted_vault_pb::LocalTrustedVault data_proto; if (!base::PathExists(file_path)) { trusted_vault::RecordTrustedVaultFileReadStatus( TrustedVaultFileReadStatusForUMA::kNotFound); @@ -81,7 +84,7 @@ TrustedVaultFileReadStatusForUMA::kFileReadFailed); return data_proto; } - sync_pb::LocalTrustedVaultFileContent file_proto; + trusted_vault_pb::LocalTrustedVaultFileContent file_proto; if (!file_proto.ParseFromString(file_content)) { trusted_vault::RecordTrustedVaultFileReadStatus( TrustedVaultFileReadStatusForUMA::kFileProtoDeserializationFailed); @@ -106,9 +109,9 @@ return data_proto; } -void WriteMD5HashedFileToDisk(const sync_pb::LocalTrustedVault& data, +void WriteMD5HashedFileToDisk(const trusted_vault_pb::LocalTrustedVault& data, const base::FilePath& file_path) { - sync_pb::LocalTrustedVaultFileContent file_proto; + trusted_vault_pb::LocalTrustedVaultFileContent file_proto; file_proto.set_serialized_local_trusted_vault(data.SerializeAsString()); file_proto.set_md5_digest_hex_string( base::MD5String(file_proto.serialized_local_trusted_vault())); @@ -128,7 +131,8 @@ if (!base::PathExists(new_file_path)) { // Only write to `new_file_path` if it doesn't exist yet to prevent // overwriting the content with stale data. - sync_pb::LocalTrustedVault proto = ReadEncryptedFile(old_file_path); + trusted_vault_pb::LocalTrustedVault proto = + ReadEncryptedFile(old_file_path); WriteMD5HashedFileToDisk(proto, new_file_path); } if (base::PathExists(new_file_path)) { @@ -137,11 +141,12 @@ } bool HasNonConstantKey( - const sync_pb::LocalTrustedVaultPerUser& per_user_vault) { + const trusted_vault_pb::LocalTrustedVaultPerUser& per_user_vault) { std::string constant_key_as_proto_string; AssignBytesToProtoString(GetConstantTrustedVaultKey(), &constant_key_as_proto_string); - for (const sync_pb::LocalTrustedVaultKey& key : per_user_vault.vault_key()) { + for (const trusted_vault_pb::LocalTrustedVaultKey& key : + per_user_vault.vault_key()) { if (key.key_material() != constant_key_as_proto_string) { return true; } @@ -150,9 +155,10 @@ } std::vector<std::vector<uint8_t>> GetAllVaultKeys( - const sync_pb::LocalTrustedVaultPerUser& per_user_vault) { + const trusted_vault_pb::LocalTrustedVaultPerUser& per_user_vault) { std::vector<std::vector<uint8_t>> vault_keys; - for (const sync_pb::LocalTrustedVaultKey& key : per_user_vault.vault_key()) { + for (const trusted_vault_pb::LocalTrustedVaultKey& key : + per_user_vault.vault_key()) { vault_keys.emplace_back(ProtoStringToBytes(key.key_material())); } return vault_keys; @@ -221,7 +227,8 @@ // was affected by crbug.com/1267391, this function injects constant key if it's // not stored and there is exactly one non-constant key. |local_trusted_vault| // must not be null and must have |version| set to 0. -void UpgradeToVersion1(sync_pb::LocalTrustedVault* local_trusted_vault) { +void UpgradeToVersion1( + trusted_vault_pb::LocalTrustedVault* local_trusted_vault) { DCHECK(local_trusted_vault); DCHECK_EQ(local_trusted_vault->data_version(), 0); @@ -229,7 +236,7 @@ AssignBytesToProtoString(GetConstantTrustedVaultKey(), &constant_key_as_proto_string); - for (sync_pb::LocalTrustedVaultPerUser& per_user_vault : + for (trusted_vault_pb::LocalTrustedVaultPerUser& per_user_vault : *local_trusted_vault->mutable_user()) { if (per_user_vault.vault_key_size() == 1 && per_user_vault.vault_key(0).key_material() != @@ -246,11 +253,12 @@ // Version 1 may contain `keys_marked_as_stale_by_consumer` (before the field // was renamed) accidentally set to true, upgrade to version 2 resets it to // false. -void UpgradeToVersion2(sync_pb::LocalTrustedVault* local_trusted_vault) { +void UpgradeToVersion2( + trusted_vault_pb::LocalTrustedVault* local_trusted_vault) { DCHECK(local_trusted_vault); DCHECK_EQ(local_trusted_vault->data_version(), 1); - for (sync_pb::LocalTrustedVaultPerUser& per_user_vault : + for (trusted_vault_pb::LocalTrustedVaultPerUser& per_user_vault : *local_trusted_vault->mutable_user()) { per_user_vault.set_keys_marked_as_stale_by_consumer(false); } @@ -331,10 +339,10 @@ StandaloneTrustedVaultBackend::~StandaloneTrustedVaultBackend() = default; void StandaloneTrustedVaultBackend::WriteDegradedRecoverabilityState( - const sync_pb::LocalTrustedVaultDegradedRecoverabilityState& + const trusted_vault_pb::LocalTrustedVaultDegradedRecoverabilityState& degraded_recoverability_state) { DCHECK(primary_account_.has_value()); - sync_pb::LocalTrustedVaultPerUser* per_user_vault = + trusted_vault_pb::LocalTrustedVaultPerUser* per_user_vault = FindUserVault(primary_account_->gaia); *per_user_vault->mutable_degraded_recoverability_state() = degraded_recoverability_state; @@ -379,7 +387,7 @@ ongoing_fetch_keys_callback_ = std::move(callback); ongoing_fetch_keys_gaia_id_ = account_info.gaia; - const sync_pb::LocalTrustedVaultPerUser* per_user_vault = + const trusted_vault_pb::LocalTrustedVaultPerUser* per_user_vault = FindUserVault(account_info.gaia); if (per_user_vault && HasNonConstantKey(*per_user_vault) && @@ -462,7 +470,8 @@ const std::vector<std::vector<uint8_t>>& keys, int last_key_version) { // Find or create user for |gaid_id|. - sync_pb::LocalTrustedVaultPerUser* per_user_vault = FindUserVault(gaia_id); + trusted_vault_pb::LocalTrustedVaultPerUser* per_user_vault = + FindUserVault(gaia_id); if (!per_user_vault) { per_user_vault = data_.add_user(); per_user_vault->set_gaia_id(gaia_id); @@ -532,7 +541,7 @@ return; } - sync_pb::LocalTrustedVaultPerUser* per_user_vault = + trusted_vault_pb::LocalTrustedVaultPerUser* per_user_vault = FindUserVault(primary_account->gaia); if (!per_user_vault) { per_user_vault = data_.add_user(); @@ -604,14 +613,14 @@ // jar. if (primary_account_.has_value() && !base::Contains(gaia_ids_in_cookie_jar, primary_account_->gaia)) { - sync_pb::LocalTrustedVaultPerUser* primary_account_data_ = + trusted_vault_pb::LocalTrustedVaultPerUser* primary_account_data_ = FindUserVault(primary_account_->gaia); primary_account_data_->set_should_delete_keys_when_non_primary(true); } auto should_remove_user_data = [&gaia_ids_in_cookie_jar, &primary_account = primary_account_]( - const sync_pb::LocalTrustedVaultPerUser& per_user_data) { + const trusted_vault_pb::LocalTrustedVaultPerUser& per_user_data) { const std::string& gaia_id = per_user_data.gaia_id(); if (primary_account.has_value() && gaia_id == primary_account->gaia) { // Don't delete primary account data. @@ -629,7 +638,7 @@ bool StandaloneTrustedVaultBackend::MarkLocalKeysAsStale( const CoreAccountInfo& account_info) { - sync_pb::LocalTrustedVaultPerUser* per_user_vault = + trusted_vault_pb::LocalTrustedVaultPerUser* per_user_vault = FindUserVault(account_info.gaia); if (!per_user_vault || per_user_vault->keys_marked_as_stale_by_consumer()) { // No keys available for |account_info| or they are already marked as stale. @@ -697,7 +706,8 @@ return; } - sync_pb::LocalTrustedVaultPerUser* per_user_vault = FindUserVault(gaia_id); + trusted_vault_pb::LocalTrustedVaultPerUser* per_user_vault = + FindUserVault(gaia_id); DCHECK(per_user_vault); if (per_user_vault->vault_key().empty()) { @@ -737,13 +747,13 @@ void StandaloneTrustedVaultBackend::ClearLocalDataForAccount( const CoreAccountInfo& account_info) { - sync_pb::LocalTrustedVaultPerUser* per_user_vault = + trusted_vault_pb::LocalTrustedVaultPerUser* per_user_vault = FindUserVault(account_info.gaia); if (!per_user_vault) { return; } - *per_user_vault = sync_pb::LocalTrustedVaultPerUser(); + *per_user_vault = trusted_vault_pb::LocalTrustedVaultPerUser(); per_user_vault->set_gaia_id(account_info.gaia); WriteDataToDisk(); @@ -759,12 +769,13 @@ return primary_account_; } -sync_pb::LocalDeviceRegistrationInfo +trusted_vault_pb::LocalDeviceRegistrationInfo StandaloneTrustedVaultBackend::GetDeviceRegistrationInfoForTesting( const std::string& gaia_id) { - sync_pb::LocalTrustedVaultPerUser* per_user_vault = FindUserVault(gaia_id); + trusted_vault_pb::LocalTrustedVaultPerUser* per_user_vault = + FindUserVault(gaia_id); if (!per_user_vault) { - return sync_pb::LocalDeviceRegistrationInfo(); + return trusted_vault_pb::LocalDeviceRegistrationInfo(); } return per_user_vault->local_device_registration_info(); } @@ -778,7 +789,8 @@ void StandaloneTrustedVaultBackend::SetDeviceRegisteredVersionForTesting( const std::string& gaia_id, int version) { - sync_pb::LocalTrustedVaultPerUser* per_user_vault = FindUserVault(gaia_id); + trusted_vault_pb::LocalTrustedVaultPerUser* per_user_vault = + FindUserVault(gaia_id); DCHECK(per_user_vault); per_user_vault->mutable_local_device_registration_info() ->set_device_registered_version(version); @@ -788,7 +800,8 @@ void StandaloneTrustedVaultBackend:: SetLastRegistrationReturnedLocalDataObsoleteForTesting( const std::string& gaia_id) { - sync_pb::LocalTrustedVaultPerUser* per_user_vault = FindUserVault(gaia_id); + trusted_vault_pb::LocalTrustedVaultPerUser* per_user_vault = + FindUserVault(gaia_id); DCHECK(per_user_vault); per_user_vault->mutable_local_device_registration_info() ->set_last_registration_returned_local_data_obsolete(true); @@ -823,7 +836,7 @@ } // |per_user_vault| must be created before calling this function. - sync_pb::LocalTrustedVaultPerUser* per_user_vault = + trusted_vault_pb::LocalTrustedVaultPerUser* per_user_vault = FindUserVault(primary_account_->gaia); DCHECK(per_user_vault); @@ -931,7 +944,7 @@ DCHECK(ongoing_device_registration_request_); ongoing_device_registration_request_ = nullptr; - sync_pb::LocalTrustedVaultPerUser* per_user_vault = + trusted_vault_pb::LocalTrustedVaultPerUser* per_user_vault = FindUserVault(primary_account_->gaia); DCHECK(per_user_vault); @@ -985,7 +998,7 @@ // by OnDeviceRegistered() call. DCHECK(ongoing_device_registration_request_); - sync_pb::LocalTrustedVaultPerUser* per_user_vault = + trusted_vault_pb::LocalTrustedVaultPerUser* per_user_vault = FindUserVault(primary_account_->gaia); DCHECK(per_user_vault); @@ -1038,7 +1051,7 @@ DCHECK(ongoing_keys_downloading_request_); ongoing_keys_downloading_request_ = nullptr; - sync_pb::LocalTrustedVaultPerUser* per_user_vault = + trusted_vault_pb::LocalTrustedVaultPerUser* per_user_vault = FindUserVault(primary_account_->gaia); DCHECK(per_user_vault); switch (status) { @@ -1113,7 +1126,7 @@ } DCHECK(!ongoing_fetch_keys_callback_.is_null()); - const sync_pb::LocalTrustedVaultPerUser* per_user_vault = + const trusted_vault_pb::LocalTrustedVaultPerUser* per_user_vault = FindUserVault(*ongoing_fetch_keys_gaia_id_); if (status_for_uma.has_value()) { @@ -1143,7 +1156,7 @@ DCHECK(clock_); DCHECK(primary_account_.has_value()); - sync_pb::LocalTrustedVaultPerUser* per_user_vault = + trusted_vault_pb::LocalTrustedVaultPerUser* per_user_vault = FindUserVault(primary_account_->gaia); DCHECK(per_user_vault); @@ -1175,7 +1188,7 @@ RemoveNonPrimaryAccountKeysIfMarkedForDeletion() { auto should_remove_user_data = [&primary_account = primary_account_]( - const sync_pb::LocalTrustedVaultPerUser& per_user_data) { + const trusted_vault_pb::LocalTrustedVaultPerUser& per_user_data) { return per_user_data.should_delete_keys_when_non_primary() && (!primary_account.has_value() || primary_account->gaia != per_user_data.gaia_id()); @@ -1187,8 +1200,8 @@ WriteDataToDisk(); } -sync_pb::LocalTrustedVaultPerUser* StandaloneTrustedVaultBackend::FindUserVault( - const std::string& gaia_id) { +trusted_vault_pb::LocalTrustedVaultPerUser* +StandaloneTrustedVaultBackend::FindUserVault(const std::string& gaia_id) { for (int i = 0; i < data_.user_size(); ++i) { if (data_.user(i).gaia_id() == gaia_id) { return data_.mutable_user(i); @@ -1199,7 +1212,7 @@ void StandaloneTrustedVaultBackend::VerifyDeviceRegistrationForUMA( const std::string& gaia_id) { - const sync_pb::LocalTrustedVaultPerUser* per_user_vault = + const trusted_vault_pb::LocalTrustedVaultPerUser* per_user_vault = FindUserVault(gaia_id); // Ignore call if things have changed since the task was scheduled, although
diff --git a/components/trusted_vault/standalone_trusted_vault_backend.h b/components/trusted_vault/standalone_trusted_vault_backend.h index f2ba2d7..ffdb9ede 100644 --- a/components/trusted_vault/standalone_trusted_vault_backend.h +++ b/components/trusted_vault/standalone_trusted_vault_backend.h
@@ -17,7 +17,7 @@ #include "base/memory/ref_counted.h" #include "base/time/time.h" #include "components/signin/public/identity_manager/account_info.h" -#include "components/sync/protocol/local_trusted_vault.pb.h" +#include "components/trusted_vault/proto/local_trusted_vault.pb.h" #include "components/trusted_vault/trusted_vault_connection.h" #include "components/trusted_vault/trusted_vault_degraded_recoverability_handler.h" #include "components/trusted_vault/trusted_vault_histograms.h" @@ -81,7 +81,7 @@ // TrustedVaultDegradedRecoverabilityHandler::Delegate implementation. void WriteDegradedRecoverabilityState( - const sync_pb::LocalTrustedVaultDegradedRecoverabilityState& + const trusted_vault_pb::LocalTrustedVaultDegradedRecoverabilityState& degraded_recoverability_state) override; void OnDegradedRecoverabilityChanged() override; @@ -134,8 +134,8 @@ absl::optional<CoreAccountInfo> GetPrimaryAccountForTesting() const; - sync_pb::LocalDeviceRegistrationInfo GetDeviceRegistrationInfoForTesting( - const std::string& gaia_id); + trusted_vault_pb::LocalDeviceRegistrationInfo + GetDeviceRegistrationInfoForTesting(const std::string& gaia_id); std::vector<uint8_t> GetLastAddedRecoveryMethodPublicKeyForTesting() const; @@ -167,7 +167,8 @@ // Finds the per-user vault in |data_| for |gaia_id|. Returns null if not // found. - sync_pb::LocalTrustedVaultPerUser* FindUserVault(const std::string& gaia_id); + trusted_vault_pb::LocalTrustedVaultPerUser* FindUserVault( + const std::string& gaia_id); // Attempts to register device in case it's not yet registered and currently // available local data is sufficient to do it. For the cases where @@ -230,7 +231,7 @@ // in this case and clean up related logic. const std::unique_ptr<TrustedVaultConnection> connection_; - sync_pb::LocalTrustedVault data_; + trusted_vault_pb::LocalTrustedVault data_; // Only current |primary_account_| can be used for communication with trusted // vault server.
diff --git a/components/trusted_vault/standalone_trusted_vault_backend_unittest.cc b/components/trusted_vault/standalone_trusted_vault_backend_unittest.cc index 7d258be..0997f9a 100644 --- a/components/trusted_vault/standalone_trusted_vault_backend_unittest.cc +++ b/components/trusted_vault/standalone_trusted_vault_backend_unittest.cc
@@ -25,7 +25,7 @@ #include "components/signin/public/identity_manager/account_info.h" #include "components/signin/public/identity_manager/accounts_in_cookie_jar_info.h" #include "components/sync/base/features.h" -#include "components/sync/protocol/local_trusted_vault.pb.h" +#include "components/trusted_vault/proto/local_trusted_vault.pb.h" #include "components/trusted_vault/proto_string_bytes_conversion.h" #include "components/trusted_vault/securebox.h" #include "components/trusted_vault/trusted_vault_connection.h" @@ -52,8 +52,8 @@ using testing::SaveArg; MATCHER_P(DegradedRecoverabilityStateEq, expected_state, "") { - const sync_pb::LocalTrustedVaultDegradedRecoverabilityState& given_state = - arg; + const trusted_vault_pb::LocalTrustedVaultDegradedRecoverabilityState& + given_state = arg; return given_state.degraded_recoverability_value() == expected_state.degraded_recoverability_value() && given_state.last_refresh_time_millis_since_unix_epoch() == @@ -89,9 +89,10 @@ return account_info; } -bool WriteLocalTrustedVaultFile(const sync_pb::LocalTrustedVault& proto, - const base::FilePath& path) { - sync_pb::LocalTrustedVaultFileContent file_proto; +bool WriteLocalTrustedVaultFile( + const trusted_vault_pb::LocalTrustedVault& proto, + const base::FilePath& path) { + trusted_vault_pb::LocalTrustedVaultFileContent file_proto; file_proto.set_serialized_local_trusted_vault(proto.SerializeAsString()); file_proto.set_md5_digest_hex_string( base::MD5String(file_proto.serialized_local_trusted_vault())); @@ -99,7 +100,7 @@ } bool WriteLocalEncryptedTrustedVaultFile( - const sync_pb::LocalTrustedVault& proto, + const trusted_vault_pb::LocalTrustedVault& proto, const base::FilePath& path) { std::string encrypted_content; if (!OSCrypt::EncryptString(proto.SerializeAsString(), &encrypted_content)) { @@ -108,14 +109,14 @@ return base::WriteFile(path, encrypted_content); } -sync_pb::LocalTrustedVault ReadLocalTrustedVaultFile( +trusted_vault_pb::LocalTrustedVault ReadLocalTrustedVaultFile( const base::FilePath& path) { std::string file_content; - sync_pb::LocalTrustedVault data_proto; + trusted_vault_pb::LocalTrustedVault data_proto; if (!base::ReadFileToString(path, &file_content)) { return data_proto; } - sync_pb::LocalTrustedVaultFileContent file_proto; + trusted_vault_pb::LocalTrustedVaultFileContent file_proto; if (!file_proto.ParseFromString(file_content)) { return data_proto; } @@ -295,16 +296,17 @@ TEST_F(StandaloneTrustedVaultBackendTest, ShouldWriteDegradedRecoverabilityState) { SetPrimaryAccountWithUnknownAuthError(MakeAccountInfoWithGaiaId("user")); - sync_pb::LocalTrustedVaultDegradedRecoverabilityState + trusted_vault_pb::LocalTrustedVaultDegradedRecoverabilityState degraded_recoverability_state; degraded_recoverability_state.set_degraded_recoverability_value( - sync_pb::DegradedRecoverabilityValue::kDegraded); + trusted_vault_pb::DegradedRecoverabilityValue::kDegraded); degraded_recoverability_state.set_last_refresh_time_millis_since_unix_epoch( 123); backend()->WriteDegradedRecoverabilityState(degraded_recoverability_state); // Read the file from disk. - sync_pb::LocalTrustedVault proto = ReadLocalTrustedVaultFile(file_path()); + trusted_vault_pb::LocalTrustedVault proto = + ReadLocalTrustedVaultFile(file_path()); ASSERT_THAT(proto.user_size(), Eq(1)); EXPECT_THAT(proto.user(0).degraded_recoverability_state(), DegradedRecoverabilityStateEq(degraded_recoverability_state)); @@ -425,7 +427,7 @@ TEST_F(StandaloneTrustedVaultBackendTest, ShouldRecordMD5DigestMismatchWhenReadingFile) { - sync_pb::LocalTrustedVaultFileContent file_proto; + trusted_vault_pb::LocalTrustedVaultFileContent file_proto; file_proto.set_md5_digest_hex_string("corrupted_md5_digest"); ASSERT_TRUE(base::WriteFile(file_path(), file_proto.SerializeAsString())); @@ -453,7 +455,7 @@ TEST_F(StandaloneTrustedVaultBackendTest, ShouldRecordDataProtoDeserializationFailedWhenReadingFile) { const std::string kCorruptedSerializedDataProto = "corrupted_proto"; - sync_pb::LocalTrustedVaultFileContent file_proto; + trusted_vault_pb::LocalTrustedVaultFileContent file_proto; file_proto.set_serialized_local_trusted_vault(kCorruptedSerializedDataProto); file_proto.set_md5_digest_hex_string( base::MD5String(kCorruptedSerializedDataProto)); @@ -476,9 +478,11 @@ const std::vector<uint8_t> kKey2 = {1, 2, 3, 4}; const std::vector<uint8_t> kKey3 = {2, 3, 4}; - sync_pb::LocalTrustedVault initial_data; - sync_pb::LocalTrustedVaultPerUser* user_data1 = initial_data.add_user(); - sync_pb::LocalTrustedVaultPerUser* user_data2 = initial_data.add_user(); + trusted_vault_pb::LocalTrustedVault initial_data; + trusted_vault_pb::LocalTrustedVaultPerUser* user_data1 = + initial_data.add_user(); + trusted_vault_pb::LocalTrustedVaultPerUser* user_data2 = + initial_data.add_user(); user_data1->set_gaia_id(account_info_1.gaia); user_data2->set_gaia_id(account_info_2.gaia); user_data1->add_vault_key()->set_key_material(kKey1.data(), kKey1.size()); @@ -507,11 +511,12 @@ const std::vector<uint8_t> kKey = {0, 1, 2, 3, 4}; const int kLastKeyVersion = 1; - sync_pb::LocalTrustedVault initial_data; + trusted_vault_pb::LocalTrustedVault initial_data; // Migration from version 0 to version 1 makes test more complex, bypass it. initial_data.set_data_version(1); - sync_pb::LocalTrustedVaultPerUser* user_data = initial_data.add_user(); + trusted_vault_pb::LocalTrustedVaultPerUser* user_data = + initial_data.add_user(); user_data->set_gaia_id(account_info.gaia); user_data->add_vault_key()->set_key_material(kKey.data(), kKey.size()); user_data->set_last_vault_key_version(kLastKeyVersion); @@ -528,7 +533,8 @@ // Ensure that backend completed file migration. EXPECT_FALSE(base::PathExists(deprecated_file_path())); - sync_pb::LocalTrustedVault proto = ReadLocalTrustedVaultFile(file_path()); + trusted_vault_pb::LocalTrustedVault proto = + ReadLocalTrustedVaultFile(file_path()); ASSERT_THAT(proto.user_size(), Eq(1)); EXPECT_THAT(proto.user(0).vault_key(), ElementsAre(KeyMaterialEq(kKey))); EXPECT_THAT(proto.user(0).last_vault_key_version(), Eq(kLastKeyVersion)); @@ -538,8 +544,9 @@ const CoreAccountInfo account_info = MakeAccountInfoWithGaiaId("user1"); const std::vector<uint8_t> kKey = {1, 2, 3, 4}; - sync_pb::LocalTrustedVault initial_data; - sync_pb::LocalTrustedVaultPerUser* user_data = initial_data.add_user(); + trusted_vault_pb::LocalTrustedVault initial_data; + trusted_vault_pb::LocalTrustedVaultPerUser* user_data = + initial_data.add_user(); user_data->set_gaia_id(account_info.gaia); user_data->add_vault_key()->set_key_material( GetConstantTrustedVaultKey().data(), GetConstantTrustedVaultKey().size()); @@ -573,7 +580,8 @@ /*expected_bucket_count=*/3); // Read the file from disk. - sync_pb::LocalTrustedVault proto = ReadLocalTrustedVaultFile(file_path()); + trusted_vault_pb::LocalTrustedVault proto = + ReadLocalTrustedVaultFile(file_path()); ASSERT_THAT(proto.user_size(), Eq(2)); EXPECT_THAT(proto.user(0).vault_key(), ElementsAre(KeyMaterialEq(kKey1))); EXPECT_THAT(proto.user(0).last_vault_key_version(), Eq(7)); @@ -590,9 +598,11 @@ const std::vector<uint8_t> kKey1 = {0, 1, 2, 3, 4}; const std::vector<uint8_t> kKey2 = {1, 2, 3, 4}; - sync_pb::LocalTrustedVault initial_data; - sync_pb::LocalTrustedVaultPerUser* user_data1 = initial_data.add_user(); - sync_pb::LocalTrustedVaultPerUser* user_data2 = initial_data.add_user(); + trusted_vault_pb::LocalTrustedVault initial_data; + trusted_vault_pb::LocalTrustedVaultPerUser* user_data1 = + initial_data.add_user(); + trusted_vault_pb::LocalTrustedVaultPerUser* user_data2 = + initial_data.add_user(); user_data1->set_gaia_id(account_info_1.gaia); user_data2->set_gaia_id(account_info_2.gaia); // Mimic |user_data1| to be affected by crbug.com/1267391 and |user_data2| to @@ -609,7 +619,8 @@ backend()->ReadDataFromDisk(); // Read the file from disk. - sync_pb::LocalTrustedVault proto = ReadLocalTrustedVaultFile(file_path()); + trusted_vault_pb::LocalTrustedVault proto = + ReadLocalTrustedVaultFile(file_path()); ASSERT_THAT(proto.user_size(), Eq(2)); // Constant key should be added for the first user. EXPECT_THAT(proto.user(0).vault_key(), @@ -627,9 +638,11 @@ const CoreAccountInfo account_info_1 = MakeAccountInfoWithGaiaId("user1"); const CoreAccountInfo account_info_2 = MakeAccountInfoWithGaiaId("user2"); - sync_pb::LocalTrustedVault initial_data; - sync_pb::LocalTrustedVaultPerUser* user_data1 = initial_data.add_user(); - sync_pb::LocalTrustedVaultPerUser* user_data2 = initial_data.add_user(); + trusted_vault_pb::LocalTrustedVault initial_data; + trusted_vault_pb::LocalTrustedVaultPerUser* user_data1 = + initial_data.add_user(); + trusted_vault_pb::LocalTrustedVaultPerUser* user_data2 = + initial_data.add_user(); user_data1->set_gaia_id(account_info_1.gaia); user_data1->set_keys_marked_as_stale_by_consumer(true); user_data2->set_gaia_id(account_info_2.gaia); @@ -640,7 +653,8 @@ // and write new state. backend()->ReadDataFromDisk(); - sync_pb::LocalTrustedVault new_data = ReadLocalTrustedVaultFile(file_path()); + trusted_vault_pb::LocalTrustedVault new_data = + ReadLocalTrustedVaultFile(file_path()); ASSERT_THAT(new_data.user_size(), Eq(2)); EXPECT_FALSE(new_data.user(0).keys_marked_as_stale_by_consumer()); EXPECT_FALSE(new_data.user(1).keys_marked_as_stale_by_consumer()); @@ -714,7 +728,8 @@ // Read the file from disk and verify that keys were removed from disk // storage. - sync_pb::LocalTrustedVault proto = ReadLocalTrustedVaultFile(file_path()); + trusted_vault_pb::LocalTrustedVault proto = + ReadLocalTrustedVaultFile(file_path()); EXPECT_THAT(proto.user_size(), Eq(0)); } @@ -740,7 +755,8 @@ // Read the file from disk and verify that keys were removed from disk // storage. - sync_pb::LocalTrustedVault proto = ReadLocalTrustedVaultFile(file_path()); + trusted_vault_pb::LocalTrustedVault proto = + ReadLocalTrustedVaultFile(file_path()); EXPECT_THAT(proto.user_size(), Eq(0)); } @@ -777,7 +793,8 @@ // Read the file from disk and verify that keys were removed from disk // storage. - sync_pb::LocalTrustedVault proto = ReadLocalTrustedVaultFile(file_path()); + trusted_vault_pb::LocalTrustedVault proto = + ReadLocalTrustedVaultFile(file_path()); EXPECT_THAT(proto.user_size(), Eq(0)); } @@ -830,7 +847,7 @@ /*expected_bucket_count=*/1); // Now the device should be registered. - sync_pb::LocalDeviceRegistrationInfo registration_info = + trusted_vault_pb::LocalDeviceRegistrationInfo registration_info = backend()->GetDeviceRegistrationInfoForTesting(account_info.gaia); EXPECT_TRUE(registration_info.device_registered()); EXPECT_TRUE(registration_info.has_private_key_material()); @@ -876,7 +893,8 @@ .Run(TrustedVaultRegistrationStatus::kLocalDataObsolete); // Verify persisted file state. - sync_pb::LocalTrustedVault proto = ReadLocalTrustedVaultFile(file_path()); + trusted_vault_pb::LocalTrustedVault proto = + ReadLocalTrustedVaultFile(file_path()); ASSERT_THAT(proto.user_size(), Eq(1)); // Ensure that the failure is remembered, so there are no retries. This is a // regression test for crbug.com/1358015. @@ -940,7 +958,7 @@ kInitialLastKeyVersion + 1)); // Now the device should be registered. - sync_pb::LocalDeviceRegistrationInfo registration_info = + trusted_vault_pb::LocalDeviceRegistrationInfo registration_info = backend()->GetDeviceRegistrationInfoForTesting(account_info.gaia); EXPECT_TRUE(registration_info.device_registered()); EXPECT_TRUE(registration_info.has_private_key_material()); @@ -1488,7 +1506,7 @@ kServerConstantKeyVersion}); // Now the device should be registered. - sync_pb::LocalDeviceRegistrationInfo registration_info = + trusted_vault_pb::LocalDeviceRegistrationInfo registration_info = backend()->GetDeviceRegistrationInfoForTesting(account_info.gaia); EXPECT_TRUE(registration_info.device_registered()); EXPECT_TRUE(registration_info.has_private_key_material()); @@ -1579,7 +1597,7 @@ .Run(TrustedVaultRegistrationStatus::kSuccess); // Now the device reregistration should be completed. - sync_pb::LocalDeviceRegistrationInfo registration_info = + trusted_vault_pb::LocalDeviceRegistrationInfo registration_info = backend()->GetDeviceRegistrationInfoForTesting(account_info.gaia); EXPECT_TRUE(registration_info.device_registered()); EXPECT_THAT(registration_info.device_registered_version(), Eq(1)); @@ -1680,7 +1698,7 @@ kNewServerConstantKeyVersion}); // Now the device reregistration should be completed. - sync_pb::LocalDeviceRegistrationInfo registration_info = + trusted_vault_pb::LocalDeviceRegistrationInfo registration_info = backend()->GetDeviceRegistrationInfoForTesting(account_info.gaia); EXPECT_TRUE(registration_info.device_registered()); EXPECT_THAT(registration_info.device_registered_version(), Eq(1)); @@ -1688,7 +1706,8 @@ // Read the file from disk and verify that kNewServerConstantKeyVersion is // stored. - sync_pb::LocalTrustedVault proto = ReadLocalTrustedVaultFile(file_path()); + trusted_vault_pb::LocalTrustedVault proto = + ReadLocalTrustedVaultFile(file_path()); ASSERT_THAT(proto.user_size(), Eq(1)); EXPECT_THAT(proto.user(0).last_vault_key_version(), Eq(kNewServerConstantKeyVersion)); @@ -1988,7 +2007,7 @@ backend()->FetchKeys(account_info, base::DoNothing()); { - sync_pb::LocalDeviceRegistrationInfo registration_info = + trusted_vault_pb::LocalDeviceRegistrationInfo registration_info = backend()->GetDeviceRegistrationInfoForTesting(account_info.gaia); ASSERT_THAT(registration_info.device_registered_version(), Ne(1)); } @@ -1996,7 +2015,7 @@ ASSERT_FALSE(redo_device_registration_callback.is_null()); std::move(redo_device_registration_callback) .Run(TrustedVaultRegistrationStatus::kSuccess); - sync_pb::LocalDeviceRegistrationInfo registration_info = + trusted_vault_pb::LocalDeviceRegistrationInfo registration_info = backend()->GetDeviceRegistrationInfoForTesting(account_info.gaia); EXPECT_THAT(registration_info.device_registered_version(), Eq(1)); }
diff --git a/components/trusted_vault/trusted_vault_connection_impl.cc b/components/trusted_vault/trusted_vault_connection_impl.cc index 64203d60..78850c6b 100644 --- a/components/trusted_vault/trusted_vault_connection_impl.cc +++ b/components/trusted_vault/trusted_vault_connection_impl.cc
@@ -12,8 +12,8 @@ #include "base/files/important_file_writer.h" #include "base/time/time.h" #include "components/signin/public/identity_manager/account_info.h" -#include "components/sync/protocol/vault.pb.h" #include "components/trusted_vault/download_keys_response_handler.h" +#include "components/trusted_vault/proto/vault.pb.h" #include "components/trusted_vault/proto_string_bytes_conversion.h" #include "components/trusted_vault/securebox.h" #include "components/trusted_vault/trusted_vault_access_token_fetcher.h" @@ -29,7 +29,7 @@ // Returns security domain epoch if valid (>0) and nullopt otherwise. absl::optional<int> GetLastKeyVersionFromJoinSecurityDomainsResponse( - const sync_pb::JoinSecurityDomainsResponse response) { + const trusted_vault_pb::JoinSecurityDomainsResponse response) { if (response.security_domain().current_epoch() > 0) { return response.security_domain().current_epoch(); } @@ -40,13 +40,14 @@ // error case and nullopt otherwise. absl::optional<int> GetLastKeyVersionFromAlreadyExistsResponse( const std::string& response_body) { - sync_pb::RPCStatus rpc_status; + trusted_vault_pb::RPCStatus rpc_status; rpc_status.ParseFromString(response_body); - for (const sync_pb::Proto3Any& status_detail : rpc_status.details()) { + for (const trusted_vault_pb::Proto3Any& status_detail : + rpc_status.details()) { if (status_detail.type_url() != kJoinSecurityDomainsErrorDetailTypeURL) { continue; } - sync_pb::JoinSecurityDomainsErrorDetail error_detail; + trusted_vault_pb::JoinSecurityDomainsErrorDetail error_detail; error_detail.ParseFromString(status_detail.value()); return GetLastKeyVersionFromJoinSecurityDomainsResponse( error_detail.already_exists_response()); @@ -66,10 +67,10 @@ return result; } -sync_pb::SharedMemberKey CreateSharedMemberKey( +trusted_vault_pb::SharedMemberKey CreateSharedMemberKey( const TrustedVaultKeyAndVersion& trusted_vault_key_and_version, const SecureBoxPublicKey& public_key) { - sync_pb::SharedMemberKey shared_member_key; + trusted_vault_pb::SharedMemberKey shared_member_key; shared_member_key.set_epoch(trusted_vault_key_and_version.version); const std::vector<uint8_t>& trusted_vault_key = @@ -82,10 +83,10 @@ return shared_member_key; } -sync_pb::SecurityDomainMember CreateSecurityDomainMember( +trusted_vault_pb::SecurityDomainMember CreateSecurityDomainMember( const SecureBoxPublicKey& public_key, AuthenticationFactorType authentication_factor_type) { - sync_pb::SecurityDomainMember member; + trusted_vault_pb::SecurityDomainMember member; std::string public_key_string; AssignBytesToProtoString(public_key.ExportToBytes(), &public_key_string); @@ -101,23 +102,23 @@ switch (authentication_factor_type) { case AuthenticationFactorType::kPhysicalDevice: member.set_member_type( - sync_pb::SecurityDomainMember::MEMBER_TYPE_PHYSICAL_DEVICE); + trusted_vault_pb::SecurityDomainMember::MEMBER_TYPE_PHYSICAL_DEVICE); break; case AuthenticationFactorType::kUnspecified: member.set_member_type( - sync_pb::SecurityDomainMember::MEMBER_TYPE_UNSPECIFIED); + trusted_vault_pb::SecurityDomainMember::MEMBER_TYPE_UNSPECIFIED); break; } return member; } -sync_pb::JoinSecurityDomainsRequest CreateJoinSecurityDomainsRequest( +trusted_vault_pb::JoinSecurityDomainsRequest CreateJoinSecurityDomainsRequest( const std::vector<std::vector<uint8_t>>& trusted_vault_keys, int last_trusted_vault_key_version, const SecureBoxPublicKey& public_key, AuthenticationFactorType authentication_factor_type, absl::optional<int> authentication_factor_type_hint) { - sync_pb::JoinSecurityDomainsRequest request; + trusted_vault_pb::JoinSecurityDomainsRequest request; request.mutable_security_domain()->set_name(kSyncSecurityDomainName); *request.mutable_security_domain_member() = CreateSecurityDomainMember(public_key, authentication_factor_type); @@ -195,7 +196,7 @@ last_key_version = GetLastKeyVersionFromAlreadyExistsResponse(response_body); } else { - sync_pb::JoinSecurityDomainsResponse response; + trusted_vault_pb::JoinSecurityDomainsResponse response; response.ParseFromString(response_body); last_key_version = GetLastKeyVersionFromJoinSecurityDomainsResponse(response); @@ -246,7 +247,7 @@ std::move(callback).Run(TrustedVaultRecoverabilityStatus::kError); return; } - sync_pb::SecurityDomain security_domain; + trusted_vault_pb::SecurityDomain security_domain; if (!security_domain.ParseFromString(response_body) || !security_domain.security_domain_details().has_sync_details()) { std::move(callback).Run(TrustedVaultRecoverabilityStatus::kError);
diff --git a/components/trusted_vault/trusted_vault_connection_impl_unittest.cc b/components/trusted_vault/trusted_vault_connection_impl_unittest.cc index 39cd6a1..6cefb756 100644 --- a/components/trusted_vault/trusted_vault_connection_impl_unittest.cc +++ b/components/trusted_vault/trusted_vault_connection_impl_unittest.cc
@@ -17,7 +17,7 @@ #include "base/types/expected.h" #include "components/signin/public/identity_manager/access_token_info.h" #include "components/signin/public/identity_manager/account_info.h" -#include "components/sync/protocol/vault.pb.h" +#include "components/trusted_vault/proto/vault.pb.h" #include "components/trusted_vault/proto_string_bytes_conversion.h" #include "components/trusted_vault/securebox.h" #include "components/trusted_vault/trusted_vault_access_token_fetcher.h" @@ -59,9 +59,9 @@ return SecureBoxKeyPair::CreateByPrivateKeyImport(private_key_bytes); } -sync_pb::SecurityDomain MakeSecurityDomainWithDegradedRecoverability( +trusted_vault_pb::SecurityDomain MakeSecurityDomainWithDegradedRecoverability( bool recoverability_degraded) { - sync_pb::SecurityDomain security_domain; + trusted_vault_pb::SecurityDomain security_domain; security_domain.set_name(kSyncSecurityDomainName); security_domain.mutable_security_domain_details() ->mutable_sync_details() @@ -69,10 +69,11 @@ return security_domain; } -sync_pb::JoinSecurityDomainsResponse MakeJoinSecurityDomainsResponse( +trusted_vault_pb::JoinSecurityDomainsResponse MakeJoinSecurityDomainsResponse( int current_epoch) { - sync_pb::JoinSecurityDomainsResponse response; - sync_pb::SecurityDomain* security_domain = response.mutable_security_domain(); + trusted_vault_pb::JoinSecurityDomainsResponse response; + trusted_vault_pb::SecurityDomain* security_domain = + response.mutable_security_domain(); security_domain->set_name(kSyncSecurityDomainName); security_domain->set_current_epoch(current_epoch); return response; @@ -221,7 +222,7 @@ EXPECT_THAT(resource_request.url, Eq(GetFullJoinSecurityDomainsURLForTesting(kTestURL))); - sync_pb::JoinSecurityDomainsRequest deserialized_body; + trusted_vault_pb::JoinSecurityDomainsRequest deserialized_body; EXPECT_TRUE(deserialized_body.ParseFromString( network::GetUploadData(resource_request))); EXPECT_THAT(deserialized_body.security_domain().name(), @@ -236,17 +237,18 @@ base::Base64UrlEncodePolicy::OMIT_PADDING, &encoded_public_key); - const sync_pb::SecurityDomainMember& member = + const trusted_vault_pb::SecurityDomainMember& member = deserialized_body.security_domain_member(); EXPECT_THAT(member.name(), Eq(kSecurityDomainMemberNamePrefix + encoded_public_key)); EXPECT_THAT(member.public_key(), Eq(public_key_string)); - EXPECT_THAT(member.member_type(), - Eq(sync_pb::SecurityDomainMember::MEMBER_TYPE_PHYSICAL_DEVICE)); + EXPECT_THAT( + member.member_type(), + Eq(trusted_vault_pb::SecurityDomainMember::MEMBER_TYPE_PHYSICAL_DEVICE)); // Constant key with |epoch| set to kUnknownConstantKeyVersion must be sent. ASSERT_THAT(deserialized_body.shared_member_key(), SizeIs(1)); - const sync_pb::SharedMemberKey& shared_key = + const trusted_vault_pb::SharedMemberKey& shared_key = deserialized_body.shared_member_key(0); EXPECT_THAT(shared_key.epoch(), Eq(0)); @@ -284,7 +286,7 @@ EXPECT_THAT(resource_request.url, Eq(GetFullJoinSecurityDomainsURLForTesting(kTestURL))); - sync_pb::JoinSecurityDomainsRequest deserialized_body; + trusted_vault_pb::JoinSecurityDomainsRequest deserialized_body; EXPECT_TRUE(deserialized_body.ParseFromString( network::GetUploadData(resource_request))); EXPECT_THAT(deserialized_body.security_domain().name(), @@ -299,17 +301,18 @@ base::Base64UrlEncodePolicy::OMIT_PADDING, &encoded_public_key); - const sync_pb::SecurityDomainMember& member = + const trusted_vault_pb::SecurityDomainMember& member = deserialized_body.security_domain_member(); EXPECT_THAT(member.name(), Eq(kSecurityDomainMemberNamePrefix + encoded_public_key)); EXPECT_THAT(member.public_key(), Eq(public_key_string)); - EXPECT_THAT(member.member_type(), - Eq(sync_pb::SecurityDomainMember::MEMBER_TYPE_PHYSICAL_DEVICE)); + EXPECT_THAT( + member.member_type(), + Eq(trusted_vault_pb::SecurityDomainMember::MEMBER_TYPE_PHYSICAL_DEVICE)); ASSERT_THAT(deserialized_body.shared_member_key(), SizeIs(kTrustedVaultKeys.size())); - const sync_pb::SharedMemberKey& shared_key_1 = + const trusted_vault_pb::SharedMemberKey& shared_key_1 = deserialized_body.shared_member_key(0); EXPECT_THAT(shared_key_1.epoch(), Eq(kLastKeyVersion - 1)); @@ -321,7 +324,7 @@ VerifyMemberProof(key_pair->public_key(), kTrustedVaultKeys[0], ProtoStringToBytes(shared_key_1.member_proof()))); - const sync_pb::SharedMemberKey& shared_key_2 = + const trusted_vault_pb::SharedMemberKey& shared_key_2 = deserialized_body.shared_member_key(1); EXPECT_THAT(shared_key_2.epoch(), Eq(kLastKeyVersion)); @@ -357,7 +360,7 @@ EXPECT_THAT(resource_request.url, Eq(GetFullJoinSecurityDomainsURLForTesting(kTestURL))); - sync_pb::JoinSecurityDomainsRequest deserialized_body; + trusted_vault_pb::JoinSecurityDomainsRequest deserialized_body; ASSERT_TRUE(deserialized_body.ParseFromString( network::GetUploadData(resource_request))); EXPECT_THAT(deserialized_body.member_type_hint(), Eq(kTypeHint)); @@ -431,13 +434,13 @@ TrustedVaultKeyAndVersionEq(GetConstantTrustedVaultKey(), kServerConstantKeyVersion))); - sync_pb::JoinSecurityDomainsErrorDetail error_detail; + trusted_vault_pb::JoinSecurityDomainsErrorDetail error_detail; *error_detail.mutable_already_exists_response() = MakeJoinSecurityDomainsResponse( /*current_epoch=*/kServerConstantKeyVersion); - sync_pb::RPCStatus response; - sync_pb::Proto3Any* status_detail = response.add_details(); + trusted_vault_pb::RPCStatus response; + trusted_vault_pb::Proto3Any* status_detail = response.add_details(); status_detail->set_type_url(kJoinSecurityDomainsErrorDetailTypeURL); status_detail->set_value(error_detail.SerializeAsString()); @@ -826,7 +829,8 @@ // Respond with empty proto. EXPECT_TRUE(RespondToGetSecurityDomainRequest( net::HTTP_OK, - /*response_body=*/sync_pb::SecurityDomain().SerializeAsString())); + /*response_body=*/trusted_vault_pb::SecurityDomain() + .SerializeAsString())); } TEST_F(TrustedVaultConnectionImplTest,
diff --git a/components/trusted_vault/trusted_vault_degraded_recoverability_handler.cc b/components/trusted_vault/trusted_vault_degraded_recoverability_handler.cc index 0d2f835..24c7e6a 100644 --- a/components/trusted_vault/trusted_vault_degraded_recoverability_handler.cc +++ b/components/trusted_vault/trusted_vault_degraded_recoverability_handler.cc
@@ -12,7 +12,7 @@ #include "base/timer/timer.h" #include "components/sync/base/features.h" #include "components/sync/base/time.h" -#include "components/sync/protocol/local_trusted_vault.pb.h" +#include "components/trusted_vault/proto/local_trusted_vault.pb.h" #include "components/trusted_vault/trusted_vault_connection.h" #include "components/trusted_vault/trusted_vault_histograms.h" @@ -34,11 +34,11 @@ return refresh_period - elapsed_time; } -sync_pb::LocalTrustedVaultDegradedRecoverabilityState +trusted_vault_pb::LocalTrustedVaultDegradedRecoverabilityState MakeDegradedRecoverabilityState( - sync_pb::DegradedRecoverabilityValue degraded_recoverability_value, + trusted_vault_pb::DegradedRecoverabilityValue degraded_recoverability_value, const base::Time& last_refresh_time) { - sync_pb::LocalTrustedVaultDegradedRecoverabilityState + trusted_vault_pb::LocalTrustedVaultDegradedRecoverabilityState degraded_recoverability_state; degraded_recoverability_state.set_degraded_recoverability_value( degraded_recoverability_value); @@ -54,7 +54,7 @@ TrustedVaultConnection* connection, Delegate* delegate, const CoreAccountInfo& account_info, - const sync_pb::LocalTrustedVaultDegradedRecoverabilityState& + const trusted_vault_pb::LocalTrustedVaultDegradedRecoverabilityState& degraded_recoverability_state) : connection_(connection), delegate_(delegate), @@ -98,7 +98,7 @@ pending_get_is_recoverability_degraded_callback_ = std::move(cb); } else { std::move(cb).Run(degraded_recoverability_value_ == - sync_pb::DegradedRecoverabilityValue::kDegraded); + trusted_vault_pb::DegradedRecoverabilityValue::kDegraded); } if (!next_refresh_timer_.IsRunning()) { Start(); @@ -107,7 +107,7 @@ void TrustedVaultDegradedRecoverabilityHandler::UpdateCurrentRefreshPeriod() { if (degraded_recoverability_value_ == - sync_pb::DegradedRecoverabilityValue::kDegraded) { + trusted_vault_pb::DegradedRecoverabilityValue::kDegraded) { current_refresh_period_ = short_degraded_recoverability_refresh_period_; return; } @@ -115,9 +115,10 @@ } void TrustedVaultDegradedRecoverabilityHandler::Start() { - base::UmaHistogramExactLinear("Sync.TrustedVaultDegradedRecoverabilityValue2", - degraded_recoverability_value_, - sync_pb::DegradedRecoverabilityValue_ARRAYSIZE); + base::UmaHistogramExactLinear( + "Sync.TrustedVaultDegradedRecoverabilityValue2", + degraded_recoverability_value_, + trusted_vault_pb::DegradedRecoverabilityValue_ARRAYSIZE); next_refresh_timer_.Start( FROM_HERE, ComputeTimeUntilNextRefresh(current_refresh_period_, last_refresh_time_), @@ -140,16 +141,16 @@ TrustedVaultRecoverabilityStatus status) { base::UmaHistogramEnumeration( "Sync.TrustedVaultRecoverabilityStatusOnRequestCompletion", status); - sync_pb::DegradedRecoverabilityValue old_degraded_recoverability_value = - degraded_recoverability_value_; + trusted_vault_pb::DegradedRecoverabilityValue + old_degraded_recoverability_value = degraded_recoverability_value_; switch (status) { case TrustedVaultRecoverabilityStatus::kDegraded: degraded_recoverability_value_ = - sync_pb::DegradedRecoverabilityValue::kDegraded; + trusted_vault_pb::DegradedRecoverabilityValue::kDegraded; break; case TrustedVaultRecoverabilityStatus::kNotDegraded: degraded_recoverability_value_ = - sync_pb::DegradedRecoverabilityValue::kNotDegraded; + trusted_vault_pb::DegradedRecoverabilityValue::kNotDegraded; break; case TrustedVaultRecoverabilityStatus::kError: // TODO(crbug.com/1247990): To be handled. @@ -158,7 +159,7 @@ if (!pending_get_is_recoverability_degraded_callback_.is_null()) { std::move(pending_get_is_recoverability_degraded_callback_) .Run(degraded_recoverability_value_ == - sync_pb::DegradedRecoverabilityValue::kDegraded); + trusted_vault_pb::DegradedRecoverabilityValue::kDegraded); pending_get_is_recoverability_degraded_callback_ = base::NullCallback(); } if (degraded_recoverability_value_ != old_degraded_recoverability_value) {
diff --git a/components/trusted_vault/trusted_vault_degraded_recoverability_handler.h b/components/trusted_vault/trusted_vault_degraded_recoverability_handler.h index 92338bf..cdbf0874 100644 --- a/components/trusted_vault/trusted_vault_degraded_recoverability_handler.h +++ b/components/trusted_vault/trusted_vault_degraded_recoverability_handler.h
@@ -14,10 +14,10 @@ #include "components/trusted_vault/trusted_vault_connection.h" #include "components/trusted_vault/trusted_vault_histograms.h" -namespace sync_pb { +namespace trusted_vault_pb { class LocalTrustedVaultDegradedRecoverabilityState; enum DegradedRecoverabilityValue : int; -} // namespace sync_pb +} // namespace trusted_vault_pb namespace trusted_vault { // Refreshs the degraded recoverability state by scheduling the requests based @@ -32,7 +32,7 @@ virtual ~Delegate() = default; virtual void WriteDegradedRecoverabilityState( - const sync_pb::LocalTrustedVaultDegradedRecoverabilityState& + const trusted_vault_pb::LocalTrustedVaultDegradedRecoverabilityState& degraded_recoverability_state) = 0; virtual void OnDegradedRecoverabilityChanged() = 0; }; @@ -42,7 +42,7 @@ TrustedVaultConnection* connection, Delegate* delegate, const CoreAccountInfo& account_info, - const sync_pb::LocalTrustedVaultDegradedRecoverabilityState& + const trusted_vault_pb::LocalTrustedVaultDegradedRecoverabilityState& degraded_recoverability_state); TrustedVaultDegradedRecoverabilityHandler( const TrustedVaultDegradedRecoverabilityHandler&) = delete; @@ -72,7 +72,7 @@ // `current_refresh_period_` delay has elapsed. base::OneShotTimer next_refresh_timer_; base::TimeDelta current_refresh_period_; - sync_pb::DegradedRecoverabilityValue degraded_recoverability_value_; + trusted_vault_pb::DegradedRecoverabilityValue degraded_recoverability_value_; // The last time Refresh has executed, it's initially null until the first // Refresh() execution. base::TimeTicks last_refresh_time_;
diff --git a/components/trusted_vault/trusted_vault_degraded_recoverability_handler_unittest.cc b/components/trusted_vault/trusted_vault_degraded_recoverability_handler_unittest.cc index b764d1d7..fe6b658 100644 --- a/components/trusted_vault/trusted_vault_degraded_recoverability_handler_unittest.cc +++ b/components/trusted_vault/trusted_vault_degraded_recoverability_handler_unittest.cc
@@ -15,7 +15,7 @@ #include "components/signin/public/identity_manager/account_info.h" #include "components/sync/base/features.h" #include "components/sync/base/time.h" -#include "components/sync/protocol/local_trusted_vault.pb.h" +#include "components/trusted_vault/proto/local_trusted_vault.pb.h" #include "components/trusted_vault/securebox.h" #include "components/trusted_vault/trusted_vault_connection.h" #include "testing/gmock/include/gmock/gmock.h" @@ -34,8 +34,8 @@ } MATCHER_P(DegradedRecoverabilityStateEq, expected_state, "") { - const sync_pb::LocalTrustedVaultDegradedRecoverabilityState& given_state = - arg; + const trusted_vault_pb::LocalTrustedVaultDegradedRecoverabilityState& + given_state = arg; return given_state.degraded_recoverability_value() == expected_state.degraded_recoverability_value() && given_state.last_refresh_time_millis_since_unix_epoch() == @@ -83,10 +83,11 @@ MockDelegate() = default; ~MockDelegate() override = default; - MOCK_METHOD(void, - WriteDegradedRecoverabilityState, - (const sync_pb::LocalTrustedVaultDegradedRecoverabilityState&), - (override)); + MOCK_METHOD( + void, + WriteDegradedRecoverabilityState, + (const trusted_vault_pb::LocalTrustedVaultDegradedRecoverabilityState&), + (override)); MOCK_METHOD(void, OnDegradedRecoverabilityChanged, (), (override)); }; @@ -109,10 +110,10 @@ base::HistogramTester histogram_tester; testing::NiceMock<MockTrustedVaultConnection> connection; testing::NiceMock<MockDelegate> delegate; - sync_pb::LocalTrustedVaultDegradedRecoverabilityState + trusted_vault_pb::LocalTrustedVaultDegradedRecoverabilityState degraded_recoverability_state; degraded_recoverability_state.set_degraded_recoverability_value( - sync_pb::DegradedRecoverabilityValue::kNotDegraded); + trusted_vault_pb::DegradedRecoverabilityValue::kNotDegraded); std::unique_ptr<TrustedVaultDegradedRecoverabilityHandler> scheduler = std::make_unique<TrustedVaultDegradedRecoverabilityHandler>( @@ -120,14 +121,14 @@ degraded_recoverability_state); histogram_tester.ExpectUniqueSample( "Sync.TrustedVaultDegradedRecoverabilityValue2", - /*sample=*/sync_pb::DegradedRecoverabilityValue::kNotDegraded, + /*sample=*/trusted_vault_pb::DegradedRecoverabilityValue::kNotDegraded, /*expected_bucket_count=*/0); // Start the scheduler. scheduler->GetIsRecoverabilityDegraded(base::DoNothing()); histogram_tester.ExpectUniqueSample( "Sync.TrustedVaultDegradedRecoverabilityValue2", - /*sample=*/sync_pb::DegradedRecoverabilityValue::kNotDegraded, + /*sample=*/trusted_vault_pb::DegradedRecoverabilityValue::kNotDegraded, /*expected_bucket_count=*/1); } @@ -141,7 +142,7 @@ std::unique_ptr<TrustedVaultDegradedRecoverabilityHandler> scheduler = std::make_unique<TrustedVaultDegradedRecoverabilityHandler>( &connection, &delegate, MakeAccountInfoWithGaiaId("user"), - sync_pb::LocalTrustedVaultDegradedRecoverabilityState()); + trusted_vault_pb::LocalTrustedVaultDegradedRecoverabilityState()); base::MockCallback<base::OnceCallback<void(bool)>> completion_callback; EXPECT_CALL(connection, DownloadIsRecoverabilityDegraded( @@ -163,10 +164,10 @@ // instance. testing::NiceMock<MockTrustedVaultConnection> connection; testing::NiceMock<MockDelegate> delegate; - sync_pb::LocalTrustedVaultDegradedRecoverabilityState + trusted_vault_pb::LocalTrustedVaultDegradedRecoverabilityState degraded_recoverability_state; degraded_recoverability_state.set_degraded_recoverability_value( - sync_pb::DegradedRecoverabilityValue::kNotDegraded); + trusted_vault_pb::DegradedRecoverabilityValue::kNotDegraded); degraded_recoverability_state.set_last_refresh_time_millis_since_unix_epoch( syncer::TimeToProtoTime(base::Time::Now())); @@ -202,7 +203,7 @@ std::unique_ptr<TrustedVaultDegradedRecoverabilityHandler> scheduler = std::make_unique<TrustedVaultDegradedRecoverabilityHandler>( &connection, &delegate, MakeAccountInfoWithGaiaId("user"), - sync_pb::LocalTrustedVaultDegradedRecoverabilityState()); + trusted_vault_pb::LocalTrustedVaultDegradedRecoverabilityState()); // Start the scheduler. scheduler->GetIsRecoverabilityDegraded(base::DoNothing()); // Moving the time forward by one millisecond to make sure that the first @@ -225,10 +226,10 @@ ShouldRefreshOncePerShortPeriod) { testing::NiceMock<MockTrustedVaultConnection> connection; testing::NiceMock<MockDelegate> delegate; - sync_pb::LocalTrustedVaultDegradedRecoverabilityState + trusted_vault_pb::LocalTrustedVaultDegradedRecoverabilityState degraded_recoverability_state; degraded_recoverability_state.set_degraded_recoverability_value( - sync_pb::DegradedRecoverabilityValue::kDegraded); + trusted_vault_pb::DegradedRecoverabilityValue::kDegraded); degraded_recoverability_state.set_last_refresh_time_millis_since_unix_epoch( syncer::TimeToProtoTime(base::Time::Now())); @@ -249,10 +250,10 @@ ShouldRefreshOncePerLongPeriod) { testing::NiceMock<MockTrustedVaultConnection> connection; testing::NiceMock<MockDelegate> delegate; - sync_pb::LocalTrustedVaultDegradedRecoverabilityState + trusted_vault_pb::LocalTrustedVaultDegradedRecoverabilityState degraded_recoverability_state; degraded_recoverability_state.set_degraded_recoverability_value( - sync_pb::DegradedRecoverabilityValue::kNotDegraded); + trusted_vault_pb::DegradedRecoverabilityValue::kNotDegraded); degraded_recoverability_state.set_last_refresh_time_millis_since_unix_epoch( syncer::TimeToProtoTime(base::Time::Now())); @@ -285,7 +286,7 @@ std::unique_ptr<TrustedVaultDegradedRecoverabilityHandler> scheduler = std::make_unique<TrustedVaultDegradedRecoverabilityHandler>( &connection, &delegate, MakeAccountInfoWithGaiaId("user"), - sync_pb::LocalTrustedVaultDegradedRecoverabilityState()); + trusted_vault_pb::LocalTrustedVaultDegradedRecoverabilityState()); // Make handler aware about degraded recoverability. EXPECT_CALL(connection, DownloadIsRecoverabilityDegraded( @@ -313,10 +314,10 @@ ShouldSwitchToLongPeriod) { testing::NiceMock<MockTrustedVaultConnection> connection; testing::NiceMock<MockDelegate> delegate; - sync_pb::LocalTrustedVaultDegradedRecoverabilityState + trusted_vault_pb::LocalTrustedVaultDegradedRecoverabilityState degraded_recoverability_state; degraded_recoverability_state.set_degraded_recoverability_value( - sync_pb::DegradedRecoverabilityValue::kDegraded); + trusted_vault_pb::DegradedRecoverabilityValue::kDegraded); degraded_recoverability_state.set_last_refresh_time_millis_since_unix_epoch( syncer::TimeToProtoTime(base::Time::Now())); @@ -376,17 +377,17 @@ std::unique_ptr<TrustedVaultDegradedRecoverabilityHandler> scheduler = std::make_unique<TrustedVaultDegradedRecoverabilityHandler>( &connection, &delegate, MakeAccountInfoWithGaiaId("user"), - sync_pb::LocalTrustedVaultDegradedRecoverabilityState()); + trusted_vault_pb::LocalTrustedVaultDegradedRecoverabilityState()); // Start the scheduler. scheduler->GetIsRecoverabilityDegraded(base::DoNothing()); // Moving the time forward by one millisecond to make sure that the first // refresh had called. task_environment().FastForwardBy(base::Milliseconds(1)); - sync_pb::LocalTrustedVaultDegradedRecoverabilityState + trusted_vault_pb::LocalTrustedVaultDegradedRecoverabilityState degraded_recoverability_state; degraded_recoverability_state.set_degraded_recoverability_value( - sync_pb::DegradedRecoverabilityValue::kDegraded); + trusted_vault_pb::DegradedRecoverabilityValue::kDegraded); // Since the time is not moving, the `Time::Now()` is the expected to be // written. degraded_recoverability_state.set_last_refresh_time_millis_since_unix_epoch( @@ -428,17 +429,17 @@ std::unique_ptr<TrustedVaultDegradedRecoverabilityHandler> scheduler = std::make_unique<TrustedVaultDegradedRecoverabilityHandler>( &connection, &delegate, MakeAccountInfoWithGaiaId("user"), - sync_pb::LocalTrustedVaultDegradedRecoverabilityState()); + trusted_vault_pb::LocalTrustedVaultDegradedRecoverabilityState()); // Start the scheduler. scheduler->GetIsRecoverabilityDegraded(base::DoNothing()); // Moving the time forward by one millisecond to make sure that the first // refresh had called. task_environment().FastForwardBy(base::Milliseconds(1)); - sync_pb::LocalTrustedVaultDegradedRecoverabilityState + trusted_vault_pb::LocalTrustedVaultDegradedRecoverabilityState degraded_recoverability_state; degraded_recoverability_state.set_degraded_recoverability_value( - sync_pb::DegradedRecoverabilityValue::kNotDegraded); + trusted_vault_pb::DegradedRecoverabilityValue::kNotDegraded); // Since the time is not moving, the `Time::Now()` is the expected to be // written. degraded_recoverability_state.set_last_refresh_time_millis_since_unix_epoch( @@ -463,7 +464,7 @@ ShouldComputeTheNextRefreshTimeBasedOnTheStoredState) { testing::NiceMock<MockTrustedVaultConnection> connection; testing::NiceMock<MockDelegate> delegate; - sync_pb::LocalTrustedVaultDegradedRecoverabilityState + trusted_vault_pb::LocalTrustedVaultDegradedRecoverabilityState degraded_recoverability_state; degraded_recoverability_state.set_last_refresh_time_millis_since_unix_epoch( syncer::TimeToProtoTime(base::Time::Now() - base::Minutes(1)));
diff --git a/components/ui_devtools/views/overlay_agent_views.cc b/components/ui_devtools/views/overlay_agent_views.cc index 7768cd64..ce362fe9 100644 --- a/components/ui_devtools/views/overlay_agent_views.cc +++ b/components/ui_devtools/views/overlay_agent_views.cc
@@ -56,8 +56,10 @@ SK_ColorMAGENTA); int short_stroke = 5; + int mid_stroke = 7; int long_stroke = 10; - int gap_between_strokes = 4; + int gap_between_strokes = 5; + int gap_between_mid_stroke = 25; int gap_between_long_stroke = 100; // Draw top horizontal ruler. @@ -71,6 +73,9 @@ DrawRulerText(utf16_text, gfx::Point(x + 2, long_stroke), canvas, render_text_); + } else if (x % gap_between_mid_stroke == 0) { + canvas->Draw1pxLine(gfx::PointF(x, 0.0f), gfx::PointF(x, mid_stroke), + SK_ColorMAGENTA); } else { canvas->Draw1pxLine(gfx::PointF(x, 0.0f), gfx::PointF(x, short_stroke), SK_ColorMAGENTA);
diff --git a/components/webdata/common/web_database_table.h b/components/webdata/common/web_database_table.h index 0b3cd9c..9ecacb5d 100644 --- a/components/webdata/common/web_database_table.h +++ b/components/webdata/common/web_database_table.h
@@ -40,13 +40,6 @@ // Returns true on success, false on failure. virtual bool CreateTablesIfNecessary() = 0; - // In order to encourage developers to think about sync when adding or - // or altering new tables, this method must be implemented. Please get in - // contact with the sync team if you believe you're making a change that they - // should be aware of (or if you could break something). - // TODO(andybons): Implement something more robust. - virtual bool IsSyncable() = 0; - // Migrates this table to |version|. Returns false if there was // migration work to do and it failed, true otherwise. //
diff --git a/content/BUILD.gn b/content/BUILD.gn index 27141a8..5750a33 100644 --- a/content/BUILD.gn +++ b/content/BUILD.gn
@@ -94,10 +94,7 @@ "grit/content_resources_map.h", "content_resources.pak", ] - deps = [ - "//components/ukm/debug:build_ts", - "//gpu/ipc/common:vulkan_interface_js__generator", - ] + deps = [ "//components/ukm/debug:build_ts" ] if (is_chromeos_ash) { deps += [
diff --git a/content/browser/gpu/gpu_internals_ui.cc b/content/browser/gpu/gpu_internals_ui.cc index 2adc779..67d7619 100644 --- a/content/browser/gpu/gpu_internals_ui.cc +++ b/content/browser/gpu/gpu_internals_ui.cc
@@ -28,7 +28,6 @@ #include "content/browser/gpu/compositor_util.h" #include "content/browser/gpu/gpu_data_manager_impl.h" #include "content/browser/gpu/gpu_process_host.h" -#include "content/grit/content_resources.h" #include "content/grit/gpu_resources.h" #include "content/grit/gpu_resources_map.h" #include "content/public/browser/browser_thread.h" @@ -83,10 +82,6 @@ source->UseStringsJs(); source->AddResourcePaths(base::make_span(kGpuResources, kGpuResourcesSize)); - source->AddResourcePath("vulkan_info.mojom-webui.js", - IDR_VULKAN_INFO_MOJO_JS); - source->AddResourcePath("vulkan_types.mojom-webui.js", - IDR_VULKAN_TYPES_MOJO_JS); source->AddResourcePath("", IDR_GPU_GPU_INTERNALS_HTML); }
diff --git a/content/browser/interest_group/auction_runner_unittest.cc b/content/browser/interest_group/auction_runner_unittest.cc index f778743..28ae86c8 100644 --- a/content/browser/interest_group/auction_runner_unittest.cc +++ b/content/browser/interest_group/auction_runner_unittest.cc
@@ -119,12 +119,15 @@ R"({"keys": {"l1":"a", "l2": "b", "extra": "c"}})"; const char kPostAuctionSignalsPlaceholder[] = - "?winningBid=${winningBid}&madeWinningBid=${madeWinningBid}&" + "?winningBid=${winningBid}&" + "winningBidCurrency=${winningBidCurrency}&madeWinningBid=${madeWinningBid}&" "highestScoringOtherBid=${highestScoringOtherBid}&" + "highestScoringOtherBidCurrency=${highestScoringOtherBidCurrency}&" "madeHighestScoringOtherBid=${madeHighestScoringOtherBid}"; const char kTopLevelPostAuctionSignalsPlaceholder[] = "topLevelWinningBid=${topLevelWinningBid}&" + "topLevelWinningBidCurrency=${topLevelWinningBidCurrency}&" "topLevelMadeWinningBid=${topLevelMadeWinningBid}"; const auction_worklet::mojom::PrivateAggregationRequestPtr @@ -374,8 +377,10 @@ throw new Error("wrong interestGroupOwner"); if (sellerSignals.renderUrl !== renderUrl) throw new Error("wrong renderUrl"); - if (sellerSignals.bid !== bid) - throw new Error("wrong bid"); + if (sellerSignals.bid !== bid) { + throw new Error("wrong bid, bidder:" + bid + + " seller:" + sellerSignals.bid); + } // `sellerSignals` is the `browserSignals` for the seller that's // associated with the bid. If it's the top-level seller, the seller's // `browserSignals` should have no `componentSeller`, since the bid @@ -425,8 +430,12 @@ if (reportPostAuctionSignals) { sendReportUrl += '?highestScoringOtherBid=' + browserSignals.highestScoringOtherBid + + '&highestScoringOtherBidCurrency=' + + browserSignals.highestScoringOtherBidCurrency + '&madeHighestScoringOtherBid=' + - browserSignals.madeHighestScoringOtherBid + '&bid='; + browserSignals.madeHighestScoringOtherBid + + '&bidCurrency=' + browserSignals.bidCurrency + + '&bid='; } sendReportTo(sendReportUrl + bid); registerAdBeacon({ @@ -460,8 +469,11 @@ sendReportTo( "https://buyer-reporting.example.com/" + '?highestScoringOtherBid=' + browserSignals.highestScoringOtherBid + + '&highestScoringOtherBidCurrency=' + + browserSignals.highestScoringOtherBidCurrency + '&madeHighestScoringOtherBid=' + browserSignals.madeHighestScoringOtherBid + + '&bidCurrency=' + browserSignals.bidCurrency + '&bid=' + browserSignals.bid); } )"; @@ -664,7 +676,9 @@ adMetadata.fromComponentAuction = true; - return {desirability: computeScore(bid), + let convertedBid = auctionConfig.sellerCurrency ? bid * 10 : undefined; + return {desirability: computeScore(convertedBid ? convertedBid : bid), + incomingBidInSellerCurrency: convertedBid, // Only allow a component auction when the passed in ad is from // one. allowComponentAuction: @@ -743,7 +757,11 @@ }); if (reportPostAuctionSignals) { sendReportUrl += "?highestScoringOtherBid=" + - browserSignals.highestScoringOtherBid + "&bid="; + browserSignals.highestScoringOtherBid + + '&highestScoringOtherBidCurrency=' + + browserSignals.highestScoringOtherBidCurrency + + "&bidCurrency=" + browserSignals.bidCurrency + + "&bid="; } sendReportTo(sendReportUrl + browserSignals.bid); } @@ -753,6 +771,11 @@ privateAggregation.reportContributionForEvent( 'click', {bucket: 70n, value: 80}); + // Convert the bid back into bidder currency if we're covering that. + if (auctionConfig.sellerCurrency) { + browserSignals.bid /= 10.0; + } + return browserSignals; } @@ -813,6 +836,10 @@ registerAdBeacon({ "click": "https://reporting.example.com/" + 2*browserSignals.bid, }); + // Convert the bid back into bidder currency if we're covering that. + if (auctionConfig.sellerCurrency) { + browserSignals.bid /= 10.0; + } return browserSignals; } )"; @@ -824,7 +851,8 @@ privateAggregation.sendHistogramReport({bucket: 5n, value: 6}); if (bid === 2) return {desirability: -1, rejectReason: '%s'}; - return bid + 1; + let convertedBid = auctionConfig.sellerCurrency ? bid * 10 : undefined; + return {desirability: bid + 1, incomingBidInSellerCurrency: convertedBid}; } )"; return base::StringPrintf(kAuctionScriptRejects2, reject_reason.c_str()) + @@ -883,15 +911,19 @@ debugLossReportUrl + postAuctionSignalsPlaceholder + '&bid=' + bid); forDebuggingOnly.reportAdAuctionWin( debugWinReportUrl + postAuctionSignalsPlaceholder + '&bid=' + bid); - return {ad: [], bid: bid, render: interestGroup.ads[0].renderUrl}; + return {ad: [], bid: bid, bidCurrency: 'USD', + render: interestGroup.ads[0].renderUrl}; } function reportWin( auctionSignals, perBuyerSignals, sellerSignals, browserSignals) { sendReportTo( 'https://buyer-reporting.example.com/?highestScoringOtherBid=' + browserSignals.highestScoringOtherBid + + '&highestScoringOtherBidCurrency=' + + browserSignals.highestScoringOtherBidCurrency + '&madeHighestScoringOtherBid=' + browserSignals.madeHighestScoringOtherBid + + '&bidCurrency=' + browserSignals.bidCurrency + '&bid=' + browserSignals.bid); } )"; @@ -911,13 +943,18 @@ debugLossReportUrl + postAuctionSignalsPlaceholder + "&bid=" + bid); forDebuggingOnly.reportAdAuctionWin( debugWinReportUrl + postAuctionSignalsPlaceholder + "&bid=" + bid); - return bid = (bid == 3 || bid == 4) ? 3 : 1; + let score = (bid == 3 || bid == 4) ? 3 : 1; + let convertedBid = auctionConfig.sellerCurrency ? bid * 10 : undefined; + return {desirability: score, incomingBidInSellerCurrency: convertedBid}; } function reportResult(auctionConfig, browserSignals) { sendReportTo( "https://reporting.example.com/?highestScoringOtherBid=" + - browserSignals.highestScoringOtherBid + "&bid=" + - browserSignals.bid); + browserSignals.highestScoringOtherBid + + '&highestScoringOtherBidCurrency=' + + browserSignals.highestScoringOtherBidCurrency + + "&bidCurrency=" + browserSignals.bidCurrency + + "&bid=" + browserSignals.bid); } )"; return base::StringPrintf( @@ -961,15 +998,20 @@ // signals included in the URL const GURL ReportWinUrl( double bid, + const absl::optional<blink::AdCurrency>& bid_currency, double highest_scoring_other_bid, + const absl::optional<blink::AdCurrency>& highest_scoring_other_bid_currency, bool made_highest_scoring_other_bid, const std::string& url = "https://buyer-reporting.example.com/") { // Only keeps integer part of bid values for simplicity for now. return GURL(base::StringPrintf( "%s" - "?highestScoringOtherBid=%.0f&madeHighestScoringOtherBid=%s&bid=%.0f", + "?highestScoringOtherBid=%.0f&highestScoringOtherBidCurrency=%s" + "&madeHighestScoringOtherBid=%s&bidCurrency=%s&bid=%.0f", url.c_str(), highest_scoring_other_bid, - made_highest_scoring_other_bid ? "true" : "false", bid)); + blink::PrintableAdCurrency(highest_scoring_other_bid_currency).c_str(), + made_highest_scoring_other_bid ? "true" : "false", + blink::PrintableAdCurrency(bid_currency).c_str(), bid)); } // Returns a report URL with given parameters for forDebuggingOnly win/loss @@ -985,11 +1027,15 @@ std::string report_url_string = base::StringPrintf( "%s" // Post auction signals - "?winningBid=%.0f&madeWinningBid=%s&highestScoringOtherBid=%.0f&" - "madeHighestScoringOtherBid=%s", + "?winningBid=%.0f&winningBidCurrency=%s&" + "madeWinningBid=%s&highestScoringOtherBid=%.0f&" + "highestScoringOtherBidCurrency=%s&madeHighestScoringOtherBid=%s", url.c_str(), signals.winning_bid, + blink::PrintableAdCurrency(signals.winning_bid_currency).c_str(), signals.made_winning_bid ? "true" : "false", signals.highest_scoring_other_bid, + blink::PrintableAdCurrency(signals.highest_scoring_other_bid_currency) + .c_str(), signals.made_highest_scoring_other_bid ? "true" : "false"); if (reject_reason.has_value()) { report_url_string.append( @@ -1019,17 +1065,24 @@ return GURL(base::StringPrintf( "%s" // Post auction signals. - "?winningBid=%.0f&madeWinningBid=%s&highestScoringOtherBid=%.0f&" - "madeHighestScoringOtherBid=%s" + "?winningBid=%.0f&winningBidCurrency=%s&" + "madeWinningBid=%s&highestScoringOtherBid=%.0f&" + "highestScoringOtherBidCurrency=%s&madeHighestScoringOtherBid=%s" // Top level post auction signals. - "&topLevelWinningBid=%.0f&topLevelMadeWinningBid=%s" + "&topLevelWinningBid=%.0f&topLevelWinningBidCurrency=%s&" + "topLevelMadeWinningBid=%s" // Bid value. "&bid=%.0f", url.c_str(), signals.winning_bid, + blink::PrintableAdCurrency(signals.winning_bid_currency).c_str(), signals.made_winning_bid ? "true" : "false", signals.highest_scoring_other_bid, + blink::PrintableAdCurrency(signals.highest_scoring_other_bid_currency) + .c_str(), signals.made_highest_scoring_other_bid ? "true" : "false", top_level_signals.winning_bid, + blink::PrintableAdCurrency(top_level_signals.winning_bid_currency) + .c_str(), top_level_signals.made_winning_bid ? "true" : "false", bid)); } @@ -1390,7 +1443,9 @@ return blink::AuctionConfig::MaybePromiseBuyerCurrencies::FromPromise(); } else { blink::AuctionConfig::BuyerCurrencies buyer_currencies; - buyer_currencies.all_buyers_currency = "USD"; + if (specify_all_buyer_currency_) { + buyer_currencies.all_buyers_currency = blink::AdCurrency::From("USD"); + } return blink::AuctionConfig::MaybePromiseBuyerCurrencies::FromValue( std::move(buyer_currencies)); } @@ -1421,6 +1476,7 @@ MakeBuyerCumulativeTimeouts(use_promise_for_buyer_cumulative_timeouts_); auction_config.non_shared_params.buyer_currencies = MakeBuyerCurrencies(use_promise_for_buyer_currencies_); + auction_config.non_shared_params.seller_currency = seller_currency_; auction_config.non_shared_params.auction_signals = MakeAuctionSignals( use_promise_for_auction_signals_, auction_config.seller); @@ -1825,7 +1881,7 @@ } bidder_worklet->InvokeGenerateBidCallback( /*bid=*/should_bid[i] ? absl::make_optional(1) : absl::nullopt, - blink::kUnspecifiedAdCurrency, + /*bid_currency=*/absl::nullopt, blink::AdDescriptor(GURL("https://ad1.com/"))); if (should_bid[i]) { auto score_ad_params = seller_worklet->WaitForScoreAd(); @@ -1836,8 +1892,8 @@ /*reject_reason=*/ auction_worklet::mojom::RejectReason::kNotAvailable, auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr(), - /*scoring_signals_data_version=*/0, - /*has_scoring_signals_data_version=*/false, + /*bid_in_seller_currency=*/absl::nullopt, + /*scoring_signals_data_version=*/absl::nullopt, /*debug_loss_report_url=*/absl::nullopt, /*debug_win_report_url=*/absl::nullopt, /*pa_requests=*/{}, /*errors=*/{}); @@ -2391,6 +2447,8 @@ bool use_promise_for_buyer_timeouts_ = false; bool use_promise_for_buyer_cumulative_timeouts_ = false; bool use_promise_for_buyer_currencies_ = false; + bool specify_all_buyer_currency_ = true; + absl::optional<blink::AdCurrency> seller_currency_; // Unlike others, this is only test with promises at this level. bool pass_promise_for_direct_from_seller_signals_ = false; @@ -2731,8 +2789,14 @@ EXPECT_THAT( result_.report_urls, testing::UnorderedElementsAre( - GURL("https://reporting.example.com/?highestScoringOtherBid=0&bid=1"), - ReportWinUrl(/*bid=*/1, /*highest_scoring_other_bid=*/0, + GURL("https://reporting.example.com/" + "?highestScoringOtherBid=0&" + "highestScoringOtherBidCurrency=???&" + "bidCurrency=???&bid=1"), + ReportWinUrl(/*bid=*/1, + /*bid_currency=*/blink::AdCurrency::From("USD"), + /*highest_scoring_other_bid=*/0, + /*highest_scoring_other_bid_currency=*/absl::nullopt, /*made_highest_scoring_other_bid=*/false))); EXPECT_THAT(result_.interest_groups_that_bid, testing::UnorderedElementsAre(kBidder1Key)); @@ -2882,8 +2946,14 @@ EXPECT_THAT( result_.report_urls, testing::UnorderedElementsAre( - GURL("https://reporting.example.com/?highestScoringOtherBid=1&bid=2"), - ReportWinUrl(/*bid=*/2, /*highest_scoring_other_bid=*/1, + GURL("https://reporting.example.com/" + "?highestScoringOtherBid=1&" + "highestScoringOtherBidCurrency=???&" + "bidCurrency=???&bid=2"), + ReportWinUrl(/*bid=*/2, + /*bid_currency=*/blink::AdCurrency::From("USD"), + /*highest_scoring_other_bid=*/1, + /*highest_scoring_other_bid_currency=*/absl::nullopt, /*made_highest_scoring_other_bid=*/false))); EXPECT_THAT( result_.ad_beacon_map, @@ -2998,6 +3068,56 @@ " returned 'CAD', expected 'USD'.")); } +TEST_F(AuctionRunnerTest, BasicCurrencyRedact) { + // Make sure that if buyer currency isn't specified in AuctionConfig it's + // redacted in reportWin() + specify_all_buyer_currency_ = false; + + auction_worklet::AddJavascriptResponse( + &url_loader_factory_, kBidder1Url, + MakeBidScript(kSeller, "1", "https://ad1.com/", /*num_ad_components=*/2, + kBidder1, kBidder1Name, + /*has_signals=*/true, "k1", "a", + /*report_post_auction_signals=*/true)); + auction_worklet::AddJavascriptResponse( + &url_loader_factory_, kBidder2Url, + MakeBidScript(kSeller, "2", "https://ad2.com/", /*num_ad_components=*/2, + kBidder2, kBidder2Name, + /*has_signals=*/true, "l2", "b", + /*report_post_auction_signals=*/true)); + auction_worklet::AddJavascriptResponse( + &url_loader_factory_, kSellerUrl, + MakeAuctionScript(/*report_post_auction_signals=*/true)); + auction_worklet::AddBidderJsonResponse( + &url_loader_factory_, + GURL(kBidder1TrustedSignalsUrl.spec() + + "?hostname=publisher1.com&keys=k1,k2" + "&interestGroupNames=Ad+Platform"), + kBidder1SignalsJson); + auction_worklet::AddBidderJsonResponse( + &url_loader_factory_, + GURL(kBidder2TrustedSignalsUrl.spec() + + "?hostname=publisher1.com&keys=l1,l2" + "&interestGroupNames=Another+Ad+Thing"), + kBidder2SignalsJson); + + RunStandardAuction(); + EXPECT_FALSE(result_.manually_aborted); + EXPECT_EQ(kBidder2Key, result_.winning_group_id); + EXPECT_EQ(GURL("https://ad2.com/"), result_.ad_descriptor->url); + EXPECT_THAT(result_.report_urls, + testing::UnorderedElementsAre( + GURL("https://reporting.example.com/" + "?highestScoringOtherBid=1&" + "highestScoringOtherBidCurrency=???&" + "bidCurrency=???&bid=2"), + ReportWinUrl( + /*bid=*/2, /*bid_currency=*/absl::nullopt, + /*highest_scoring_other_bid=*/1, + /*highest_scoring_other_bid_currency=*/absl::nullopt, + /*made_highest_scoring_other_bid=*/false))); +} + TEST_F(AuctionRunnerTest, BasicDebug) { auction_worklet::AddJavascriptResponse( &url_loader_factory_, kBidder1Url, @@ -3358,10 +3478,18 @@ EXPECT_THAT( result_.report_urls, testing::UnorderedElementsAre( - GURL("https://reporting.example.com/?highestScoringOtherBid=1&bid=2"), - GURL( - "https://component2-report.test/?highestScoringOtherBid=0&bid=2"), - ReportWinUrl(/*bid=*/2, /*highest_scoring_other_bid=*/0, + GURL("https://reporting.example.com/" + "?highestScoringOtherBid=1&" + "highestScoringOtherBidCurrency=???&" + "bidCurrency=???&bid=2"), + GURL("https://component2-report.test/" + "?highestScoringOtherBid=0&" + "highestScoringOtherBidCurrency=???&" + "bidCurrency=???&bid=2"), + ReportWinUrl(/*bid=*/2, + /*bid_currency=*/blink::AdCurrency::From("USD"), + /*highest_scoring_other_bid=*/0, + /*highest_scoring_other_bid_currency=*/absl::nullopt, /*made_highest_scoring_other_bid=*/false))); EXPECT_THAT( result_.ad_beacon_map, @@ -3689,10 +3817,18 @@ EXPECT_THAT( result_.report_urls, testing::UnorderedElementsAre( - GURL("https://reporting.example.com/?highestScoringOtherBid=0&bid=1"), - GURL( - "https://component1-report.test/?highestScoringOtherBid=2&bid=1"), - ReportWinUrl(/*bid=*/1, /*highest_scoring_other_bid=*/2, + GURL("https://reporting.example.com/" + "?highestScoringOtherBid=0&" + "highestScoringOtherBidCurrency=???&" + "bidCurrency=???&bid=1"), + GURL("https://component1-report.test/" + "?highestScoringOtherBid=2&" + "highestScoringOtherBidCurrency=???&" + "bidCurrency=???&bid=1"), + ReportWinUrl(/*bid=*/1, + /*bid_currency=*/blink::AdCurrency::From("USD"), + /*highest_scoring_other_bid=*/2, + /*highest_scoring_other_bid_currency=*/absl::nullopt, /*made_highest_scoring_other_bid=*/false))); EXPECT_THAT( result_.ad_beacon_map, @@ -3889,11 +4025,12 @@ } )"; - // Component seller script that modifies the bid to 3 USD. + // Component seller script that modifies the bid to 3 USD; also notes that + // it interpreted the incoming bid as 20 in sellerCurrency. const std::string kComponentSellerScript = R"( function scoreAd(adMetadata, bid, auctionConfig, browserSignals) { return {desirability: 10, allowComponentAuction: true, bid: 3, - bidCurrency: 'USD'}; + bidCurrency: 'USD', incomingBidInSellerCurrency: 20}; } function reportResult(auctionConfig, browserSignals) { @@ -3936,7 +4073,7 @@ component_auctions_.emplace_back( CreateAuctionConfig(kComponentSeller1Url, {{kBidder1}})); component_auctions_[0].non_shared_params.seller_currency = - match_currency ? "USD" : "CAD"; + blink::AdCurrency::From(match_currency ? "USD" : "CAD"); // Basic interest group. std::vector<StorageInterestGroup> bidders; @@ -3951,11 +4088,12 @@ EXPECT_THAT(result_.errors, testing::ElementsAre()); EXPECT_EQ(GURL("https://ad1.com"), result_.ad_descriptor->url); // The reporting URLs contain the bids - the top-level seller report - // should see the modified bid, the other worklets see the original bid. + // should see the modified bid, the other worklets see the original bid + // (modulo currency conversion). EXPECT_THAT(result_.report_urls, testing::UnorderedElementsAre( GURL("https://buyer-reporting.example.com/2"), - GURL("https://component.seller1.test/2_3"), + GURL("https://component.seller1.test/20_3"), GURL("https://adstuff.publisher1.com/3"))); EXPECT_THAT( result_.ad_beacon_map, @@ -3967,7 +4105,7 @@ testing::Pair( ReportingDestination::kComponentSeller, testing::ElementsAre(testing::Pair( - "click", GURL("https://component.seller1.test/4_3")))), + "click", GURL("https://component.seller1.test/40_3")))), testing::Pair( ReportingDestination::kBuyer, testing::ElementsAre(testing::Pair( @@ -7485,11 +7623,11 @@ ASSERT_TRUE(bidder2_worklet); bidder1_worklet->InvokeGenerateBidCallback( - /*bid=*/6, blink::kUnspecifiedAdCurrency, + /*bid=*/6, /*bid_currency=*/absl::nullopt, blink::AdDescriptor(GURL("https://ad1.com/"))); bidder1_worklet.reset(); bidder2_worklet->InvokeGenerateBidCallback( - /*bid=*/7, blink::kUnspecifiedAdCurrency, + /*bid=*/7, /*bid_currency=*/absl::nullopt, blink::AdDescriptor(GURL("https://ad2.com/"))); bidder2_worklet.reset(); @@ -7513,8 +7651,8 @@ /*reject_reason=*/ auction_worklet::mojom::RejectReason::kNotAvailable, auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr(), - /*scoring_signals_data_version=*/0, - /*has_scoring_signals_data_version=*/false, + /*bid_in_seller_currency=*/absl::nullopt, + /*scoring_signals_data_version=*/absl::nullopt, /*debug_loss_report_url=*/absl::nullopt, /*debug_win_report_url=*/absl::nullopt, /*pa_requests=*/{}, /*errors=*/{}); @@ -7529,8 +7667,8 @@ /*reject_reason=*/ auction_worklet::mojom::RejectReason::kNotAvailable, auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr(), - /*scoring_signals_data_version=*/0, - /*has_scoring_signals_data_version=*/false, + /*bid_in_seller_currency=*/absl::nullopt, + /*scoring_signals_data_version=*/absl::nullopt, /*debug_loss_report_url=*/absl::nullopt, /*debug_win_report_url=*/absl::nullopt, /*pa_requests=*/{}, /*errors=*/{}); @@ -7733,7 +7871,7 @@ ASSERT_FALSE(auction_complete_); if (other_bidder_finishes_first) { bidder2_worklet->InvokeGenerateBidCallback( - /*bid=*/7, blink::kUnspecifiedAdCurrency, + /*bid=*/7, /*bid_currency=*/absl::nullopt, blink::AdDescriptor(GURL("https://ad2.com/"))); // The bidder pipe should be closed after it bids. EXPECT_TRUE(bidder2_worklet->PipeIsClosed()); @@ -7751,7 +7889,7 @@ if (!other_bidder_finishes_first) { bidder2_worklet->InvokeGenerateBidCallback( - /*bid=*/7, blink::kUnspecifiedAdCurrency, + /*bid=*/7, /*bid_currency=*/absl::nullopt, blink::AdDescriptor(GURL("https://ad2.com/"))); // The bidder pipe should be closed after it bids. EXPECT_TRUE(bidder2_worklet->PipeIsClosed()); @@ -7782,8 +7920,8 @@ /*reject_reason=*/ auction_worklet::mojom::RejectReason::kNotAvailable, auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr(), - /*scoring_signals_data_version=*/0, - /*has_scoring_signals_data_version=*/false, + /*bid_in_seller_currency=*/absl::nullopt, + /*scoring_signals_data_version=*/absl::nullopt, /*debug_loss_report_url=*/absl::nullopt, /*debug_win_report_url=*/absl::nullopt, /*pa_requests=*/{}, /*errors=*/{}); @@ -7892,10 +8030,10 @@ } else { // Generate both bids, wait for seller to receive them.. bidder1_worklet->InvokeGenerateBidCallback( - /*bid=*/5, blink::kUnspecifiedAdCurrency, + /*bid=*/5, /*bid_currency=*/absl::nullopt, blink::AdDescriptor(GURL("https://ad1.com/"))); bidder2_worklet->InvokeGenerateBidCallback( - /*bid=*/7, blink::kUnspecifiedAdCurrency, + /*bid=*/7, /*bid_currency=*/absl::nullopt, blink::AdDescriptor(GURL("https://ad2.com/"))); auto score_ad_params = seller_worklet->WaitForScoreAd(); auto score_ad_params2 = seller_worklet->WaitForScoreAd(); @@ -7995,7 +8133,7 @@ mock_auction_process_manager_->TakeBidderWorklet(kBidder2Url); ASSERT_TRUE(bidder2_worklet); bidder2_worklet->InvokeGenerateBidCallback( - 2, blink::kUnspecifiedAdCurrency, + 2, /*bid_currency=*/absl::nullopt, blink::AdDescriptor(GURL("https://ad2.com/"))); // Component worklet scores the bid. @@ -8014,10 +8152,10 @@ auction_worklet::mojom::ComponentAuctionModifiedBidParams::New( /*ad=*/"null", /*bid=*/0, - /*bid_currency=*/"", + /*bid_currency=*/absl::nullopt, /*has_bid=*/false), - /*scoring_signals_data_version=*/0, - /*has_scoring_signals_data_version=*/false, + /*bid_in_seller_currency=*/absl::nullopt, + /*scoring_signals_data_version=*/absl::nullopt, /*debug_loss_report_url=*/absl::nullopt, /*debug_win_report_url=*/absl::nullopt, /*pa_requests=*/{}, /*errors=*/{}); @@ -8036,8 +8174,8 @@ /*reject_reason=*/ auction_worklet::mojom::RejectReason::kNotAvailable, auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr(), - /*scoring_signals_data_version=*/0, - /*has_scoring_signals_data_version=*/false, + /*bid_in_seller_currency=*/absl::nullopt, + /*scoring_signals_data_version=*/absl::nullopt, /*debug_loss_report_url=*/absl::nullopt, /*debug_win_report_url=*/absl::nullopt, /*pa_requests=*/{}, /*errors=*/{}); @@ -8144,30 +8282,30 @@ // Bad bids. {auction_worklet::mojom::ComponentAuctionModifiedBidParams::New( /*ad=*/"null", - /*bid=*/0, blink::kUnspecifiedAdCurrency, + /*bid=*/0, /*bid_currency=*/absl::nullopt, /*has_bid=*/true), "Invalid component_auction_modified_bid_params bid"}, {auction_worklet::mojom::ComponentAuctionModifiedBidParams::New( /*ad=*/"null", - /*bid=*/-1, blink::kUnspecifiedAdCurrency, + /*bid=*/-1, /*bid_currency=*/absl::nullopt, /*has_bid=*/true), "Invalid component_auction_modified_bid_params bid"}, {auction_worklet::mojom::ComponentAuctionModifiedBidParams::New( /*ad=*/"null", /*bid=*/std::numeric_limits<double>::infinity(), - blink::kUnspecifiedAdCurrency, + /*bid_currency=*/absl::nullopt, /*has_bid=*/true), "Invalid component_auction_modified_bid_params bid"}, {auction_worklet::mojom::ComponentAuctionModifiedBidParams::New( /*ad=*/"null", /*bid=*/-std::numeric_limits<double>::infinity(), - blink::kUnspecifiedAdCurrency, + /*bid_currency=*/absl::nullopt, /*has_bid=*/true), "Invalid component_auction_modified_bid_params bid"}, {auction_worklet::mojom::ComponentAuctionModifiedBidParams::New( /*ad=*/"null", /*bid=*/-std::numeric_limits<double>::quiet_NaN(), - blink::kUnspecifiedAdCurrency, + /*bid_currency=*/absl::nullopt, /*has_bid=*/true), "Invalid component_auction_modified_bid_params bid"}, @@ -8175,19 +8313,13 @@ {auction_worklet::mojom::ComponentAuctionModifiedBidParams::New( /*ad=*/"null", /*bid=*/2, - /*bid_currency=*/"Dollar", + /*bid_currency=*/blink::AdCurrency::From("USD"), /*has_bid=*/true), "Invalid component_auction_modified_bid_params bid_currency"}, {auction_worklet::mojom::ComponentAuctionModifiedBidParams::New( /*ad=*/"null", /*bid=*/2, - /*bid_currency=*/"USD", - /*has_bid=*/true), - "Invalid component_auction_modified_bid_params bid_currency"}, - {auction_worklet::mojom::ComponentAuctionModifiedBidParams::New( - /*ad=*/"null", - /*bid=*/2, - /*bid_currency=*/"CAD", + /*bid_currency=*/blink::AdCurrency::From("CAD"), /*has_bid=*/true), "Invalid component_auction_modified_bid_params bid_currency"}}; @@ -8196,7 +8328,8 @@ /*bid_from_component_auction_wins=*/true); // The default top-level config requires USD, so one of the two currency // checks will always fail here. - component_auctions_[0].non_shared_params.seller_currency = "CAD"; + component_auctions_[0].non_shared_params.seller_currency = + blink::AdCurrency::From("CAD"); for (const auto& test_case : kTestCases) { StartStandardAuctionWithMockService(); @@ -8213,7 +8346,7 @@ mock_auction_process_manager_->TakeBidderWorklet(kBidder2Url); ASSERT_TRUE(bidder2_worklet); bidder2_worklet->InvokeGenerateBidCallback( - 2, blink::kUnspecifiedAdCurrency, + 2, /*bid_currency=*/absl::nullopt, blink::AdDescriptor(GURL("https://ad2.com/"))); // Component seller scores the bid, but returns a bad @@ -8232,8 +8365,8 @@ /*reject_reason=*/ auction_worklet::mojom::RejectReason::kNotAvailable, test_case.params.Clone(), - /*scoring_signals_data_version=*/0, - /*has_scoring_signals_data_version=*/false, + /*bid_in_seller_currency=*/absl::nullopt, + /*scoring_signals_data_version=*/absl::nullopt, /*debug_loss_report_url=*/absl::nullopt, /*debug_win_report_url=*/absl::nullopt, /*pa_requests=*/{}, @@ -8280,7 +8413,7 @@ mock_auction_process_manager_->TakeBidderWorklet(kBidder2Url); ASSERT_TRUE(bidder2_worklet); bidder2_worklet->InvokeGenerateBidCallback( - 2, blink::kUnspecifiedAdCurrency, + 2, /*bid_currency=*/absl::nullopt, blink::AdDescriptor(GURL("https://ad2.com/"))); // Seller scores the bid, but returns a ComponentAuctionModifiedBidParams. @@ -8300,10 +8433,10 @@ auction_worklet::mojom::ComponentAuctionModifiedBidParams::New( /*ad=*/"null", /*bid=*/0, - /*bid_currency=*/"", + /*bid_currency=*/absl::nullopt, /*has_bid=*/false), - /*scoring_signals_data_version=*/0, - /*has_scoring_signals_data_version=*/false, + /*bid_in_seller_currency=*/absl::nullopt, + /*scoring_signals_data_version=*/absl::nullopt, /*debug_loss_report_url=*/absl::nullopt, /*debug_win_report_url=*/absl::nullopt, /*pa_requests=*/{}, /*errors=*/{}); @@ -8361,7 +8494,7 @@ ASSERT_TRUE(bidder_worklet); bidder_worklet->InvokeGenerateBidCallback( - /*bid=*/1, blink::kUnspecifiedAdCurrency, + /*bid=*/1, /*bid_currency=*/absl::nullopt, blink::AdDescriptor(kRenderUrl), /*mojo_kanon_bid=*/nullptr, test_case.bid_ad_component_urls, base::TimeDelta()); @@ -8378,8 +8511,8 @@ /*reject_reason=*/ auction_worklet::mojom::RejectReason::kNotAvailable, auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr(), - /*scoring_signals_data_version=*/0, - /*has_scoring_signals_data_version=*/false, + /*bid_in_seller_currency=*/absl::nullopt, + /*scoring_signals_data_version=*/absl::nullopt, /*debug_loss_report_url=*/absl::nullopt, /*debug_win_report_url=*/absl::nullopt, /*pa_requests=*/{}, /*errors=*/{}); @@ -8473,7 +8606,7 @@ ASSERT_TRUE(bidder_worklet); bidder_worklet->InvokeGenerateBidCallback( - /*bid=*/1, blink::kUnspecifiedAdCurrency, + /*bid=*/1, /*bid_currency=*/absl::nullopt, blink::AdDescriptor(kRenderUrl), /*mojo_kanon_bid=*/nullptr, ad_component_descriptors, base::TimeDelta()); @@ -8490,8 +8623,8 @@ /*reject_reason=*/ auction_worklet::mojom::RejectReason::kNotAvailable, auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr(), - /*scoring_signals_data_version=*/0, - /*has_scoring_signals_data_version=*/false, + /*bid_in_seller_currency=*/absl::nullopt, + /*scoring_signals_data_version=*/absl::nullopt, /*debug_loss_report_url=*/absl::nullopt, /*debug_win_report_url=*/absl::nullopt, /*pa_requests=*/{}, /*errors=*/{}); @@ -8560,7 +8693,7 @@ const struct TestCase { const char* expected_error_message; double bid; - const char* bid_currency; + absl::optional<blink::AdCurrency> bid_currency; blink::AdDescriptor ad_descriptor; absl::optional<std::vector<blink::AdDescriptor>> ad_component_descriptors; base::TimeDelta duration; @@ -8569,7 +8702,7 @@ { "Invalid bid value", -10, - blink::kUnspecifiedAdCurrency, + /*bid_currency=*/absl::nullopt, blink::AdDescriptor(GURL("https://ad1.com")), absl::nullopt, base::TimeDelta(), @@ -8577,7 +8710,7 @@ { "Invalid bid value", 0, - blink::kUnspecifiedAdCurrency, + /*bid_currency=*/absl::nullopt, blink::AdDescriptor(GURL("https://ad1.com")), absl::nullopt, base::TimeDelta(), @@ -8585,7 +8718,7 @@ { "Invalid bid value", std::numeric_limits<double>::infinity(), - blink::kUnspecifiedAdCurrency, + /*bid_currency=*/absl::nullopt, blink::AdDescriptor(GURL("https://ad1.com")), absl::nullopt, base::TimeDelta(), @@ -8593,7 +8726,7 @@ { "Invalid bid value", std::numeric_limits<double>::quiet_NaN(), - blink::kUnspecifiedAdCurrency, + /*bid_currency=*/absl::nullopt, blink::AdDescriptor(GURL("https://ad1.com")), absl::nullopt, base::TimeDelta(), @@ -8602,17 +8735,9 @@ // Invalid currencies. { "Invalid bid currency", - 1.0, - "usd", - blink::AdDescriptor(GURL("https://ad1.com")), - absl::nullopt, - base::TimeDelta(), - }, - { - "Invalid bid currency", // This is syntactically valid but test fixture says USD. 1.0, - "CAD", + blink::AdCurrency::From("CAD"), blink::AdDescriptor(GURL("https://ad1.com")), absl::nullopt, base::TimeDelta(), @@ -8622,7 +8747,7 @@ { "Bid render ad must have a valid URL and size (if specified)", 1, - blink::kUnspecifiedAdCurrency, + /*bid_currency=*/absl::nullopt, blink::AdDescriptor(GURL(":")), absl::nullopt, base::TimeDelta(), @@ -8632,7 +8757,7 @@ { "Bid render ad must have a valid URL and size (if specified)", 1, - blink::kUnspecifiedAdCurrency, + /*bid_currency=*/absl::nullopt, blink::AdDescriptor(GURL("data:,foo")), absl::nullopt, base::TimeDelta(), @@ -8640,7 +8765,7 @@ { "Bid render ad must have a valid URL and size (if specified)", 1, - blink::kUnspecifiedAdCurrency, + /*bid_currency=*/absl::nullopt, blink::AdDescriptor(GURL("http://ad1.com")), absl::nullopt, base::TimeDelta(), @@ -8650,7 +8775,7 @@ { "Bid render ad must have a valid URL and size (if specified)", 1, - blink::kUnspecifiedAdCurrency, + /*bid_currency=*/absl::nullopt, blink::AdDescriptor(GURL("https://ad2.com")), absl::nullopt, base::TimeDelta(), @@ -8660,7 +8785,7 @@ { "Bid render ad must have a valid URL and size (if specified)", 1, - blink::kUnspecifiedAdCurrency, + /*bid_currency=*/absl::nullopt, blink::AdDescriptor( GURL("https://ad1.com"), blink::AdSize(0, blink::AdSize::LengthUnit::kPixels, 100, @@ -8673,7 +8798,7 @@ { "Bid render ad must have a valid URL and size (if specified)", 1, - blink::kUnspecifiedAdCurrency, + /*bid_currency=*/absl::nullopt, blink::AdDescriptor( GURL("https://ad1.com"), blink::AdSize(100, blink::AdSize::LengthUnit::kInvalid, 100, @@ -8687,7 +8812,7 @@ { "Bid render ad must have a valid URL and size (if specified)", 1, - blink::kUnspecifiedAdCurrency, + /*bid_currency=*/absl::nullopt, blink::AdDescriptor( GURL("https://ad1.com"), blink::AdSize(100, blink::AdSize::LengthUnit::kPixels, 100, @@ -8700,7 +8825,7 @@ { "Bid ad component must have a valid URL and size (if specified)", 1, - blink::kUnspecifiedAdCurrency, + /*bid_currency=*/absl::nullopt, blink::AdDescriptor(GURL("https://ad1.com")), std::vector<blink::AdDescriptor>{blink::AdDescriptor(GURL(":"))}, base::TimeDelta(), @@ -8711,7 +8836,7 @@ { "Bid ad component must have a valid URL and size (if specified)", 1, - blink::kUnspecifiedAdCurrency, + /*bid_currency=*/absl::nullopt, blink::AdDescriptor(GURL("https://ad1.com")), std::vector<blink::AdDescriptor>{ blink::AdDescriptor(GURL("https://ad2.com-component1.com"))}, @@ -8720,7 +8845,7 @@ { "Bid ad component must have a valid URL and size (if specified)", 1, - blink::kUnspecifiedAdCurrency, + /*bid_currency=*/absl::nullopt, blink::AdDescriptor(GURL("https://ad1.com")), std::vector<blink::AdDescriptor>{ blink::AdDescriptor(GURL("https://ad1.com-component1.com")), @@ -8732,7 +8857,7 @@ { "Bid ad component must have a valid URL and size (if specified)", 1, - blink::kUnspecifiedAdCurrency, + /*bid_currency=*/absl::nullopt, blink::AdDescriptor(GURL("https://ad1.com")), std::vector<blink::AdDescriptor>{blink::AdDescriptor( GURL("https://ad1.com-component1.com"), @@ -8744,7 +8869,7 @@ { "Bid ad component must have a valid URL and size (if specified)", 1, - blink::kUnspecifiedAdCurrency, + /*bid_currency=*/absl::nullopt, blink::AdDescriptor(GURL("https://ad1.com")), std::vector<blink::AdDescriptor>{blink::AdDescriptor( GURL("https://ad1.com-component1.com"), @@ -8757,7 +8882,7 @@ { "Bid ad component must have a valid URL and size (if specified)", 1, - blink::kUnspecifiedAdCurrency, + /*bid_currency=*/absl::nullopt, blink::AdDescriptor(GURL("https://ad1.com")), std::vector<blink::AdDescriptor>{blink::AdDescriptor( GURL("https://ad1.com-component1.com"), @@ -8770,7 +8895,7 @@ { "Invalid bid duration", 1, - blink::kUnspecifiedAdCurrency, + /*bid_currency=*/absl::nullopt, blink::AdDescriptor(GURL("https://ad2.com")), absl::nullopt, base::Milliseconds(-1), @@ -8827,6 +8952,70 @@ } } +// Testcase for mojo errors in ScoreAd result's bid_in_seller_currency; note +// that problems with ComponentAuctionModifiedBidParams are covered in +// *BadBidParams* tests and those with debug URLs in +// ForDebuggingOnlyReportingSellerBadUrls. +TEST_F(AuctionRunnerTest, BadScoreAdBidInSellerCurrency) { + const struct TestCase { + const char* test_name; + absl::optional<blink::AdCurrency> seller_currency; + absl::optional<double> bid_in_seller_currency; + } kTestCases[] = { + { + "Should not specify when no seller_currency", + absl::nullopt, + 5, + }, + { + "Must be a valid bid", + blink::AdCurrency::From("CAD"), + -5, + }, + }; + for (const auto& test_case : kTestCases) { + SCOPED_TRACE(test_case.test_name); + seller_currency_ = test_case.seller_currency; + + StartStandardAuctionWithMockService(); + auto seller_worklet = mock_auction_process_manager_->TakeSellerWorklet(); + ASSERT_TRUE(seller_worklet); + auto bidder1_worklet = + mock_auction_process_manager_->TakeBidderWorklet(kBidder1Url); + ASSERT_TRUE(bidder1_worklet); + auto bidder2_worklet = + mock_auction_process_manager_->TakeBidderWorklet(kBidder2Url); + ASSERT_TRUE(bidder2_worklet); + + // Only Bidder1 bids, to keep things simple. + bidder1_worklet->InvokeGenerateBidCallback( + /*bid=*/5, /*bid_currency=*/absl::nullopt, + blink::AdDescriptor(GURL("https://ad1.com/"))); + bidder2_worklet->InvokeGenerateBidCallback(/*bid=*/absl::nullopt); + + auto score_ad_params = seller_worklet->WaitForScoreAd(); + EXPECT_EQ(kBidder1, score_ad_params.interest_group_owner); + EXPECT_EQ(5, score_ad_params.bid); + mojo::Remote<auction_worklet::mojom::ScoreAdClient>( + std::move(score_ad_params.score_ad_client)) + ->OnScoreAdComplete( + /*score=*/10, + /*reject_reason=*/ + auction_worklet::mojom::RejectReason::kNotAvailable, + auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr(), + /*bid_in_seller_currency=*/test_case.bid_in_seller_currency, + /*scoring_signals_data_version=*/absl::nullopt, + /*debug_loss_report_url=*/absl::nullopt, + /*debug_win_report_url=*/absl::nullopt, /*pa_requests=*/{}, + /*errors=*/{}); + auction_run_loop_->Run(); + EXPECT_EQ("Invalid bid_in_seller_currency", TakeBadMessage()); + + // No bidder won. + EXPECT_FALSE(result_.winning_group_id); + } +} + // Check that BidderWorklets that don't make a bid are destroyed immediately. TEST_F(AuctionRunnerTest, DestroyBidderWorkletWithoutBid) { StartStandardAuctionWithMockService(); @@ -8849,7 +9038,7 @@ // Bidder2 returns a bid, which is then scored. bidder2_worklet->InvokeGenerateBidCallback( - /*bid=*/7, blink::kUnspecifiedAdCurrency, + /*bid=*/7, /*bid_currency=*/absl::nullopt, blink::AdDescriptor(GURL("https://ad2.com/"))); auto score_ad_params = seller_worklet->WaitForScoreAd(); EXPECT_EQ(kBidder2, score_ad_params.interest_group_owner); @@ -8861,8 +9050,8 @@ /*reject_reason=*/ auction_worklet::mojom::RejectReason::kNotAvailable, auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr(), - /*scoring_signals_data_version=*/0, - /*has_scoring_signals_data_version=*/false, + /*bid_in_seller_currency=*/absl::nullopt, + /*scoring_signals_data_version=*/absl::nullopt, /*debug_loss_report_url=*/absl::nullopt, /*debug_win_report_url=*/absl::nullopt, /*pa_requests=*/{}, /*errors=*/{}); @@ -8922,7 +9111,7 @@ // Bidder1 returns a bid, which is then scored. bidder1_worklet->InvokeGenerateBidCallback( - /*bid=*/5, blink::kUnspecifiedAdCurrency, + /*bid=*/5, /*bid_currency=*/absl::nullopt, blink::AdDescriptor(GURL("https://ad1.com/"))); auto score_ad_params = seller_worklet->WaitForScoreAd(); EXPECT_EQ(kBidder1, score_ad_params.interest_group_owner); @@ -8934,15 +9123,15 @@ /*reject_reason=*/ auction_worklet::mojom::RejectReason::kNotAvailable, auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr(), - /*scoring_signals_data_version=*/0, - /*has_scoring_signals_data_version=*/false, + /*bid_in_seller_currency=*/absl::nullopt, + /*scoring_signals_data_version=*/absl::nullopt, /*debug_loss_report_url=*/absl::nullopt, /*debug_win_report_url=*/absl::nullopt, /*pa_requests=*/{}, /*errors=*/{}); // Bidder2 returns a bid, which is then scored. bidder2_worklet->InvokeGenerateBidCallback( - /*bid=*/5, blink::kUnspecifiedAdCurrency, + /*bid=*/5, /*bid_currency=*/absl::nullopt, blink::AdDescriptor(GURL("https://ad2.com/"))); score_ad_params = seller_worklet->WaitForScoreAd(); EXPECT_EQ(kBidder2, score_ad_params.interest_group_owner); @@ -8954,8 +9143,8 @@ /*reject_reason=*/ auction_worklet::mojom::RejectReason::kNotAvailable, auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr(), - /*scoring_signals_data_version=*/0, - /*has_scoring_signals_data_version=*/false, + /*bid_in_seller_currency=*/absl::nullopt, + /*scoring_signals_data_version=*/absl::nullopt, /*debug_loss_report_url=*/absl::nullopt, /*debug_win_report_url=*/absl::nullopt, /*pa_requests=*/{}, /*errors=*/{}); @@ -9070,7 +9259,7 @@ switch (event) { case Event::kBid1Generated: bidder1_worklet->InvokeGenerateBidCallback( - /*bid=*/9, blink::kUnspecifiedAdCurrency, + /*bid=*/9, /*bid_currency=*/absl::nullopt, blink::AdDescriptor(GURL("https://ad1.com/"))); score_ad_params1 = seller_worklet->WaitForScoreAd(); EXPECT_EQ(kBidder1, score_ad_params1.interest_group_owner); @@ -9078,7 +9267,7 @@ break; case Event::kBid2Generated: bidder2_worklet->InvokeGenerateBidCallback( - /*bid=*/10, blink::kUnspecifiedAdCurrency, + /*bid=*/10, /*bid_currency=*/absl::nullopt, blink::AdDescriptor(GURL("https://ad2.com/"))); score_ad_params2 = seller_worklet->WaitForScoreAd(); EXPECT_EQ(kBidder2, score_ad_params2.interest_group_owner); @@ -9093,8 +9282,8 @@ auction_worklet::mojom::RejectReason::kNotAvailable, auction_worklet::mojom:: ComponentAuctionModifiedBidParamsPtr(), - /*scoring_signals_data_version=*/0, - /*has_scoring_signals_data_version=*/false, + /*bid_in_seller_currency=*/absl::nullopt, + /*scoring_signals_data_version=*/absl::nullopt, /*debug_loss_report_url=*/absl::nullopt, /*debug_win_report_url=*/absl::nullopt, /*pa_requests=*/{}, /*errors=*/{}); @@ -9110,8 +9299,8 @@ auction_worklet::mojom::RejectReason::kNotAvailable, auction_worklet::mojom:: ComponentAuctionModifiedBidParamsPtr(), - /*scoring_signals_data_version=*/0, - /*has_scoring_signals_data_version=*/false, + /*bid_in_seller_currency=*/absl::nullopt, + /*scoring_signals_data_version=*/absl::nullopt, /*debug_loss_report_url=*/absl::nullopt, /*debug_win_report_url=*/absl::nullopt, /*pa_requests=*/{}, @@ -9377,7 +9566,7 @@ // Bid generation completes. bidder1_worklet->InvokeGenerateBidCallback( - /*bid=*/2, blink::kUnspecifiedAdCurrency, + /*bid=*/2, /*bid_currency=*/absl::nullopt, blink::AdDescriptor(GURL("https://ad1.com/"))); // More than the timeout time passes, but since the bid is being blocked on @@ -9396,8 +9585,8 @@ /*reject_reason=*/ auction_worklet::mojom::RejectReason::kNotAvailable, auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr(), - /*scoring_signals_data_version=*/0, - /*has_scoring_signals_data_version=*/false, + /*bid_in_seller_currency=*/absl::nullopt, + /*scoring_signals_data_version=*/absl::nullopt, /*debug_loss_report_url=*/absl::nullopt, /*debug_win_report_url=*/absl::nullopt, /*pa_requests=*/{}, /*errors=*/{}); @@ -9499,7 +9688,7 @@ // Bid generation completes. bidder1_worklet->InvokeGenerateBidCallback( - /*bid=*/2, blink::kUnspecifiedAdCurrency, + /*bid=*/2, /*bid_currency=*/absl::nullopt, blink::AdDescriptor(GURL("https://ad1.com/"))); // Score the ad. @@ -9513,8 +9702,8 @@ /*reject_reason=*/ auction_worklet::mojom::RejectReason::kNotAvailable, auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr(), - /*scoring_signals_data_version=*/0, - /*has_scoring_signals_data_version=*/false, + /*bid_in_seller_currency=*/absl::nullopt, + /*scoring_signals_data_version=*/absl::nullopt, /*debug_loss_report_url=*/absl::nullopt, /*debug_win_report_url=*/absl::nullopt, /*pa_requests=*/{}, /*errors=*/{}); @@ -11297,7 +11486,7 @@ // event type is not a supported one. This could only happen when the bidder // worklet is compromised. bidder1_worklet->InvokeGenerateBidCallback( - /*bid=*/5, blink::kUnspecifiedAdCurrency, + /*bid=*/5, /*bid_currency=*/absl::nullopt, blink::AdDescriptor(GURL("https://ad1.com")), /*mojo_kanon_bid=*/nullptr, /*ad_component_descriptors=*/absl::nullopt, @@ -11322,8 +11511,8 @@ /*reject_reason=*/ auction_worklet::mojom::RejectReason::kNotAvailable, auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr(), - /*scoring_signals_data_version=*/0, - /*has_scoring_signals_data_version=*/false, + /*bid_in_seller_currency=*/absl::nullopt, + /*scoring_signals_data_version=*/absl::nullopt, /*debug_loss_report_url=*/absl::nullopt, /*debug_win_report_url=*/absl::nullopt, std::move(score_ad_1_pa_requests), @@ -12892,19 +13081,39 @@ // Enable and test forDebuggingOnly.reportAdAuctionLoss() and // forDebuggingOnly.reportAdAuctionWin() APIs. +// IMPORTANT: These tests do a better job of covering second-highest-scoring +// bid ties and other such tricky cases than elsewhere[1], so if the +// forDebuggingOnly functionality is removed they should be adjusted to only +// look at `report_urls` rather than entirely removed. +// +// [1] And are therefore the only place for some currency testcases. class AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest - : public AuctionRunnerTest { + : public AuctionRunnerTest, + public ::testing::WithParamInterface<bool> { public: AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest() { feature_list_.InitAndEnableFeature( blink::features::kBiddingAndScoringDebugReportingAPI); + if (SellerCurrencyOn()) { + seller_currency_ = blink::AdCurrency::From("EUR"); + } } + bool SellerCurrencyOn() const { return GetParam(); } + + absl::optional<blink::AdCurrency> ModeCurrency() { + return SellerCurrencyOn() + ? absl::make_optional(blink::AdCurrency::From("EUR")) + : absl::nullopt; + } + + double ModeBid(double in) { return SellerCurrencyOn() ? in * 10.0 : in; } + protected: base::test::ScopedFeatureList feature_list_; }; -TEST_F(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest, +TEST_P(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest, ForDebuggingOnlyReporting) { auction_worklet::AddJavascriptResponse( &url_loader_factory_, kBidder1Url, @@ -12938,17 +13147,23 @@ // Sellers can get highest scoring other bid, but losing bidders can not. EXPECT_THAT(result_.debug_loss_report_urls, testing::UnorderedElementsAre( - DebugReportUrl(kBidder1DebugLossReportUrl, - PostAuctionSignals( - /*winning_bid=*/2, - /*made_winning_bid=*/false, - /*highest_scoring_other_bid=*/0, - /*made_highest_scoring_other_bid=*/false)), + DebugReportUrl( + kBidder1DebugLossReportUrl, + PostAuctionSignals( + /*winning_bid=*/ModeBid(2), + /*winning_bid_currency=*/ModeCurrency(), + /*made_winning_bid=*/false, + /*highest_scoring_other_bid=*/0, + /*highest_scoring_other_bid_currency=*/absl::nullopt, + /*made_highest_scoring_other_bid=*/false)), DebugReportUrl(kSellerDebugLossReportBaseUrl, PostAuctionSignals( - /*winning_bid=*/2, + /*winning_bid=*/ModeBid(2), + /*winning_bid_currency=*/ModeCurrency(), /*made_winning_bid=*/false, - /*highest_scoring_other_bid=*/1, + /*highest_scoring_other_bid=*/ModeBid(1), + /*highest_scoring_other_bid_currency=*/ + ModeCurrency(), /*made_highest_scoring_other_bid=*/true), /*bid=*/1))); @@ -12956,25 +13171,31 @@ // Winning bidders can get highest scoring other bid. EXPECT_THAT(result_.debug_win_report_urls, testing::UnorderedElementsAre( - DebugReportUrl(kBidder2DebugWinReportUrl, - PostAuctionSignals( - /*winning_bid=*/2, - /*made_winning_bid=*/true, - /*highest_scoring_other_bid=*/1, - /*made_highest_scoring_other_bid=*/false)), - DebugReportUrl(kSellerDebugWinReportBaseUrl, - PostAuctionSignals( - /*winning_bid=*/2, - /*made_winning_bid=*/true, - /*highest_scoring_other_bid=*/1, - /*made_highest_scoring_other_bid=*/false), - /*bid=*/2))); + DebugReportUrl( + kBidder2DebugWinReportUrl, + PostAuctionSignals( + /*winning_bid=*/ModeBid(2), + /*winning_bid_currency=*/ModeCurrency(), + /*made_winning_bid=*/true, + /*highest_scoring_other_bid=*/ModeBid(1), + /*highest_scoring_other_bid_currency=*/ModeCurrency(), + /*made_highest_scoring_other_bid=*/false)), + DebugReportUrl( + kSellerDebugWinReportBaseUrl, + PostAuctionSignals( + /*winning_bid=*/ModeBid(2), + /*winning_bid_currency=*/ModeCurrency(), + /*made_winning_bid=*/true, + /*highest_scoring_other_bid=*/ModeBid(1), + /*highest_scoring_other_bid_currency=*/ModeCurrency(), + /*made_highest_scoring_other_bid=*/false), + /*bid=*/2))); } // Post auction signals should only be reported through report URL's query // string. Placeholder ${} in a debugging report URL's other parts such as path // will be kept as it is without being replaced with actual signal. -TEST_F(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest, +TEST_P(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest, PostAuctionSignalsInQueryStringOnly) { auction_worklet::AddJavascriptResponse( &url_loader_factory_, kBidder1Url, @@ -13018,16 +13239,22 @@ DebugReportUrl("https://bidder1-debug-loss-reporting.com/" "winningBid=${winningBid}", PostAuctionSignals( - /*winning_bid=*/2, + /*winning_bid=*/ModeBid(2), + /*winning_bid_currency=*/ModeCurrency(), /*made_winning_bid=*/false, /*highest_scoring_other_bid=*/0, + /*highest_scoring_other_bid_currency=*/ + absl::nullopt, /*made_highest_scoring_other_bid=*/false)), DebugReportUrl("https://seller-debug-loss-reporting.com/" "winningBid=${winningBid}", PostAuctionSignals( - /*winning_bid=*/2, + /*winning_bid=*/ModeBid(2), + /*winning_bid_currency=*/ModeCurrency(), /*made_winning_bid=*/false, - /*highest_scoring_other_bid=*/1, + /*highest_scoring_other_bid=*/ModeBid(1), + /*highest_scoring_other_bid_currency=*/ + ModeCurrency(), /*made_highest_scoring_other_bid=*/true), /*bid=*/1))); @@ -13038,23 +13265,29 @@ DebugReportUrl("https://bidder2-debug-win-reporting.com/" "winningBid=${winningBid}", PostAuctionSignals( - /*winning_bid=*/2, + /*winning_bid=*/ModeBid(2), + /*winning_bid_currency=*/ModeCurrency(), /*made_winning_bid=*/true, - /*highest_scoring_other_bid=*/1, + /*highest_scoring_other_bid=*/ModeBid(1), + /*highest_scoring_other_bid_currency=*/ + ModeCurrency(), /*made_highest_scoring_other_bid=*/false)), DebugReportUrl( "https://seller-debug-win-reporting.com/winningBid=${winningBid}", PostAuctionSignals( - /*winning_bid=*/2, + /*winning_bid=*/ModeBid(2), + /*winning_bid_currency=*/ModeCurrency(), /*made_winning_bid=*/true, - /*highest_scoring_other_bid=*/1, + /*highest_scoring_other_bid=*/ModeBid(1), + /*highest_scoring_other_bid_currency=*/ + ModeCurrency(), /*made_highest_scoring_other_bid=*/false), /*bid=*/2))); } // When there are multiple bids getting the highest score, then highest scoring // other bid will be one of them which didn't win the bid. -TEST_F(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest, +TEST_P(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest, ForDebuggingOnlyReportingMultipleTopBids) { bool seen_ad2_win = false; bool seen_ad3_win = false; @@ -13098,31 +13331,43 @@ testing::UnorderedElementsAre( DebugReportUrl( kBidderDebugLossReportBaseUrl, - PostAuctionSignals(/*winning_bid=*/3, - /*made_winning_bid=*/true, - /*highest_scoring_other_bid=*/0, - /*made_highest_scoring_other_bid=*/false), + PostAuctionSignals( + /*winning_bid=*/ModeBid(3), + /*winning_bid_currency=*/ModeCurrency(), + /*made_winning_bid=*/true, + /*highest_scoring_other_bid=*/0, + /*highest_scoring_other_bid_currency=*/absl::nullopt, + /*made_highest_scoring_other_bid=*/false), /*bid=*/1), DebugReportUrl( kBidderDebugLossReportBaseUrl, - PostAuctionSignals(/*winning_bid=*/3, - /*made_winning_bid=*/false, - /*highest_scoring_other_bid=*/0, - /*made_highest_scoring_other_bid=*/false), + PostAuctionSignals( + /*winning_bid=*/ModeBid(3), + /*winning_bid_currency=*/ModeCurrency(), + /*made_winning_bid=*/false, + /*highest_scoring_other_bid=*/0, + /*highest_scoring_other_bid_currency=*/absl::nullopt, + /*made_highest_scoring_other_bid=*/false), /*bid=*/4), DebugReportUrl( kSellerDebugLossReportBaseUrl, - PostAuctionSignals(/*winning_bid=*/3, - /*made_winning_bid=*/true, - /*highest_scoring_other_bid=*/4, - /*made_highest_scoring_other_bid=*/false), + PostAuctionSignals( + /*winning_bid=*/ModeBid(3), + /*winning_bid_currency=*/ModeCurrency(), + /*made_winning_bid=*/true, + /*highest_scoring_other_bid=*/ModeBid(4), + /*highest_scoring_other_bid_currency=*/ModeCurrency(), + /*made_highest_scoring_other_bid=*/false), /*bid=*/1), DebugReportUrl( kSellerDebugLossReportBaseUrl, - PostAuctionSignals(/*winning_bid=*/3, - /*made_winning_bid=*/false, - /*highest_scoring_other_bid=*/4, - /*made_highest_scoring_other_bid=*/false), + PostAuctionSignals( + /*winning_bid=*/ModeBid(3), + /*winning_bid_currency=*/ModeCurrency(), + /*made_winning_bid=*/false, + /*highest_scoring_other_bid=*/ModeBid(4), + /*highest_scoring_other_bid_currency=*/ModeCurrency(), + /*made_highest_scoring_other_bid=*/false), /*bid=*/4))); EXPECT_THAT( @@ -13130,25 +13375,40 @@ testing::UnorderedElementsAre( DebugReportUrl( kBidderDebugWinReportBaseUrl, - PostAuctionSignals(/*winning_bid=*/3, - /*made_winning_bid=*/true, - /*highest_scoring_other_bid=*/4, - /*made_highest_scoring_other_bid=*/false), + PostAuctionSignals( + /*winning_bid=*/ModeBid(3), + /*winning_bid_currency=*/ModeCurrency(), + /*made_winning_bid=*/true, + /*highest_scoring_other_bid=*/ModeBid(4), + /*highest_scoring_other_bid_currency=*/ModeCurrency(), + /*made_highest_scoring_other_bid=*/false), /*bid=*/3), DebugReportUrl( kSellerDebugWinReportBaseUrl, - PostAuctionSignals(/*winning_bid=*/3, - /*made_winning_bid=*/true, - /*highest_scoring_other_bid=*/4, - /*made_highest_scoring_other_bid=*/false), + PostAuctionSignals( + /*winning_bid=*/ModeBid(3), + /*winning_bid_currency=*/ModeCurrency(), + /*made_winning_bid=*/true, + /*highest_scoring_other_bid=*/ModeBid(4), + /*highest_scoring_other_bid_currency=*/ModeCurrency(), + /*made_highest_scoring_other_bid=*/false), /*bid=*/3))); - EXPECT_THAT(result_.report_urls, - testing::UnorderedElementsAre( - GURL("https://reporting.example.com/" - "?highestScoringOtherBid=4&bid=3"), - ReportWinUrl(/*bid=*/3, /*highest_scoring_other_bid=*/4, - /*made_highest_scoring_other_bid=*/false))); + EXPECT_THAT( + result_.report_urls, + testing::UnorderedElementsAre( + SellerCurrencyOn() ? GURL("https://reporting.example.com/" + "?highestScoringOtherBid=40&" + "highestScoringOtherBidCurrency=EUR&" + "bidCurrency=EUR&bid=30") + : GURL("https://reporting.example.com/" + "?highestScoringOtherBid=4&" + "highestScoringOtherBidCurrency=???&" + "bidCurrency=???&bid=3"), + ReportWinUrl( + /*bid=*/3, /*bid_currency=*/blink::AdCurrency::From("USD"), + /*highest_scoring_other_bid=*/ModeBid(4), ModeCurrency(), + /*made_highest_scoring_other_bid=*/false))); } else if (result_.ad_descriptor->url == "https://ad3.com/") { seen_ad3_win = true; EXPECT_THAT( @@ -13156,31 +13416,43 @@ testing::UnorderedElementsAre( DebugReportUrl( kBidderDebugLossReportBaseUrl, - PostAuctionSignals(/*winning_bid=*/4, - /*made_winning_bid=*/false, - /*highest_scoring_other_bid=*/0, - /*made_highest_scoring_other_bid=*/false), + PostAuctionSignals( + /*winning_bid=*/ModeBid(4), + /*winning_bid_currency=*/ModeCurrency(), + /*made_winning_bid=*/false, + /*highest_scoring_other_bid=*/0, + /*highest_scoring_other_bid_currency=*/absl::nullopt, + /*made_highest_scoring_other_bid=*/false), /*bid=*/1), DebugReportUrl( kBidderDebugLossReportBaseUrl, - PostAuctionSignals(/*winning_bid=*/4, - /*made_winning_bid=*/false, - /*highest_scoring_other_bid=*/0, - /*made_highest_scoring_other_bid=*/false), + PostAuctionSignals( + /*winning_bid=*/ModeBid(4), + /*winning_bid_currency=*/ModeCurrency(), + /*made_winning_bid=*/false, + /*highest_scoring_other_bid=*/0, + /*highest_scoring_other_bid_currency=*/absl::nullopt, + /*made_highest_scoring_other_bid=*/false), /*bid=*/3), DebugReportUrl( kSellerDebugLossReportBaseUrl, - PostAuctionSignals(/*winning_bid=*/4, - /*made_winning_bid=*/false, - /*highest_scoring_other_bid=*/3, - /*made_highest_scoring_other_bid=*/false), + PostAuctionSignals( + /*winning_bid=*/ModeBid(4), + /*winning_bid_currency=*/ModeCurrency(), + /*made_winning_bid=*/false, + /*highest_scoring_other_bid=*/ModeBid(3), + /*highest_scoring_other_bid_currency=*/ModeCurrency(), + /*made_highest_scoring_other_bid=*/false), /*bid=*/1), DebugReportUrl( kSellerDebugLossReportBaseUrl, - PostAuctionSignals(/*winning_bid=*/4, - /*made_winning_bid=*/false, - /*highest_scoring_other_bid=*/3, - /*made_highest_scoring_other_bid=*/false), + PostAuctionSignals( + /*winning_bid=*/ModeBid(4), + /*winning_bid_currency=*/ModeCurrency(), + /*made_winning_bid=*/false, + /*highest_scoring_other_bid=*/ModeBid(3), + /*highest_scoring_other_bid_currency=*/ModeCurrency(), + /*made_highest_scoring_other_bid=*/false), /*bid=*/3))); EXPECT_THAT( @@ -13188,26 +13460,41 @@ testing::UnorderedElementsAre( DebugReportUrl( kBidderDebugWinReportBaseUrl, - PostAuctionSignals(/*winning_bid=*/4, - /*made_winning_bid=*/true, - /*highest_scoring_other_bid=*/3, - /*made_highest_scoring_other_bid=*/false), + PostAuctionSignals( + /*winning_bid=*/ModeBid(4), + /*winning_bid_currency=*/ModeCurrency(), + /*made_winning_bid=*/true, + /*highest_scoring_other_bid=*/ModeBid(3), + /*highest_scoring_other_bid_currency=*/ModeCurrency(), + /*made_highest_scoring_other_bid=*/false), /*bid=*/4), DebugReportUrl( kSellerDebugWinReportBaseUrl, - PostAuctionSignals(/*winning_bid=*/4, - /*made_winning_bid=*/true, - /*highest_scoring_other_bid=*/3, - /*made_highest_scoring_other_bid=*/false), + PostAuctionSignals( + /*winning_bid=*/ModeBid(4), + /*winning_bid_currency=*/ModeCurrency(), + /*made_winning_bid=*/true, + /*highest_scoring_other_bid=*/ModeBid(3), + /*highest_scoring_other_bid_currency=*/ModeCurrency(), + /*made_highest_scoring_other_bid=*/false), /*bid=*/4))); - EXPECT_THAT(result_.report_urls, - testing::UnorderedElementsAre( - GURL("https://reporting.example.com/" - "?highestScoringOtherBid=3&bid=4"), - ReportWinUrl(/*bid=*/4, /*highest_scoring_other_bid=*/3, - /*made_highest_scoring_other_bid=*/false))); + EXPECT_THAT( + result_.report_urls, + testing::UnorderedElementsAre( + SellerCurrencyOn() ? GURL("https://reporting.example.com/" + "?highestScoringOtherBid=30&" + "highestScoringOtherBidCurrency=EUR&" + "bidCurrency=EUR&bid=40") + : GURL("https://reporting.example.com/" + "?highestScoringOtherBid=3&" + "highestScoringOtherBidCurrency=???&" + "bidCurrency=???&bid=4"), + ReportWinUrl( + /*bid=*/4, /*bid_currency=*/blink::AdCurrency::From("USD"), + /*highest_scoring_other_bid=*/ModeBid(3), ModeCurrency(), + /*made_highest_scoring_other_bid=*/false))); } else { NOTREACHED(); } @@ -13217,7 +13504,7 @@ // This is used to test post auction signals when an auction where bidders are // from the same interest group owner. All winning bid and highest scoring other // bids come from the same interest group owner. -TEST_F(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest, +TEST_P(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest, ForDebuggingOnlyReportingSameOwnerBidders) { // Seen bid1 or bid2 being picked as highest scoring other bid. bool seen_bid1 = false; @@ -13258,14 +13545,30 @@ RunAuctionAndWait(kSellerUrl, std::move(bidders)); double highest_scoring_other_bid = 0.0; - if (base::Contains( - result_.report_urls, - "https://reporting.example.com/?highestScoringOtherBid=1&bid=3", - &GURL::spec)) { + if (base::Contains(result_.report_urls, + "https://reporting.example.com/" + "?highestScoringOtherBid=1&" + "highestScoringOtherBidCurrency=???&" + "bidCurrency=???&bid=3", + &GURL::spec) || + base::Contains(result_.report_urls, + "https://reporting.example.com/" + "?highestScoringOtherBid=10&" + "highestScoringOtherBidCurrency=EUR&" + "bidCurrency=EUR&bid=30", + &GURL::spec)) { highest_scoring_other_bid = 1; } else if (base::Contains(result_.report_urls, "https://reporting.example.com/" - "?highestScoringOtherBid=2&bid=3", + "?highestScoringOtherBid=2&" + "highestScoringOtherBidCurrency=???&" + "bidCurrency=???&bid=3", + &GURL::spec) || + base::Contains(result_.report_urls, + "https://reporting.example.com/" + "?highestScoringOtherBid=20&" + "highestScoringOtherBidCurrency=EUR&" + "bidCurrency=EUR&bid=30", &GURL::spec)) { highest_scoring_other_bid = 2; } @@ -13282,57 +13585,84 @@ testing::UnorderedElementsAre( DebugReportUrl( kBidderDebugLossReportBaseUrl, - PostAuctionSignals(/*winning_bid=*/3, - /*made_winning_bid=*/true, - /*highest_scoring_other_bid=*/0, - /*made_highest_scoring_other_bid=*/false), + PostAuctionSignals( + /*winning_bid=*/ModeBid(3), + /*winning_bid_currency=*/ModeCurrency(), + /*made_winning_bid=*/true, + /*highest_scoring_other_bid=*/0, + /*highest_scoring_other_bid_currency=*/absl::nullopt, + /*made_highest_scoring_other_bid=*/false), /*bid=*/1), DebugReportUrl( kBidderDebugLossReportBaseUrl, - PostAuctionSignals(/*winning_bid=*/3, - /*made_winning_bid=*/true, - /*highest_scoring_other_bid=*/0, - /*made_highest_scoring_other_bid=*/false), + PostAuctionSignals( + /*winning_bid=*/ModeBid(3), + /*winning_bid_currency=*/ModeCurrency(), + /*made_winning_bid=*/true, + /*highest_scoring_other_bid=*/0, + /*highest_scoring_other_bid_currency=*/absl::nullopt, + /*made_highest_scoring_other_bid=*/false), /*bid=*/2), - DebugReportUrl( - kSellerDebugLossReportBaseUrl, - PostAuctionSignals(/*winning_bid=*/3, - /*made_winning_bid=*/true, - /*highest_scoring_other_bid=*/1, - /*made_highest_scoring_other_bid=*/true), - /*bid=*/1), - DebugReportUrl( - kSellerDebugLossReportBaseUrl, - PostAuctionSignals(/*winning_bid=*/3, - /*made_winning_bid=*/true, - /*highest_scoring_other_bid=*/1, - /*made_highest_scoring_other_bid=*/true), - /*bid=*/2))); + DebugReportUrl(kSellerDebugLossReportBaseUrl, + PostAuctionSignals( + /*winning_bid=*/ModeBid(3), + /*winning_bid_currency=*/ModeCurrency(), + /*made_winning_bid=*/true, + /*highest_scoring_other_bid=*/ModeBid(1), + /*highest_scoring_other_bid_currency=*/ + ModeCurrency(), + /*made_highest_scoring_other_bid=*/true), + /*bid=*/1), + DebugReportUrl(kSellerDebugLossReportBaseUrl, + PostAuctionSignals( + /*winning_bid=*/ModeBid(3), + /*winning_bid_currency=*/ModeCurrency(), + /*made_winning_bid=*/true, + /*highest_scoring_other_bid=*/ModeBid(1), + /*highest_scoring_other_bid_currency=*/ + ModeCurrency(), + /*made_highest_scoring_other_bid=*/true), + /*bid=*/2))); EXPECT_THAT( result_.debug_win_report_urls, testing::UnorderedElementsAre( DebugReportUrl(kBidderDebugWinReportBaseUrl, PostAuctionSignals( - /*winning_bid=*/3, + /*winning_bid=*/ModeBid(3), + /*winning_bid_currency=*/ModeCurrency(), /*made_winning_bid=*/true, - /*highest_scoring_other_bid=*/1, + /*highest_scoring_other_bid=*/ModeBid(1), + /*highest_scoring_other_bid_currency=*/ + ModeCurrency(), /*made_highest_scoring_other_bid=*/true), /*bid=*/3), DebugReportUrl(kSellerDebugWinReportBaseUrl, PostAuctionSignals( - /*winning_bid=*/3, + /*winning_bid=*/ModeBid(3), + /*winning_bid_currency=*/ModeCurrency(), /*made_winning_bid=*/true, - /*highest_scoring_other_bid=*/1, + /*highest_scoring_other_bid=*/ModeBid(1), + /*highest_scoring_other_bid_currency=*/ + ModeCurrency(), /*made_highest_scoring_other_bid=*/true), /*bid=*/3))); - EXPECT_THAT(result_.report_urls, - testing::UnorderedElementsAre( - GURL("https://reporting.example.com/" - "?highestScoringOtherBid=1&bid=3"), - ReportWinUrl(/*bid=*/3, /*highest_scoring_other_bid=*/1, - /*made_highest_scoring_other_bid=*/true))); + EXPECT_THAT( + result_.report_urls, + testing::UnorderedElementsAre( + SellerCurrencyOn() ? GURL("https://reporting.example.com/" + "?highestScoringOtherBid=10&" + "highestScoringOtherBidCurrency=EUR&" + "bidCurrency=EUR&bid=30") + : GURL("https://reporting.example.com/" + "?highestScoringOtherBid=1&" + "highestScoringOtherBidCurrency=???&" + "bidCurrency=???&bid=3"), + ReportWinUrl( + /*bid=*/3, /*bid_currency=*/blink::AdCurrency::From("USD"), + /*highest_scoring_other_bid=*/ModeBid(1), ModeCurrency(), + /*made_highest_scoring_other_bid=*/true))); } else if (highest_scoring_other_bid == 2) { seen_bid2 = true; EXPECT_THAT( @@ -13340,57 +13670,84 @@ testing::UnorderedElementsAre( DebugReportUrl( kBidderDebugLossReportBaseUrl, - PostAuctionSignals(/*winning_bid=*/3, - /*made_winning_bid=*/true, - /*highest_scoring_other_bid=*/0, - /*made_highest_scoring_other_bid=*/false), + PostAuctionSignals( + /*winning_bid=*/ModeBid(3), + /*winning_bid_currency=*/ModeCurrency(), + /*made_winning_bid=*/true, + /*highest_scoring_other_bid=*/0, + /*highest_scoring_other_bid_currency=*/absl::nullopt, + /*made_highest_scoring_other_bid=*/false), /*bid=*/1), DebugReportUrl( kBidderDebugLossReportBaseUrl, - PostAuctionSignals(/*winning_bid=*/3, - /*made_winning_bid=*/true, - /*highest_scoring_other_bid=*/0, - /*made_highest_scoring_other_bid=*/false), + PostAuctionSignals( + /*winning_bid=*/ModeBid(3), + /*winning_bid_currency=*/ModeCurrency(), + /*made_winning_bid=*/true, + /*highest_scoring_other_bid=*/0, + /*highest_scoring_other_bid_currency=*/absl::nullopt, + /*made_highest_scoring_other_bid=*/false), /*bid=*/2), - DebugReportUrl( - kSellerDebugLossReportBaseUrl, - PostAuctionSignals(/*winning_bid=*/3, - /*made_winning_bid=*/true, - /*highest_scoring_other_bid=*/2, - /*made_highest_scoring_other_bid=*/true), - /*bid=*/1), - DebugReportUrl( - kSellerDebugLossReportBaseUrl, - PostAuctionSignals(/*winning_bid=*/3, - /*made_winning_bid=*/true, - /*highest_scoring_other_bid=*/2, - /*made_highest_scoring_other_bid=*/true), - /*bid=*/2))); + DebugReportUrl(kSellerDebugLossReportBaseUrl, + PostAuctionSignals( + /*winning_bid=*/ModeBid(3), + /*winning_bid_currency=*/ModeCurrency(), + /*made_winning_bid=*/true, + /*highest_scoring_other_bid=*/ModeBid(2), + /*highest_scoring_other_bid_currency=*/ + ModeCurrency(), + /*made_highest_scoring_other_bid=*/true), + /*bid=*/1), + DebugReportUrl(kSellerDebugLossReportBaseUrl, + PostAuctionSignals( + /*winning_bid=*/ModeBid(3), + /*winning_bid_currency=*/ModeCurrency(), + /*made_winning_bid=*/true, + /*highest_scoring_other_bid=*/ModeBid(2), + /*highest_scoring_other_bid_currency=*/ + ModeCurrency(), + /*made_highest_scoring_other_bid=*/true), + /*bid=*/2))); EXPECT_THAT( result_.debug_win_report_urls, testing::UnorderedElementsAre( DebugReportUrl(kBidderDebugWinReportBaseUrl, PostAuctionSignals( - /*winning_bid=*/3, + /*winning_bid=*/ModeBid(3), + /*winning_bid_currency=*/ModeCurrency(), /*made_winning_bid=*/true, - /*highest_scoring_other_bid=*/2, + /*highest_scoring_other_bid=*/ModeBid(2), + /*highest_scoring_other_bid_currency=*/ + ModeCurrency(), /*made_highest_scoring_other_bid=*/true), /*bid=*/3), DebugReportUrl(kSellerDebugWinReportBaseUrl, PostAuctionSignals( - /*winning_bid=*/3, + /*winning_bid=*/ModeBid(3), + /*winning_bid_currency=*/ModeCurrency(), /*made_winning_bid=*/true, - /*highest_scoring_other_bid=*/2, + /*highest_scoring_other_bid=*/ModeBid(2), + /*highest_scoring_other_bid_currency=*/ + ModeCurrency(), /*made_highest_scoring_other_bid=*/true), /*bid=*/3))); - EXPECT_THAT(result_.report_urls, - testing::UnorderedElementsAre( - GURL("https://reporting.example.com/" - "?highestScoringOtherBid=2&bid=3"), - ReportWinUrl(/*bid=*/3, /*highest_scoring_other_bid=*/2, - /*made_highest_scoring_other_bid=*/true))); + EXPECT_THAT( + result_.report_urls, + testing::UnorderedElementsAre( + SellerCurrencyOn() ? GURL("https://reporting.example.com/" + "?highestScoringOtherBid=20&" + "highestScoringOtherBidCurrency=EUR&" + "bidCurrency=EUR&bid=30") + : GURL("https://reporting.example.com/" + "?highestScoringOtherBid=2&" + "highestScoringOtherBidCurrency=???&" + "bidCurrency=???&bid=3"), + ReportWinUrl( + /*bid=*/3, /*bid_currency=*/blink::AdCurrency::From("USD"), + /*highest_scoring_other_bid=*/ModeBid(2), ModeCurrency(), + /*made_highest_scoring_other_bid=*/true))); } else { NOTREACHED(); } @@ -13399,7 +13756,7 @@ // Multiple bids from different interest group owners get the second highest // score, then `${madeHighestScoringOtherBid}` is always false. -TEST_F(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest, +TEST_P(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest, ForDebuggingOnlyReportingHighestScoringOtherBidFromDifferentOwners) { // Seen bid1 or bid2 being picked as highest scoring other bid. bool seen_bid1 = false; @@ -13436,14 +13793,30 @@ EXPECT_EQ(2u, result_.debug_win_report_urls.size()); EXPECT_EQ(2u, result_.report_urls.size()); double highest_scoring_other_bid = 0.0; - if (base::Contains( - result_.report_urls, - "https://reporting.example.com/?highestScoringOtherBid=1&bid=3", - &GURL::spec)) { + if (base::Contains(result_.report_urls, + "https://reporting.example.com/" + "?highestScoringOtherBid=1&" + "highestScoringOtherBidCurrency=???&" + "bidCurrency=???&bid=3", + &GURL::spec) || + base::Contains(result_.report_urls, + "https://reporting.example.com/" + "?highestScoringOtherBid=10&" + "highestScoringOtherBidCurrency=EUR&" + "bidCurrency=EUR&bid=30", + &GURL::spec)) { highest_scoring_other_bid = 1; } else if (base::Contains(result_.report_urls, "https://reporting.example.com/" - "?highestScoringOtherBid=2&bid=3", + "?highestScoringOtherBid=2&" + "highestScoringOtherBidCurrency=???&" + "bidCurrency=???&bid=3", + &GURL::spec) || + base::Contains(result_.report_urls, + "https://reporting.example.com/" + "?highestScoringOtherBid=20&" + "highestScoringOtherBidCurrency=EUR&" + "bidCurrency=EUR&bid=30", &GURL::spec)) { highest_scoring_other_bid = 2; } @@ -13455,115 +13828,169 @@ testing::UnorderedElementsAre( DebugReportUrl( kBidderDebugLossReportBaseUrl, - PostAuctionSignals(/*winning_bid=*/3, - /*made_winning_bid=*/true, - /*highest_scoring_other_bid=*/0, - /*made_highest_scoring_other_bid=*/false), + PostAuctionSignals( + /*winning_bid=*/ModeBid(3), + /*winning_bid_currency=*/ModeCurrency(), + /*made_winning_bid=*/true, + /*highest_scoring_other_bid=*/0, + /*highest_scoring_other_bid_currency=*/absl::nullopt, + /*made_highest_scoring_other_bid=*/false), /*bid=*/1), DebugReportUrl( kBidderDebugLossReportBaseUrl, - PostAuctionSignals(/*winning_bid=*/3, + PostAuctionSignals(/*winning_bid=*/ModeBid(3), + /*winning_bid_currency=*/ModeCurrency(), /*made_winning_bid=*/false, /*highest_scoring_other_bid=*/0, + /*highest_scoring_other_bid_currency=*/ + absl::nullopt, /*made_highest_scoring_other_bid=*/false), /*bid=*/2), + DebugReportUrl(kSellerDebugLossReportBaseUrl, + PostAuctionSignals( + /*winning_bid=*/ModeBid(3), + /*winning_bid_currency=*/ModeCurrency(), + /*made_winning_bid=*/true, + /*highest_scoring_other_bid=*/ModeBid(1), + /*highest_scoring_other_bid_currency=*/ + ModeCurrency(), + /*made_highest_scoring_other_bid=*/false), + /*bid=*/1), DebugReportUrl( kSellerDebugLossReportBaseUrl, - PostAuctionSignals(/*winning_bid=*/3, - /*made_winning_bid=*/true, - /*highest_scoring_other_bid=*/1, - /*made_highest_scoring_other_bid=*/false), - /*bid=*/1), - DebugReportUrl( - kSellerDebugLossReportBaseUrl, - PostAuctionSignals(/*winning_bid=*/3, + PostAuctionSignals(/*winning_bid=*/ModeBid(3), + /*winning_bid_currency=*/ModeCurrency(), /*made_winning_bid=*/false, - /*highest_scoring_other_bid=*/1, + /*highest_scoring_other_bid=*/ModeBid(1), + /*highest_scoring_other_bid_currency=*/ + ModeCurrency(), /*made_highest_scoring_other_bid=*/false), /*bid=*/2))); EXPECT_THAT( result_.debug_win_report_urls, testing::UnorderedElementsAre( - DebugReportUrl( - kBidderDebugWinReportBaseUrl, - PostAuctionSignals(/*winning_bid=*/3, - /*made_winning_bid=*/true, - /*highest_scoring_other_bid=*/1, - /*made_highest_scoring_other_bid=*/false), - /*bid=*/3), - DebugReportUrl( - kSellerDebugWinReportBaseUrl, - PostAuctionSignals(/*winning_bid=*/3, - /*made_winning_bid=*/true, - /*highest_scoring_other_bid=*/1, - /*made_highest_scoring_other_bid=*/false), - /*bid=*/3))); + DebugReportUrl(kBidderDebugWinReportBaseUrl, + PostAuctionSignals( + /*winning_bid=*/ModeBid(3), + /*winning_bid_currency=*/ModeCurrency(), + /*made_winning_bid=*/true, + /*highest_scoring_other_bid=*/ModeBid(1), + /*highest_scoring_other_bid_currency=*/ + ModeCurrency(), + /*made_highest_scoring_other_bid=*/false), + /*bid=*/3), + DebugReportUrl(kSellerDebugWinReportBaseUrl, + PostAuctionSignals( + /*winning_bid=*/ModeBid(3), + /*winning_bid_currency=*/ModeCurrency(), + /*made_winning_bid=*/true, + /*highest_scoring_other_bid=*/ModeBid(1), + /*highest_scoring_other_bid_currency=*/ + ModeCurrency(), + /*made_highest_scoring_other_bid=*/false), + /*bid=*/3))); - EXPECT_THAT(result_.report_urls, - testing::UnorderedElementsAre( - GURL("https://reporting.example.com/" - "?highestScoringOtherBid=1&bid=3"), - ReportWinUrl(/*bid=*/3, /*highest_scoring_other_bid=*/1, - /*made_highest_scoring_other_bid=*/false))); + EXPECT_THAT( + result_.report_urls, + testing::UnorderedElementsAre( + SellerCurrencyOn() ? GURL("https://reporting.example.com/" + "?highestScoringOtherBid=10&" + "highestScoringOtherBidCurrency=EUR&" + "bidCurrency=EUR&bid=30") + : GURL("https://reporting.example.com/" + "?highestScoringOtherBid=1&" + "highestScoringOtherBidCurrency=???&" + "bidCurrency=???&bid=3"), + ReportWinUrl( + /*bid=*/3, /*bid_currency=*/blink::AdCurrency::From("USD"), + /*highest_scoring_other_bid=*/ModeBid(1), ModeCurrency(), + /*made_highest_scoring_other_bid=*/false))); } else if (highest_scoring_other_bid == 2) { seen_bid2 = true; EXPECT_THAT( result_.debug_loss_report_urls, testing::UnorderedElementsAre( + DebugReportUrl(kBidderDebugLossReportBaseUrl, + PostAuctionSignals( + /*winning_bid=*/ModeBid(3), + /*winning_bid_currency=*/ModeCurrency(), + /*made_winning_bid=*/true, + /*highest_scoring_other_bid=*/0, + /*highest_scoring_other_bid_currency=*/ + absl::nullopt, + /*made_highest_scoring_other_bid=*/false), + /*bid=*/1), DebugReportUrl( kBidderDebugLossReportBaseUrl, - PostAuctionSignals(/*winning_bid=*/3, - /*made_winning_bid=*/true, - /*highest_scoring_other_bid=*/0, - /*made_highest_scoring_other_bid=*/false), - /*bid=*/1), - DebugReportUrl( - kBidderDebugLossReportBaseUrl, - PostAuctionSignals(/*winning_bid=*/3, + PostAuctionSignals(/*winning_bid=*/ModeBid(3), + /*winning_bid_currency=*/ModeCurrency(), /*made_winning_bid=*/false, /*highest_scoring_other_bid=*/0, + /*highest_scoring_other_bid_currency=*/ + absl::nullopt, /*made_highest_scoring_other_bid=*/false), /*bid=*/2), + DebugReportUrl(kSellerDebugLossReportBaseUrl, + PostAuctionSignals( + /*winning_bid=*/ModeBid(3), + /*winning_bid_currency=*/ModeCurrency(), + /*made_winning_bid=*/true, + /*highest_scoring_other_bid=*/ModeBid(2), + /*highest_scoring_other_bid_currency=*/ + ModeCurrency(), + /*made_highest_scoring_other_bid=*/false), + /*bid=*/1), DebugReportUrl( kSellerDebugLossReportBaseUrl, - PostAuctionSignals(/*winning_bid=*/3, - /*made_winning_bid=*/true, - /*highest_scoring_other_bid=*/2, - /*made_highest_scoring_other_bid=*/false), - /*bid=*/1), - DebugReportUrl( - kSellerDebugLossReportBaseUrl, - PostAuctionSignals(/*winning_bid=*/3, + PostAuctionSignals(/*winning_bid=*/ModeBid(3), + /*winning_bid_currency=*/ModeCurrency(), /*made_winning_bid=*/false, - /*highest_scoring_other_bid=*/2, + /*highest_scoring_other_bid=*/ModeBid(2), + /*highest_scoring_other_bid_currency=*/ + ModeCurrency(), /*made_highest_scoring_other_bid=*/false), /*bid=*/2))); EXPECT_THAT( result_.debug_win_report_urls, testing::UnorderedElementsAre( - DebugReportUrl( - kBidderDebugWinReportBaseUrl, - PostAuctionSignals(/*winning_bid=*/3, - /*made_winning_bid=*/true, - /*highest_scoring_other_bid=*/2, - /*made_highest_scoring_other_bid=*/false), - /*bid=*/3), - DebugReportUrl( - kSellerDebugWinReportBaseUrl, - PostAuctionSignals(/*winning_bid=*/3, - /*made_winning_bid=*/true, - /*highest_scoring_other_bid=*/2, - /*made_highest_scoring_other_bid=*/false), - /*bid=*/3))); + DebugReportUrl(kBidderDebugWinReportBaseUrl, + PostAuctionSignals( + /*winning_bid=*/ModeBid(3), + /*winning_bid_currency=*/ModeCurrency(), + /*made_winning_bid=*/true, + /*highest_scoring_other_bid=*/ModeBid(2), + /*highest_scoring_other_bid_currency=*/ + ModeCurrency(), + /*made_highest_scoring_other_bid=*/false), + /*bid=*/3), + DebugReportUrl(kSellerDebugWinReportBaseUrl, + PostAuctionSignals( + /*winning_bid=*/ModeBid(3), + /*winning_bid_currency=*/ModeCurrency(), + /*made_winning_bid=*/true, + /*highest_scoring_other_bid=*/ModeBid(2), + /*highest_scoring_other_bid_currency=*/ + ModeCurrency(), + /*made_highest_scoring_other_bid=*/false), + /*bid=*/3))); - EXPECT_THAT(result_.report_urls, - testing::UnorderedElementsAre( - GURL("https://reporting.example.com/" - "?highestScoringOtherBid=2&bid=3"), - ReportWinUrl(/*bid=*/3, /*highest_scoring_other_bid=*/2, - /*made_highest_scoring_other_bid=*/false))); + EXPECT_THAT( + result_.report_urls, + testing::UnorderedElementsAre( + SellerCurrencyOn() ? GURL("https://reporting.example.com/" + "?highestScoringOtherBid=20&" + "highestScoringOtherBidCurrency=EUR&" + "bidCurrency=EUR&bid=30") + : GURL("https://reporting.example.com/" + "?highestScoringOtherBid=2&" + "highestScoringOtherBidCurrency=???&" + "bidCurrency=???&bid=3"), + ReportWinUrl( + /*bid=*/3, /*bid_currency=*/blink::AdCurrency::From("USD"), + /*highest_scoring_other_bid=*/ModeBid(2), ModeCurrency(), + /*made_highest_scoring_other_bid=*/false))); } else { NOTREACHED(); } @@ -13572,7 +13999,7 @@ // Should send loss report to seller and bidders when auction fails due to // AllBidsRejected. -TEST_F(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest, +TEST_P(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest, ForDebuggingOnlyReportingAuctionFailAllBidsRejected) { auction_worklet::AddJavascriptResponse( &url_loader_factory_, kBidder1Url, @@ -13606,6 +14033,9 @@ EXPECT_FALSE(result_.ad_descriptor); EXPECT_EQ(4u, result_.debug_loss_report_urls.size()); + PostAuctionSignals empty_signals_with_currency; + empty_signals_with_currency.highest_scoring_other_bid_currency = + ModeCurrency(); EXPECT_THAT( result_.debug_loss_report_urls, testing::UnorderedElementsAre( @@ -13613,9 +14043,11 @@ /*bid=*/absl::nullopt, "invalid-bid"), DebugReportUrl(kBidder2DebugLossReportUrl, PostAuctionSignals(), /*bid=*/absl::nullopt, "bid-below-auction-floor"), - DebugReportUrl(kSellerDebugLossReportBaseUrl, PostAuctionSignals(), + DebugReportUrl(kSellerDebugLossReportBaseUrl, + empty_signals_with_currency, /*bid=*/1), - DebugReportUrl(kSellerDebugLossReportBaseUrl, PostAuctionSignals(), + DebugReportUrl(kSellerDebugLossReportBaseUrl, + empty_signals_with_currency, /*bid=*/2))); EXPECT_EQ(0u, result_.debug_win_report_urls.size()); @@ -13623,7 +14055,7 @@ // Test win/loss reporting in a component auction with two components with one // bidder each. -TEST_F(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest, +TEST_P(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest, ForDebuggingOnlyReportingComponentAuctionTwoComponents) { interest_group_buyers_.emplace(); @@ -13698,59 +14130,76 @@ EXPECT_THAT( result_.debug_loss_report_urls, testing::UnorderedElementsAre( - DebugReportUrl(kBidder1DebugLossReportUrl, - PostAuctionSignals( - /*winning_bid=*/1, - /*made_winning_bid=*/true, - /*highest_scoring_other_bid=*/0, - /*made_highest_scoring_other_bid=*/false)), + DebugReportUrl( + kBidder1DebugLossReportUrl, + PostAuctionSignals( + /*winning_bid=*/ModeBid(1), + /*winning_bid_currency=*/ModeCurrency(), + /*made_winning_bid=*/true, + /*highest_scoring_other_bid=*/0, + /*highest_scoring_other_bid_currency=*/absl::nullopt, + /*made_highest_scoring_other_bid=*/false)), ComponentSellerDebugReportUrl( "https://component1-loss-reporting.test/", /*signals=*/ - PostAuctionSignals(/*winning_bid=*/1, - /*made_winning_bid=*/true, - /*highest_scoring_other_bid=*/0, - /*made_highest_scoring_other_bid=*/false), + PostAuctionSignals( + /*winning_bid=*/ModeBid(1), + /*winning_bid_currency=*/ModeCurrency(), + /*made_winning_bid=*/true, + /*highest_scoring_other_bid=*/0, + /*highest_scoring_other_bid_currency=*/ModeCurrency(), + /*made_highest_scoring_other_bid=*/false), /*top_level_signals=*/ - PostAuctionSignals(/*winning_bid=*/2, + PostAuctionSignals(/*winning_bid=*/ModeBid(2), + /*winning_bid_currency=*/ModeCurrency(), /*made_winning_bid=*/false), /*bid=*/1), - DebugReportUrl("https://top-seller-loss-reporting.test/", - PostAuctionSignals(/*winning_bid=*/2, - /*made_winning_bid=*/false), - /*bid=*/1))); - - EXPECT_THAT( - result_.debug_win_report_urls, - testing::UnorderedElementsAre( DebugReportUrl( - kBidder2DebugWinReportUrl, - PostAuctionSignals(/*winning_bid=*/2, - /*made_winning_bid=*/true, - /*highest_scoring_other_bid=*/0, - /*made_highest_scoring_other_bid=*/false)), - ComponentSellerDebugReportUrl( - "https://component2-win-reporting.test/", - /*signals=*/ - PostAuctionSignals(/*winning_bid=*/2, - /*made_winning_bid=*/true, - /*highest_scoring_other_bid=*/0, - /*made_highest_scoring_other_bid=*/false), - /*top_level_signals=*/ - PostAuctionSignals(/*winning_bid=*/2, - /*made_winning_bid=*/true), - /*bid=*/2), - DebugReportUrl("https://top-seller-win-reporting.test/", - PostAuctionSignals(/*winning_bid=*/2, - /*made_winning_bid=*/true), - /*bid=*/2))); + "https://top-seller-loss-reporting.test/", + PostAuctionSignals(/*winning_bid=*/ModeBid(2), + /*winning_bid_currency=*/ModeCurrency(), + /*made_winning_bid=*/false), + /*bid=*/1))); + + EXPECT_THAT(result_.debug_win_report_urls, + testing::UnorderedElementsAre( + DebugReportUrl( + kBidder2DebugWinReportUrl, + PostAuctionSignals( + /*winning_bid=*/ModeBid(2), + /*winning_bid_currency=*/ModeCurrency(), + /*made_winning_bid=*/true, + /*highest_scoring_other_bid=*/0, + /*highest_scoring_other_bid_currency=*/ModeCurrency(), + /*made_highest_scoring_other_bid=*/false)), + ComponentSellerDebugReportUrl( + "https://component2-win-reporting.test/", + /*signals=*/ + PostAuctionSignals( + /*winning_bid=*/ModeBid(2), + /*winning_bid_currency=*/ModeCurrency(), + /*made_winning_bid=*/true, + /*highest_scoring_other_bid=*/0, + /*highest_scoring_other_bid_currency=*/ModeCurrency(), + /*made_highest_scoring_other_bid=*/false), + /*top_level_signals=*/ + PostAuctionSignals( + /*winning_bid=*/ModeBid(2), + /*winning_bid_currency=*/ModeCurrency(), + /*made_winning_bid=*/true), + /*bid=*/2), + DebugReportUrl("https://top-seller-win-reporting.test/", + PostAuctionSignals(/*winning_bid=*/ModeBid(2), + ModeCurrency(), + /*made_winning_bid=*/true), + /*bid=*/2))); } // Test debug loss reporting in an auction with no winner. Component bidder 1 is // rejected by component seller, and component bidder 2 is rejected by top-level // seller. Component bidders get component auction's reject reason but not the // top-level auction's. -TEST_F(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest, +TEST_P(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest, ForDebuggingOnlyReportingComponentAuctionNoWinner) { interest_group_buyers_.emplace(); @@ -13834,44 +14283,52 @@ // Component bidder 1 rejected by component auction gets its reject reason // "invalid-bid". Component bidders don't get the top-level auction's reject // reason. - EXPECT_THAT( - result_.debug_loss_report_urls, - testing::UnorderedElementsAre( - DebugReportUrl(kBidder1DebugLossReportUrl, - PostAuctionSignals( - /*winning_bid=*/0, - /*made_winning_bid=*/false, - /*highest_scoring_other_bid=*/0, - /*made_highest_scoring_other_bid=*/false), - /*bid=*/absl::nullopt, "invalid-bid"), - GURL("https://component1-loss-reporting.test/?&bid=1"), - DebugReportUrl(kBidder2DebugLossReportUrl, - PostAuctionSignals( - /*winning_bid=*/2, - /*made_winning_bid=*/true, - /*highest_scoring_other_bid=*/0, - /*made_highest_scoring_other_bid=*/false), - /*bid=*/absl::nullopt, "not-available"), - ComponentSellerDebugReportUrl( - "https://component2-loss-reporting.test/", - /*signals=*/ - PostAuctionSignals(/*winning_bid=*/2, - /*made_winning_bid=*/true, - /*highest_scoring_other_bid=*/0, - /*made_highest_scoring_other_bid=*/false), - /*top_level_signals=*/ - PostAuctionSignals(), - /*bid=*/2), - DebugReportUrl("https://top-seller-loss-reporting.test/", - PostAuctionSignals(), - /*bid=*/2))); + EXPECT_THAT(result_.debug_loss_report_urls, + testing::UnorderedElementsAre( + DebugReportUrl( + kBidder1DebugLossReportUrl, + PostAuctionSignals( + /*winning_bid=*/0, + /*winning_bid_currency=*/absl::nullopt, + /*made_winning_bid=*/false, + /*highest_scoring_other_bid=*/0, + /*highest_scoring_other_bid_currency=*/absl::nullopt, + /*made_highest_scoring_other_bid=*/false), + /*bid=*/absl::nullopt, "invalid-bid"), + GURL("https://component1-loss-reporting.test/?&bid=1"), + DebugReportUrl( + kBidder2DebugLossReportUrl, + PostAuctionSignals( + /*winning_bid=*/ModeBid(2), + /*winning_bid_currency=*/ModeCurrency(), + /*made_winning_bid=*/true, + /*highest_scoring_other_bid=*/0, + /*highest_scoring_other_bid_currency=*/absl::nullopt, + /*made_highest_scoring_other_bid=*/false), + /*bid=*/absl::nullopt, "not-available"), + ComponentSellerDebugReportUrl( + "https://component2-loss-reporting.test/", + /*signals=*/ + PostAuctionSignals( + /*winning_bid=*/ModeBid(2), + /*winning_bid_currency=*/ModeCurrency(), + /*made_winning_bid=*/true, + /*highest_scoring_other_bid=*/0, + /*highest_scoring_other_bid_currency=*/ModeCurrency(), + /*made_highest_scoring_other_bid=*/false), + /*top_level_signals=*/ + PostAuctionSignals(), + /*bid=*/2), + DebugReportUrl("https://top-seller-loss-reporting.test/", + PostAuctionSignals(), + /*bid=*/2))); EXPECT_THAT(result_.debug_win_report_urls, testing::UnorderedElementsAre()); } // Test win/loss reporting in a component auction with one component with two // bidders. -TEST_F(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest, +TEST_P(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest, ForDebuggingOnlyReportingComponentAuctionOneComponent) { interest_group_buyers_.emplace(); @@ -13936,50 +14393,66 @@ testing::UnorderedElementsAre( DebugReportUrl( kBidder2DebugLossReportUrl, - PostAuctionSignals(/*winning_bid=*/1, - /*made_winning_bid=*/false, - /*highest_scoring_other_bid=*/0, - /*made_highest_scoring_other_bid=*/false)), + PostAuctionSignals( + /*winning_bid=*/ModeBid(1), + /*winning_bid_currency=*/ModeCurrency(), + /*made_winning_bid=*/false, + /*highest_scoring_other_bid=*/0, + /*highest_scoring_other_bid_currency=*/absl::nullopt, + /*made_highest_scoring_other_bid=*/false)), ComponentSellerDebugReportUrl( "https://component-loss-reporting.test/", /*signals=*/ - PostAuctionSignals(/*winning_bid=*/1, + PostAuctionSignals(/*winning_bid=*/ModeBid(1), + /*winning_bid_currency=*/ModeCurrency(), /*made_winning_bid=*/false, - /*highest_scoring_other_bid=*/2, + /*highest_scoring_other_bid=*/ModeBid(2), + /*highest_scoring_other_bid_currency=*/ + ModeCurrency(), /*made_highest_scoring_other_bid=*/true), /*top_level_signals=*/ - PostAuctionSignals(/*winning_bid=*/1, + PostAuctionSignals(/*winning_bid=*/ModeBid(1), + /*winning_bid_currency=*/ModeCurrency(), /*made_winning_bid=*/false), /*bid=*/2))); - EXPECT_THAT( - result_.debug_win_report_urls, - testing::UnorderedElementsAre( - DebugReportUrl(kBidder1DebugWinReportUrl, - PostAuctionSignals( - /*winning_bid=*/1, - /*made_winning_bid=*/true, - /*highest_scoring_other_bid=*/2, - /*made_highest_scoring_other_bid=*/false)), - ComponentSellerDebugReportUrl( - "https://component-win-reporting.test/", - /*signals=*/ - PostAuctionSignals(/*winning_bid=*/1, - /*made_winning_bid=*/true, - /*highest_scoring_other_bid=*/2, - /*made_highest_scoring_other_bid=*/false), - /*top_level_signals=*/ - PostAuctionSignals(/*winning_bid=*/1, - /*made_winning_bid=*/true), - /*bid=*/1), - DebugReportUrl("https://top-seller-win-reporting.test/", - PostAuctionSignals(/*winning_bid=*/1, - /*made_winning_bid=*/true), - /*bid=*/1))); + EXPECT_THAT(result_.debug_win_report_urls, + testing::UnorderedElementsAre( + DebugReportUrl( + kBidder1DebugWinReportUrl, + PostAuctionSignals( + /*winning_bid=*/ModeBid(1), + /*winning_bid_currency=*/ModeCurrency(), + /*made_winning_bid=*/true, + /*highest_scoring_other_bid=*/ModeBid(2), + /*highest_scoring_other_bid_currency=*/ModeCurrency(), + /*made_highest_scoring_other_bid=*/false)), + ComponentSellerDebugReportUrl( + "https://component-win-reporting.test/", + /*signals=*/ + PostAuctionSignals( + /*winning_bid=*/ModeBid(1), + /*winning_bid_currency=*/ModeCurrency(), + /*made_winning_bid=*/true, + /*highest_scoring_other_bid=*/ModeBid(2), + /*highest_scoring_other_bid_currency=*/ModeCurrency(), + /*made_highest_scoring_other_bid=*/false), + /*top_level_signals=*/ + PostAuctionSignals( + /*winning_bid=*/ModeBid(1), + /*winning_bid_currency=*/ModeCurrency(), + /*made_winning_bid=*/true), + /*bid=*/1), + DebugReportUrl("https://top-seller-win-reporting.test/", + PostAuctionSignals( + /*winning_bid=*/ModeBid(1), + /*winning_bid_currency=*/ModeCurrency(), + /*made_winning_bid=*/true), + /*bid=*/1))); } // Loss report URLs should be dropped when the seller worklet fails to load. -TEST_F(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest, +TEST_P(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest, ForDebuggingOnlyReportingSellerWorkletFailToLoad) { auction_worklet::AddJavascriptResponse( &url_loader_factory_, kBidder1Url, @@ -14015,7 +14488,7 @@ EXPECT_EQ(0u, result_.debug_loss_report_urls.size()); } -TEST_F(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest, +TEST_P(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest, ForDebuggingOnlyReportingBidderBadUrls) { const struct TestCase { const char* expected_error_message; @@ -14056,7 +14529,7 @@ // Only Bidder1 bids, to keep things simple. bidder1_worklet->InvokeGenerateBidCallback( - /*bid=*/5, blink::kUnspecifiedAdCurrency, + /*bid=*/5, /*bid_currency=*/absl::nullopt, blink::AdDescriptor(GURL("https://ad1.com/")), /*mojo_kanon_bid=*/nullptr, /*ad_component_descriptors=*/absl::nullopt, base::TimeDelta(), @@ -14081,7 +14554,7 @@ } } -TEST_F(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest, +TEST_P(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest, ForDebuggingOnlyReportingSellerBadUrls) { const struct TestCase { const char* expected_error_message; @@ -14122,7 +14595,7 @@ // Only Bidder1 bids, to keep things simple. bidder1_worklet->InvokeGenerateBidCallback( - /*bid=*/5, blink::kUnspecifiedAdCurrency, + /*bid=*/5, /*bid_currency=*/absl::nullopt, blink::AdDescriptor(GURL("https://ad1.com/")), /*mojo_kanon_bid=*/nullptr, /*ad_component_descriptors=*/absl::nullopt, base::TimeDelta(), @@ -14141,8 +14614,8 @@ /*reject_reason=*/ auction_worklet::mojom::RejectReason::kNotAvailable, auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr(), - /*scoring_signals_data_version=*/0, - /*has_scoring_signals_data_version=*/false, + /*bid_in_seller_currency=*/absl::nullopt, + /*scoring_signals_data_version=*/absl::nullopt, test_case.seller_debug_loss_report_url, test_case.seller_debug_win_report_url, /*pa_requests=*/{}, /*errors=*/{}); @@ -14160,7 +14633,7 @@ } } -TEST_F(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest, +TEST_P(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest, ForDebuggingOnlyReportingGoodAndBadUrl) { StartStandardAuctionWithMockService(); auto seller_worklet = mock_auction_process_manager_->TakeSellerWorklet(); @@ -14174,7 +14647,7 @@ // Bidder1 returns a bid, which is then scored. bidder1_worklet->InvokeGenerateBidCallback( - /*bid=*/5, blink::kUnspecifiedAdCurrency, + /*bid=*/5, /*bid_currency=*/absl::nullopt, blink::AdDescriptor(GURL("https://ad1.com/")), /*mojo_kanon_bid=*/nullptr, /*ad_component_descriptors=*/absl::nullopt, base::TimeDelta(), @@ -14189,7 +14662,7 @@ // happen when the bidder worklet is compromised. It will be filtered out // and not be scored. bidder2_worklet->InvokeGenerateBidCallback( - /*bid=*/10, blink::kUnspecifiedAdCurrency, + /*bid=*/10, /*bid_currency=*/absl::nullopt, blink::AdDescriptor(GURL("https://ad2.com/")), /*mojo_kanon_bid=*/nullptr, /*ad_component_descriptors=*/absl::nullopt, base::TimeDelta(), @@ -14210,8 +14683,8 @@ /*reject_reason=*/ auction_worklet::mojom::RejectReason::kNotAvailable, auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr(), - /*scoring_signals_data_version=*/0, - /*has_scoring_signals_data_version=*/false, + /*bid_in_seller_currency=*/absl::nullopt, + /*scoring_signals_data_version=*/absl::nullopt, GURL("https://seller-debug-loss-reporting.com/1"), GURL("https://seller-debug-win-reporting.com/1"), /*pa_requests=*/{}, /*errors=*/{}); @@ -14251,7 +14724,7 @@ // scripts were run to completion. The main thing this test serves to do is to // validate the component auction state machinery works (Waits for all bids to // be generated/scored, doesn't abort them early, doesn't wait for extra bids). -TEST_F(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest, +TEST_P(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest, LargeComponentAuction) { const GURL kComponentSeller3Url{"https://component.seller3.test/baz.js"}; @@ -14390,7 +14863,7 @@ // Reject reason returned by scoreAd() for a rejected bid can be reported to the // bidder through its debug loss report URL. -TEST_F(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest, +TEST_P(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest, RejectedBidGetsRejectReason) { for (const std::string& reject_reason : {"not-available", "invalid-bid", "bid-below-auction-floor", @@ -14441,7 +14914,7 @@ // Reject reason returned by scoreAd() for a bid whose score is positive is // ignored and will not be reported to the bidder. -TEST_F(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest, +TEST_P(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest, RejectReasonIgnoredForPositiveBid) { auction_worklet::AddJavascriptResponse( &url_loader_factory_, kBidder1Url, @@ -14487,7 +14960,7 @@ // Only bidders' debug loss report URLs support macro ${rejectReason}. // Bidders' debug win report URLs and sellers' debug loss/win report URLs does // not. -TEST_F(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest, +TEST_P(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest, RejectReasonInBidderDebugLossReportOnly) { const char kBidder1Script[] = R"( function generateBid(interestGroup, auctionSignals, perBuyerSignals, @@ -14575,7 +15048,7 @@ // When scoreAd() does not return a reject reason, report it as "not-available" // in bidder's loss report URL as default. -TEST_F(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest, +TEST_P(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest, SellerNotReturningRejectReason) { interest_group_buyers_ = {{kBidder1}}; @@ -14620,6 +15093,11 @@ EXPECT_EQ(0u, result_.debug_win_report_urls.size()); } +INSTANTIATE_TEST_SUITE_P( + /* no label */, + AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest, + ::testing::Bool()); + // Disable private aggregation API. class AuctionRunnerPrivateAggregationAPIDisabledTest : public AuctionRunnerTest { @@ -14941,9 +15419,11 @@ ad2_k_anon_keys.end()); expected_seller_report_url = GURL("https://reporting.example.com/2"); - expected_report_urls.push_back( - ReportWinUrl(/*bid=*/2, /*highest_scoring_other_bid=*/1, - /*made_highest_scoring_other_bid=*/false)); + expected_report_urls.push_back(ReportWinUrl( + /*bid=*/2, /*bid_currency=*/absl::nullopt, + /*highest_scoring_other_bid=*/1, + /*highest_scoring_other_bid_currency=*/absl::nullopt, + /*made_highest_scoring_other_bid=*/false)); CheckMetrics(MetricsExpectations(AuctionResult::kSuccess) .SetNumInterestGroups(2) .SetNumOwnersAndDistinctOwners(2) @@ -15006,9 +15486,11 @@ expected_k_anon_keys_to_join.insert(ad2_k_anon_keys.begin(), ad2_k_anon_keys.end()); expected_seller_report_url = GURL("https://reporting.example.com/1"); - expected_report_urls.push_back( - ReportWinUrl(/*bid=*/1, /*highest_scoring_other_bid=*/0, - /*made_highest_scoring_other_bid=*/false)); + expected_report_urls.push_back(ReportWinUrl( + /*bid=*/1, /*bid_currency=*/absl::nullopt, + /*highest_scoring_other_bid=*/0, + /*highest_scoring_other_bid_currency=*/absl::nullopt, + /*made_highest_scoring_other_bid=*/false)); CheckMetrics( MetricsExpectations(AuctionResult::kSuccess) .SetNumInterestGroups(2) @@ -15074,9 +15556,11 @@ expected_k_anon_keys_to_join.insert(ad2_k_anon_keys.begin(), ad2_k_anon_keys.end()); expected_seller_report_url = GURL("https://reporting.example.com/2"); - expected_report_urls.push_back( - ReportWinUrl(/*bid=*/2, /*highest_scoring_other_bid=*/1, - /*made_highest_scoring_other_bid=*/false)); + expected_report_urls.push_back(ReportWinUrl( + /*bid=*/2, /*bid_currency=*/absl::nullopt, + /*highest_scoring_other_bid=*/1, + /*highest_scoring_other_bid_currency=*/absl::nullopt, + /*made_highest_scoring_other_bid=*/false)); CheckMetrics( MetricsExpectations(AuctionResult::kSuccess) .SetNumInterestGroups(2) @@ -15212,9 +15696,11 @@ expected_k_anon_keys_to_join.insert(ad2_k_anon_keys.begin(), ad2_k_anon_keys.end()); expected_seller_report_url = GURL("https://reporting.example.com/2"); - expected_report_urls.push_back( - ReportWinUrl(/*bid=*/2, /*highest_scoring_other_bid=*/1, - /*made_highest_scoring_other_bid=*/false)); + expected_report_urls.push_back(ReportWinUrl( + /*bid=*/2, /*bid_currency=*/absl::nullopt, + /*highest_scoring_other_bid=*/1, + /*highest_scoring_other_bid_currency=*/absl::nullopt, + /*made_highest_scoring_other_bid=*/false)); CheckMetrics(MetricsExpectations(AuctionResult::kSuccess) .SetNumInterestGroups(2) .SetNumOwnersAndDistinctOwners(2) @@ -15267,9 +15753,11 @@ expected_k_anon_keys_to_join.insert(ad2_k_anon_keys.begin(), ad2_k_anon_keys.end()); expected_seller_report_url = GURL("https://reporting.example.com/1"); - expected_report_urls.push_back( - ReportWinUrl(/*bid=*/1, /*highest_scoring_other_bid=*/0, - /*made_highest_scoring_other_bid=*/false)); + expected_report_urls.push_back(ReportWinUrl( + /*bid=*/1, /*bid_currency=*/absl::nullopt, + /*highest_scoring_other_bid=*/0, + /*highest_scoring_other_bid_currency=*/absl::nullopt, + /*made_highest_scoring_other_bid=*/false)); CheckMetrics( MetricsExpectations(AuctionResult::kSuccess) .SetNumInterestGroups(2) @@ -15328,9 +15816,11 @@ expected_k_anon_keys_to_join.insert(ad2_k_anon_keys.begin(), ad2_k_anon_keys.end()); expected_seller_report_url = GURL("https://reporting.example.com/2"); - expected_report_urls.push_back( - ReportWinUrl(/*bid=*/2, /*highest_scoring_other_bid=*/1, - /*made_highest_scoring_other_bid=*/false)); + expected_report_urls.push_back(ReportWinUrl( + /*bid=*/2, /*bid_currency=*/absl::nullopt, + /*highest_scoring_other_bid=*/1, + /*highest_scoring_other_bid_currency=*/absl::nullopt, + /*made_highest_scoring_other_bid=*/false)); CheckMetrics( MetricsExpectations(AuctionResult::kSuccess) .SetNumInterestGroups(2) @@ -15444,9 +15934,11 @@ // are set. histogram_tester_->ExpectUniqueSample( "Ads.InterestGroup.Auction.NonKAnonWinnerIsKAnon", false, 1); - expected_report_urls.push_back( - ReportWinUrl(/*bid=*/2, /*highest_scoring_other_bid=*/1, - /*made_highest_scoring_other_bid=*/false)); + expected_report_urls.push_back(ReportWinUrl( + /*bid=*/2, /*bid_currency=*/absl::nullopt, + /*highest_scoring_other_bid=*/1, + /*highest_scoring_other_bid_currency=*/absl::nullopt, + /*made_highest_scoring_other_bid=*/false)); CheckMetrics(MetricsExpectations(AuctionResult::kSuccess) .SetNumInterestGroups(2) .SetNumOwnersAndDistinctOwners(2) @@ -15475,9 +15967,11 @@ // The enforced winner is the same, but there is no runner-up. histogram_tester_->ExpectUniqueSample( "Ads.InterestGroup.Auction.NonKAnonWinnerIsKAnon", true, 1); - expected_report_urls.push_back( - ReportWinUrl(/*bid=*/2, /*highest_scoring_other_bid=*/0, - /*made_highest_scoring_other_bid=*/false)); + expected_report_urls.push_back(ReportWinUrl( + /*bid=*/2, /*bid_currency=*/absl::nullopt, + /*highest_scoring_other_bid=*/0, + /*highest_scoring_other_bid_currency=*/absl::nullopt, + /*made_highest_scoring_other_bid=*/false)); CheckMetrics(MetricsExpectations(AuctionResult::kSuccess) .SetNumInterestGroups(2) .SetNumOwnersAndDistinctOwners(2) @@ -15507,9 +16001,11 @@ // ad1.com also wins in the simulated mode. histogram_tester_->ExpectUniqueSample( "Ads.InterestGroup.Auction.NonKAnonWinnerIsKAnon", true, 1); - expected_report_urls.push_back( - ReportWinUrl(/*bid=*/2, /*highest_scoring_other_bid=*/1, - /*made_highest_scoring_other_bid=*/false)); + expected_report_urls.push_back(ReportWinUrl( + /*bid=*/2, /*bid_currency=*/absl::nullopt, + /*highest_scoring_other_bid=*/1, + /*highest_scoring_other_bid_currency=*/absl::nullopt, + /*made_highest_scoring_other_bid=*/false)); CheckMetrics(MetricsExpectations(AuctionResult::kSuccess) .SetNumInterestGroups(2) .SetNumOwnersAndDistinctOwners(2) @@ -15755,7 +16251,7 @@ blink::AdDescriptor(GURL("https://ad1.com")), auction_worklet::mojom::BidderWorkletKAnonEnforcedBid::NewBid( auction_worklet::mojom::BidderWorkletBid::New( - "ad", 5.0, blink::kUnspecifiedAdCurrency, + "ad", 5.0, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://ad2.com")), /*ad_component_urls=*/absl::nullopt, @@ -15768,7 +16264,7 @@ blink::AdDescriptor(GURL("https://ad2.com")), auction_worklet::mojom::BidderWorkletKAnonEnforcedBid::NewBid( auction_worklet::mojom::BidderWorkletBid::New( - "ad", 5.0, blink::kUnspecifiedAdCurrency, + "ad", 5.0, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://ad2.com")), /*ad_component_urls=*/absl::nullopt, @@ -15782,7 +16278,7 @@ blink::AdDescriptor(GURL("https://ad2.com")), auction_worklet::mojom::BidderWorkletKAnonEnforcedBid::NewBid( auction_worklet::mojom::BidderWorkletBid::New( - "ad", 5.0, blink::kUnspecifiedAdCurrency, + "ad", 5.0, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://ad2.com")), /*ad_component_urls=*/absl::nullopt, @@ -15825,7 +16321,7 @@ auto bidder1_worklet = mock_auction_process_manager_->TakeBidderWorklet(kBidder1Url); bidder1_worklet->InvokeGenerateBidCallback( - 1.0, blink::kUnspecifiedAdCurrency, test_case.ad_descriptor, + 1.0, /*bid_currency=*/absl::nullopt, test_case.ad_descriptor, test_case.mojo_bid.Clone()); // All of these tests only get one scoreAd, since k-anon bid is invalid. @@ -15839,8 +16335,8 @@ /*reject_reason=*/ auction_worklet::mojom::RejectReason::kNotAvailable, auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr(), - /*scoring_signals_data_version=*/0, - /*has_scoring_signals_data_version=*/false, + /*bid_in_seller_currency=*/absl::nullopt, + /*scoring_signals_data_version=*/absl::nullopt, /*debug_loss_report_url=*/absl::nullopt, /*debug_win_report_url=*/absl::nullopt, /*pa_requests=*/{}, /*errors=*/{});
diff --git a/content/browser/interest_group/auction_worklet_manager_unittest.cc b/content/browser/interest_group/auction_worklet_manager_unittest.cc index d4f2fd7..1fbd8a9 100644 --- a/content/browser/interest_group/auction_worklet_manager_unittest.cc +++ b/content/browser/interest_group/auction_worklet_manager_unittest.cc
@@ -206,7 +206,10 @@ const std::string& seller_signals_json, const GURL& browser_signal_render_url, double browser_signal_bid, + const absl::optional<blink::AdCurrency>& browser_signal_bid_currency, double browser_signal_highest_scoring_other_bid, + const absl::optional<blink::AdCurrency>& + browser_signal_highest_scoring_other_bid_currency, bool browser_signal_made_highest_scoring_other_bid, absl::optional<double> browser_signal_ad_cost, absl::optional<uint16_t> browser_signal_modeling_signals, @@ -321,24 +324,25 @@ // auction_worklet::mojom::SellerWorklet implementation: - void ScoreAd(const std::string& ad_metadata_json, - double bid, - const std::string& bid_currency, - const blink::AuctionConfig::NonSharedParams& - auction_ad_config_non_shared_params, - const absl::optional<GURL>& direct_from_seller_seller_signals, - const absl::optional<GURL>& direct_from_seller_auction_signals, - auction_worklet::mojom::ComponentAuctionOtherSellerPtr - browser_signals_other_seller, - const absl::optional<std::string>& component_expect_bid_currency, - const url::Origin& browser_signal_interest_group_owner, - const GURL& browser_signal_render_url, - const std::vector<GURL>& browser_signal_ad_components, - uint32_t browser_signal_bidding_duration_msecs, - const absl::optional<base::TimeDelta> seller_timeout, - uint64_t trace_id, - mojo::PendingRemote<auction_worklet::mojom::ScoreAdClient> - score_ad_client) override { + void ScoreAd( + const std::string& ad_metadata_json, + double bid, + const absl::optional<blink::AdCurrency>& bid_currency, + const blink::AuctionConfig::NonSharedParams& + auction_ad_config_non_shared_params, + const absl::optional<GURL>& direct_from_seller_seller_signals, + const absl::optional<GURL>& direct_from_seller_auction_signals, + auction_worklet::mojom::ComponentAuctionOtherSellerPtr + browser_signals_other_seller, + const absl::optional<blink::AdCurrency>& component_expect_bid_currency, + const url::Origin& browser_signal_interest_group_owner, + const GURL& browser_signal_render_url, + const std::vector<GURL>& browser_signal_ad_components, + uint32_t browser_signal_bidding_duration_msecs, + const absl::optional<base::TimeDelta> seller_timeout, + uint64_t trace_id, + mojo::PendingRemote<auction_worklet::mojom::ScoreAdClient> + score_ad_client) override { NOTREACHED(); } @@ -360,8 +364,11 @@ const url::Origin& browser_signal_interest_group_owner, const GURL& browser_signal_render_url, double browser_signal_bid, + const absl::optional<blink::AdCurrency>& browser_signal_bid_currency, double browser_signal_desirability, double browser_signal_highest_scoring_other_bid, + const absl::optional<blink::AdCurrency>& + browser_signal_highest_scoring_other_bid_currency, auction_worklet::mojom::ComponentAuctionReportResultParamsPtr browser_signals_component_auction_report_result_params, uint32_t browser_signal_data_version,
diff --git a/content/browser/interest_group/debuggable_auction_worklet.cc b/content/browser/interest_group/debuggable_auction_worklet.cc index 55219f33..6293c46 100644 --- a/content/browser/interest_group/debuggable_auction_worklet.cc +++ b/content/browser/interest_group/debuggable_auction_worklet.cc
@@ -4,8 +4,8 @@ #include "content/browser/interest_group/debuggable_auction_worklet.h" -#include "base/guid.h" #include "base/strings/strcat.h" +#include "base/uuid.h" #include "content/browser/devtools/devtools_instrumentation.h" #include "content/browser/interest_group/debuggable_auction_worklet_tracker.h" #include "content/services/auction_worklet/public/mojom/bidder_worklet.mojom.h" @@ -49,7 +49,7 @@ : owning_frame_(owning_frame), process_handle_(process_handle), url_(url), - unique_id_(base::GenerateGUID()), + unique_id_(base::Uuid::GenerateRandomV4().AsLowercaseString()), worklet_(bidder_worklet) { DebuggableAuctionWorkletTracker::GetInstance()->NotifyCreated( this, should_pause_on_start_); @@ -64,7 +64,7 @@ : owning_frame_(owning_frame), process_handle_(process_handle), url_(url), - unique_id_(base::GenerateGUID()), + unique_id_(base::Uuid::GenerateRandomV4().AsLowercaseString()), worklet_(seller_worklet) { DebuggableAuctionWorkletTracker::GetInstance()->NotifyCreated( this, should_pause_on_start_);
diff --git a/content/browser/interest_group/interest_group_auction.cc b/content/browser/interest_group/interest_group_auction.cc index 5de7a4b..fca1172 100644 --- a/content/browser/interest_group/interest_group_auction.cc +++ b/content/browser/interest_group/interest_group_auction.cc
@@ -339,8 +339,9 @@ buyer, auction_config.non_shared_params.buyer_cumulative_timeouts); } -std::string PerBuyerCurrency(const url::Origin& buyer, - const blink::AuctionConfig& auction_config) { +absl::optional<blink::AdCurrency> PerBuyerCurrency( + const url::Origin& buyer, + const blink::AuctionConfig& auction_config) { const blink::AuctionConfig::MaybePromiseBuyerCurrencies& buyer_currencies = auction_config.non_shared_params.buyer_currencies; DCHECK(!buyer_currencies.is_promise()); @@ -354,14 +355,91 @@ } const auto& all_buyers_currency = buyer_currencies.value().all_buyers_currency; - if (all_buyers_currency.has_value()) { - return all_buyers_currency.value(); - } - return blink::kUnspecifiedAdCurrency; + return all_buyers_currency; // Maybe nullopt. } } // namespace +InterestGroupAuction::PostAuctionSignals::PostAuctionSignals() = default; + +InterestGroupAuction::PostAuctionSignals::PostAuctionSignals( + double winning_bid, + absl::optional<blink::AdCurrency> winning_bid_currency, + bool made_winning_bid) + : winning_bid(winning_bid), + winning_bid_currency(std::move(winning_bid_currency)), + made_winning_bid(made_winning_bid) {} + +InterestGroupAuction::PostAuctionSignals::PostAuctionSignals( + double winning_bid, + absl::optional<blink::AdCurrency> winning_bid_currency, + bool made_winning_bid, + double highest_scoring_other_bid, + absl::optional<blink::AdCurrency> highest_scoring_other_bid_currency, + bool made_highest_scoring_other_bid) + : winning_bid(winning_bid), + winning_bid_currency(std::move(winning_bid_currency)), + made_winning_bid(made_winning_bid), + highest_scoring_other_bid(highest_scoring_other_bid), + highest_scoring_other_bid_currency( + std::move(highest_scoring_other_bid_currency)), + made_highest_scoring_other_bid(made_highest_scoring_other_bid) {} + +InterestGroupAuction::PostAuctionSignals::~PostAuctionSignals() = default; + +// static +void InterestGroupAuction::PostAuctionSignals::FillWinningBidInfo( + const url::Origin& owner, + absl::optional<url::Origin> winner_owner, + double winning_bid, + absl::optional<double> winning_bid_in_seller_currency, + const absl::optional<blink::AdCurrency>& seller_currency, + bool& out_made_winning_bid, + double& out_winning_bid, + absl::optional<blink::AdCurrency>& out_winning_bid_currency) { + out_made_winning_bid = false; + if (winner_owner.has_value()) { + out_made_winning_bid = owner == *winner_owner; + } + + if (seller_currency.has_value()) { + out_winning_bid = winning_bid_in_seller_currency.value_or(0.0); + out_winning_bid_currency = *seller_currency; + } else { + out_winning_bid = winning_bid; + out_winning_bid_currency = absl::nullopt; + } +} + +// static +void InterestGroupAuction::PostAuctionSignals:: + FillRelevantHighestScoringOtherBidInfo( + const url::Origin& owner, + absl::optional<url::Origin> highest_scoring_other_bid_owner, + double highest_scoring_other_bid, + absl::optional<double> highest_scoring_other_bid_in_seller_currency, + const absl::optional<blink::AdCurrency>& seller_currency, + bool& out_made_highest_scoring_other_bid, + double& out_highest_scoring_other_bid, + absl::optional<blink::AdCurrency>& + out_highest_scoring_other_bid_currency) { + out_made_highest_scoring_other_bid = false; + if (highest_scoring_other_bid_owner.has_value()) { + DCHECK_GT(highest_scoring_other_bid, 0); + out_made_highest_scoring_other_bid = + owner == highest_scoring_other_bid_owner.value(); + } + + if (seller_currency.has_value()) { + out_highest_scoring_other_bid = + highest_scoring_other_bid_in_seller_currency.value_or(0); + out_highest_scoring_other_bid_currency = *seller_currency; + } else { + out_highest_scoring_other_bid = highest_scoring_other_bid; + out_highest_scoring_other_bid_currency = absl::nullopt; + } +} + InterestGroupAuction::BidState::BidState() = default; InterestGroupAuction::BidState::~BidState() { @@ -420,7 +498,7 @@ BidRole bid_role, std::string ad_metadata, double bid, - std::string bid_currency, + absl::optional<blink::AdCurrency> bid_currency, absl::optional<double> ad_cost, blink::AdDescriptor ad_descriptor, std::vector<blink::AdDescriptor> ad_component_descriptors, @@ -466,11 +544,13 @@ double score, absl::optional<uint32_t> scoring_signals_data_version, std::unique_ptr<Bid> bid, + absl::optional<double> bid_in_seller_currency, auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr component_auction_modified_bid_params) : score(score), scoring_signals_data_version(scoring_signals_data_version), bid(std::move(bid)), + bid_in_seller_currency(std::move(bid_in_seller_currency)), component_auction_modified_bid_params( std::move(component_auction_modified_bid_params)) { DCHECK_GT(score, 0); @@ -741,11 +821,15 @@ } if (bid_state->bidder_debug_loss_report_url.has_value()) { // Losing and rejected bidders should not get highest_scoring_other_bid - // and made_highest_scoring_other_bid signals. + // and made_highest_scoring_other_bid signals. (And also the currency + // bit for those). debug_loss_report_urls.emplace_back(FillPostAuctionSignals( std::move(bid_state->bidder_debug_loss_report_url).value(), - PostAuctionSignals(signals.winning_bid, signals.made_winning_bid, - 0.0, false), + PostAuctionSignals( + signals.winning_bid, signals.winning_bid_currency, + signals.made_winning_bid, /*highest_scoring_other_bid=*/0.0, + /*highest_scoring_other_bid_currency=*/absl::nullopt, + /*made_highest_scoring_other_bid=*/false), /*top_level_signals=*/absl::nullopt, bid_state->reject_reason)); } // TODO(qingxinwu): Add reject reason to seller debug loss report as well. @@ -1477,8 +1561,7 @@ return nullptr; } - if (!blink::IsValidOrUnspecifiedAdCurrencyCode(mojo_bid->bid_currency) || - !blink::VerifyAdCurrencyCode( + if (!blink::VerifyAdCurrencyCode( PerBuyerCurrency(owner_, *auction_->config_), mojo_bid->bid_currency)) { generate_bid_client_receiver_set_.ReportBadMessage( @@ -1860,10 +1943,21 @@ // the bid was from the top-level auction, and the original top bid from the // component auction, otherwise, so will always be the bid returned by the // winning bidder's generateBid() method. - winning_bid_info.bid = winner->bid->auction->top_bid()->bid->bid; - winning_bid_info.ad_cost = winner->bid->auction->top_bid()->bid->ad_cost; - winning_bid_info.modeling_signals = - winner->bid->auction->top_bid()->bid->modeling_signals; + const InterestGroupAuction::Bid* bidder_bid = + winner->bid->auction->top_bid()->bid.get(); + winning_bid_info.bid = bidder_bid->bid; + winning_bid_info.bid_currency = bidder_bid->bid_currency; + // We redact the bid currency if it's not a concrete currency from the config, + // to avoid the bidder being able to leak ~14 bits of information if the + // bidder currency configuration is not restrictive. + absl::optional<blink::AdCurrency> config_currency = PerBuyerCurrency( + bidder_bid->interest_group->owner, *bidder_bid->auction->config_); + if (!config_currency.has_value()) { + winning_bid_info.bid_currency = absl::nullopt; + } + + winning_bid_info.ad_cost = bidder_bid->ad_cost; + winning_bid_info.modeling_signals = bidder_bid->modeling_signals; winning_bid_info.bid_duration = winner->bid->bid_duration; winning_bid_info.bidding_signals_data_version = winner->bid->bidding_signals_data_version; @@ -1886,9 +1980,14 @@ top_level_seller_winning_bid_info.subresource_url_builder = std::move(subresource_url_builder_); top_level_seller_winning_bid_info.bid = winner->bid->bid; + top_level_seller_winning_bid_info.bid_in_seller_currency = + winner->bid_in_seller_currency.value_or(0.0); top_level_seller_winning_bid_info.score = winner->score; top_level_seller_winning_bid_info.highest_scoring_other_bid = leader.highest_scoring_other_bid; + top_level_seller_winning_bid_info + .highest_scoring_other_bid_in_seller_currency = + leader.highest_scoring_other_bid_in_seller_currency; top_level_seller_winning_bid_info.highest_scoring_other_bid_owner = leader.highest_scoring_other_bid_owner; top_level_seller_winning_bid_info.scoring_signals_data_version = @@ -1917,9 +2016,14 @@ std::move(component_auction->subresource_url_builder_); const LeaderInfo& component_leader = component_auction->leader_info(); component_seller_winning_bid_info->bid = component_leader.top_bid->bid->bid; + component_seller_winning_bid_info->bid_in_seller_currency = + component_leader.top_bid->bid_in_seller_currency.value_or(0.0); component_seller_winning_bid_info->score = component_leader.top_bid->score; component_seller_winning_bid_info->highest_scoring_other_bid = component_leader.highest_scoring_other_bid; + component_seller_winning_bid_info + ->highest_scoring_other_bid_in_seller_currency = + component_leader.highest_scoring_other_bid_in_seller_currency; component_seller_winning_bid_info->highest_scoring_other_bid_owner = component_leader.highest_scoring_other_bid_owner; component_seller_winning_bid_info->scoring_signals_data_version = @@ -2073,6 +2177,9 @@ std::string query_string = url.query(); base::ReplaceSubstringsAfterOffset(&query_string, 0, "${winningBid}", base::NumberToString(signals.winning_bid)); + base::ReplaceSubstringsAfterOffset( + &query_string, 0, "${winningBidCurrency}", + blink::PrintableAdCurrency(signals.winning_bid_currency)); base::ReplaceSubstringsAfterOffset( &query_string, 0, "${madeWinningBid}", @@ -2081,6 +2188,9 @@ &query_string, 0, "${highestScoringOtherBid}", base::NumberToString(signals.highest_scoring_other_bid)); base::ReplaceSubstringsAfterOffset( + &query_string, 0, "${highestScoringOtherBidCurrency}", + blink::PrintableAdCurrency(signals.highest_scoring_other_bid_currency)); + base::ReplaceSubstringsAfterOffset( &query_string, 0, "${madeHighestScoringOtherBid}", signals.made_highest_scoring_other_bid ? "true" : "false"); @@ -2093,6 +2203,9 @@ &query_string, 0, "${topLevelWinningBid}", base::NumberToString(top_level_signals->winning_bid)); base::ReplaceSubstringsAfterOffset( + &query_string, 0, "${topLevelWinningBidCurrency}", + blink::PrintableAdCurrency(top_level_signals->winning_bid_currency)); + base::ReplaceSubstringsAfterOffset( &query_string, 0, "${topLevelMadeWinningBid}", top_level_signals->made_winning_bid ? "true" : "false"); } @@ -2226,8 +2339,7 @@ // `signals` includes post auction signals from current auction. PostAuctionSignals signals; - signals.winning_bid = leader.top_bid ? leader.top_bid->bid->bid : 0.0; - signals.highest_scoring_other_bid = leader.highest_scoring_other_bid; + // `top_level_signals` includes post auction signals from top-level auction. // Will only will be used in debug report URLs of top-level seller and // component sellers. @@ -2235,10 +2347,7 @@ // (not second-price auction) and it does not need highest_scoring_other_bid. absl::optional<PostAuctionSignals> top_level_signals; if (parent_) { - ScoredBid* parent_top_bid = parent_->top_bid(); - top_level_signals = PostAuctionSignals(); - top_level_signals->winning_bid = - parent_top_bid ? parent_top_bid->bid->bid : 0.0; + top_level_signals.emplace(); } if (!leader.top_bid) { @@ -2249,18 +2358,30 @@ for (const auto& buyer_helper : buyer_helpers_) { const url::Origin& owner = buyer_helper->owner(); if (leader.top_bid) { - signals.made_winning_bid = - owner == leader.top_bid->bid->interest_group->owner; + PostAuctionSignals::FillWinningBidInfo( + owner, leader.top_bid->bid->interest_group->owner, + leader.top_bid->bid->bid, leader.top_bid->bid_in_seller_currency, + config_->non_shared_params.seller_currency, signals.made_winning_bid, + signals.winning_bid, signals.winning_bid_currency); } - if (leader.highest_scoring_other_bid_owner.has_value()) { - DCHECK_GT(leader.highest_scoring_other_bid, 0); - signals.made_highest_scoring_other_bid = - owner == leader.highest_scoring_other_bid_owner.value(); - } + PostAuctionSignals::FillRelevantHighestScoringOtherBidInfo( + owner, leader.highest_scoring_other_bid_owner, + leader.highest_scoring_other_bid, + leader.highest_scoring_other_bid_in_seller_currency, + config_->non_shared_params.seller_currency, + signals.made_highest_scoring_other_bid, + signals.highest_scoring_other_bid, + signals.highest_scoring_other_bid_currency); + if (parent_ && parent_->top_bid()) { - top_level_signals->made_winning_bid = - owner == parent_->top_bid()->bid->interest_group->owner; + PostAuctionSignals::FillWinningBidInfo( + owner, parent_->top_bid()->bid->interest_group->owner, + parent_->top_bid()->bid->bid, + parent_->top_bid()->bid_in_seller_currency, + parent_->config_->non_shared_params.seller_currency, + top_level_signals->made_winning_bid, top_level_signals->winning_bid, + top_level_signals->winning_bid_currency); } buyer_helper->TakeDebugReportUrls(winner, signals, top_level_signals, @@ -2851,7 +2972,7 @@ modified_bid_params->has_bid ? modified_bid_params->bid : component_bid->bid, modified_bid_params->has_bid ? modified_bid_params->bid_currency - : std::string(), + : component_bid->bid_currency, component_bid->ad_cost, component_bid->ad_descriptor, component_bid->ad_component_descriptors, component_bid->modeling_signals, component_bid->bid_duration, component_bid->bidding_signals_data_version, @@ -2907,8 +3028,7 @@ config_->non_shared_params, GetDirectFromSellerSellerSignals(url_builder), GetDirectFromSellerAuctionSignals(url_builder), GetOtherSellerParam(*bid_raw), - parent_ ? absl::make_optional<std::string>( - PerBuyerCurrency(config_->seller, *parent_->config_)) + parent_ ? PerBuyerCurrency(config_->seller, *parent_->config_) : absl::nullopt, bid_raw->interest_group->owner, bid_raw->ad_descriptor.url, bid_raw->GetAdComponentUrls(), bid_raw->bid_duration.InMilliseconds(), @@ -2919,6 +3039,7 @@ double score, auction_worklet::mojom::ComponentAuctionModifiedBidParams* component_auction_modified_bid_params, + absl::optional<double> bid_in_seller_currency, const absl::optional<GURL>& debug_loss_report_url, const absl::optional<GURL>& debug_win_report_url) { // If `debug_loss_report_url` or `debug_win_report_url` is not a valid HTTPS @@ -2958,12 +3079,9 @@ return false; } - if (!blink::IsValidOrUnspecifiedAdCurrencyCode( + if (!blink::VerifyAdCurrencyCode( + config_->non_shared_params.seller_currency, component_auction_modified_bid_params->bid_currency) || - (config_->non_shared_params.seller_currency && - !blink::VerifyAdCurrencyCode( - config_->non_shared_params.seller_currency.value(), - component_auction_modified_bid_params->bid_currency)) || !blink::VerifyAdCurrencyCode( PerBuyerCurrency(config_->seller, *parent_->config_), component_auction_modified_bid_params->bid_currency)) { @@ -2973,6 +3091,12 @@ } } } + if (bid_in_seller_currency.has_value() && + (!IsValidBid(*bid_in_seller_currency) || + !config_->non_shared_params.seller_currency.has_value())) { + score_ad_receivers_.ReportBadMessage("Invalid bid_in_seller_currency"); + return false; + } return true; } @@ -2981,8 +3105,8 @@ auction_worklet::mojom::RejectReason reject_reason, auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr component_auction_modified_bid_params, - uint32_t data_version, - bool has_data_version, + absl::optional<double> bid_in_seller_currency, + absl::optional<uint32_t> scoring_signals_data_version, const absl::optional<GURL>& debug_loss_report_url, const absl::optional<GURL>& debug_win_report_url, PrivateAggregationRequests pa_requests, @@ -2991,7 +3115,8 @@ if (!ValidateScoreBidCompleteResult( score, component_auction_modified_bid_params.get(), - debug_loss_report_url, debug_win_report_url)) { + bid_in_seller_currency, debug_loss_report_url, + debug_win_report_url)) { OnBiddingAndScoringComplete(AuctionResult::kBadMojoMessage); return; } @@ -3066,13 +3191,15 @@ case Bid::BidRole::kUnenforcedKAnon: UpdateAuctionLeaders(std::move(bid), score, std::move(component_auction_modified_bid_params), - data_version, has_data_version, + bid_in_seller_currency, + scoring_signals_data_version, non_kanon_enforced_auction_leader_); break; case Bid::BidRole::kEnforcedKAnon: UpdateAuctionLeaders(std::move(bid), score, std::move(component_auction_modified_bid_params), - data_version, has_data_version, + bid_in_seller_currency, + scoring_signals_data_version, kanon_enforced_auction_leader_); break; case Bid::BidRole::kBothKAnonModes: { @@ -3084,11 +3211,13 @@ ComponentAuctionModifiedBidParamsPtr(); UpdateAuctionLeaders(std::move(bid), score, std::move(component_auction_modified_bid_params), - data_version, has_data_version, + bid_in_seller_currency, + scoring_signals_data_version, non_kanon_enforced_auction_leader_); - UpdateAuctionLeaders(std::move(bid_copy), score, - std::move(modified_bid_params_copy), data_version, - has_data_version, kanon_enforced_auction_leader_); + UpdateAuctionLeaders( + std::move(bid_copy), score, std::move(modified_bid_params_copy), + bid_in_seller_currency, scoring_signals_data_version, + kanon_enforced_auction_leader_); } } } @@ -3106,8 +3235,8 @@ double score, auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr component_auction_modified_bid_params, - uint32_t data_version, - bool has_data_version, + absl::optional<double> bid_in_seller_currency, + absl::optional<uint32_t> scoring_signals_data_version, LeaderInfo& leader_info) { bool is_top_bid = false; const url::Origin& owner = bid->interest_group->owner; @@ -3119,6 +3248,7 @@ if (leader_info.top_bid) { OnNewHighestScoringOtherBid( leader_info.top_bid->score, leader_info.top_bid->bid->bid, + leader_info.top_bid->bid_in_seller_currency, &leader_info.top_bid->bid->interest_group->owner, leader_info); } leader_info.num_top_bids = 1; @@ -3139,32 +3269,41 @@ // bid. double new_highest_scoring_other_bid = is_top_bid ? leader_info.top_bid->bid->bid : bid->bid; - OnNewHighestScoringOtherBid(score, new_highest_scoring_other_bid, - leader_info.at_most_one_top_bid_owner - ? &bid->interest_group->owner - : nullptr, - leader_info); + absl::optional<double> new_highest_scoring_other_bid_in_seller_currency = + is_top_bid ? leader_info.top_bid->bid_in_seller_currency + : bid_in_seller_currency; + OnNewHighestScoringOtherBid( + score, new_highest_scoring_other_bid, + new_highest_scoring_other_bid_in_seller_currency, + leader_info.at_most_one_top_bid_owner ? &bid->interest_group->owner + : nullptr, + leader_info); } else if (score >= leader_info.second_highest_score) { // Also use this bid (the most recent one) as highest scoring other bid if // there's a tie for second highest score. - OnNewHighestScoringOtherBid(score, bid->bid, &owner, leader_info); + OnNewHighestScoringOtherBid(score, bid->bid, bid_in_seller_currency, &owner, + leader_info); } if (is_top_bid) { leader_info.top_bid = std::make_unique<ScoredBid>( - score, has_data_version ? data_version : absl::optional<uint32_t>(), - std::move(bid), std::move(component_auction_modified_bid_params)); + score, std::move(scoring_signals_data_version), std::move(bid), + std::move(bid_in_seller_currency), + std::move(component_auction_modified_bid_params)); } } void InterestGroupAuction::OnNewHighestScoringOtherBid( double score, double bid_value, + absl::optional<double> bid_in_seller_currency, const url::Origin* owner, LeaderInfo& leader_info) { // Current (the most recent) bid becomes highest scoring other bid. if (score > leader_info.second_highest_score) { leader_info.highest_scoring_other_bid = bid_value; + leader_info.highest_scoring_other_bid_in_seller_currency = + bid_in_seller_currency; leader_info.num_second_highest_bids = 1; // Owner may be false if this is one of the bids tied for first place. if (!owner) { @@ -3185,6 +3324,8 @@ // stream with fixed storage problem. if (1 == base::RandInt(1, leader_info.num_second_highest_bids)) { leader_info.highest_scoring_other_bid = bid_value; + leader_info.highest_scoring_other_bid_in_seller_currency = + bid_in_seller_currency; } }
diff --git a/content/browser/interest_group/interest_group_auction.h b/content/browser/interest_group/interest_group_auction.h index 7b3dd03..499c71fc 100644 --- a/content/browser/interest_group/interest_group_auction.h +++ b/content/browser/interest_group/interest_group_auction.h
@@ -72,28 +72,59 @@ public: // Post auction signals (signals only available after auction completes such // as winning bid) for debug loss/win reporting. - struct PostAuctionSignals { - PostAuctionSignals() = default; + struct CONTENT_EXPORT PostAuctionSignals { + PostAuctionSignals(); // For now, top-level post auction signals do not have - // `highest_scoring_other_bid` or `made_highest_scoring_other_bid`. - PostAuctionSignals(double winning_bid, bool made_winning_bid) - : winning_bid(winning_bid), made_winning_bid(made_winning_bid) {} - + // `highest_scoring_other_bid` information. PostAuctionSignals(double winning_bid, - bool made_winning_bid, - double highest_scoring_other_bid, - bool made_highest_scoring_other_bid) - : winning_bid(winning_bid), - made_winning_bid(made_winning_bid), - highest_scoring_other_bid(highest_scoring_other_bid), - made_highest_scoring_other_bid(made_highest_scoring_other_bid) {} + absl::optional<blink::AdCurrency> winning_bid_currency, + bool made_winning_bid); - ~PostAuctionSignals() = default; + PostAuctionSignals( + double winning_bid, + absl::optional<blink::AdCurrency> winning_bid_currency, + bool made_winning_bid, + double highest_scoring_other_bid, + absl::optional<blink::AdCurrency> highest_scoring_other_bid_currency, + bool made_highest_scoring_other_bid); + + ~PostAuctionSignals(); + + PostAuctionSignals(PostAuctionSignals&) = delete; + PostAuctionSignals& operator=(PostAuctionSignals&) = delete; + + // Computes appropriate information to provide for winningBid information, + // dependent on whether bidder-currency or seller-currency is expected. + static void FillWinningBidInfo( + const url::Origin& owner, + absl::optional<url::Origin> winner_owner, + double winning_bid, + absl::optional<double> winning_bid_in_seller_currency, + const absl::optional<blink::AdCurrency>& seller_currency, + bool& out_made_winning_bid, + double& out_winning_bid, + absl::optional<blink::AdCurrency>& out_winning_bid_currency); + + // Computes appropriate information to provide for highestScoringOtherBid + // information, dependent on whether bidder-currency or seller-currency is + // expected. + static void FillRelevantHighestScoringOtherBidInfo( + const url::Origin& owner, + absl::optional<url::Origin> highest_scoring_other_bid_owner, + double highest_scoring_other_bid, + absl::optional<double> highest_scoring_other_bid_in_seller_currency, + const absl::optional<blink::AdCurrency>& seller_currency, + bool& out_made_highest_scoring_other_bid, + double& out_highest_scoring_other_bid, + absl::optional<blink::AdCurrency>& + out_highest_scoring_other_bid_currency); double winning_bid = 0.0; + absl::optional<blink::AdCurrency> winning_bid_currency; bool made_winning_bid = false; double highest_scoring_other_bid = 0.0; + absl::optional<blink::AdCurrency> highest_scoring_other_bid_currency; bool made_highest_scoring_other_bid = false; }; @@ -263,7 +294,7 @@ Bid(BidRole bid_role, std::string ad_metadata, double bid, - std::string bid_currency, + absl::optional<blink::AdCurrency> bid_currency, absl::optional<double> ad_cost, blink::AdDescriptor ad_descriptor, std::vector<blink::AdDescriptor> ad_component_descriptors, @@ -297,7 +328,7 @@ // auction_worklet::mojom::BidderWorkletBid. const std::string ad_metadata; const double bid; - const std::string bid_currency; + const absl::optional<blink::AdCurrency> bid_currency; const absl::optional<double> ad_cost; const blink::AdDescriptor ad_descriptor; const std::vector<blink::AdDescriptor> ad_component_descriptors; @@ -333,6 +364,7 @@ ScoredBid(double score, absl::optional<uint32_t> scoring_signals_data_version, std::unique_ptr<Bid> bid, + absl::optional<double> bid_in_seller_currency, auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr component_auction_modified_bid_params); ~ScoredBid(); @@ -346,6 +378,9 @@ // The bid that came from the bidder or component Auction. const std::unique_ptr<Bid> bid; + // Bidder's bid currency-converted by the seller to seller's own currency. + const absl::optional<double> bid_in_seller_currency; + // Modifications that should be applied to `bid` before the parent // auction uses it. Only present for bids in component Auctions. When // the top-level auction creates a ScoredBid represending the result from @@ -622,6 +657,7 @@ // there's a tie for the second highest score, one of the second highest // scoring bids is randomly chosen. double highest_scoring_other_bid = 0.0; + absl::optional<double> highest_scoring_other_bid_in_seller_currency; double second_highest_score = 0.0; // Whether all bids of the highest score are from the same interest group // owner. @@ -728,6 +764,7 @@ double score, auction_worklet::mojom::ComponentAuctionModifiedBidParams* component_auction_modified_bid_params, + absl::optional<double> bid_in_seller_currency, const absl::optional<GURL>& debug_loss_report_url, const absl::optional<GURL>& debug_win_report_url); @@ -737,8 +774,8 @@ auction_worklet::mojom::RejectReason reject_reason, auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr component_auction_modified_bid_params, - uint32_t scoring_signals_data_version, - bool has_scoring_signals_data_version, + absl::optional<double> bid_in_seller_currency, + absl::optional<uint32_t> scoring_signals_data_version, const absl::optional<GURL>& debug_loss_report_url, const absl::optional<GURL>& debug_win_report_url, PrivateAggregationRequests pa_requests, @@ -751,17 +788,19 @@ double score, auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr component_auction_modified_bid_params, - uint32_t data_version, - bool has_data_version, + absl::optional<double> bid_in_seller_currency, + absl::optional<uint32_t> scoring_signals_data_version, LeaderInfo& leader_info); // Invoked when the bid becomes the new highest scoring other bid, to handle // calculation of post auction signals. `owner` is nullptr in the event the // bid is tied with the top bid, and they have different origins. - void OnNewHighestScoringOtherBid(double score, - double bid_value, - const url::Origin* owner, - LeaderInfo& leader_info); + void OnNewHighestScoringOtherBid( + double score, + double bid_value, + absl::optional<double> bid_in_seller_currency, + const url::Origin* owner, + LeaderInfo& leader_info); absl::optional<base::TimeDelta> SellerTimeout();
diff --git a/content/browser/interest_group/interest_group_auction_reporter.cc b/content/browser/interest_group/interest_group_auction_reporter.cc index 903a6bb..0454748 100644 --- a/content/browser/interest_group/interest_group_auction_reporter.cc +++ b/content/browser/interest_group/interest_group_auction_reporter.cc
@@ -49,6 +49,7 @@ #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/public/common/features.h" #include "third_party/blink/public/common/fenced_frame/redacted_fenced_frame_config.h" +#include "third_party/blink/public/common/interest_group/ad_auction_currencies.h" #include "third_party/blink/public/common/interest_group/interest_group.h" #include "third_party/blink/public/mojom/fenced_frame/fenced_frame.mojom-shared.h" #include "third_party/blink/public/mojom/interest_group/interest_group_types.mojom.h" @@ -327,6 +328,18 @@ seller_info->component_auction_modified_bid_params->has_bid); } + double bid = seller_info->bid; + absl::optional<blink::AdCurrency> bid_currency; + double highest_scoring_other_bid = seller_info->highest_scoring_other_bid; + if (seller_info->auction_config->non_shared_params.seller_currency + .has_value()) { + bid = seller_info->bid_in_seller_currency; + highest_scoring_other_bid = + seller_info->highest_scoring_other_bid_in_seller_currency.value_or(0.0); + bid_currency = + *seller_info->auction_config->non_shared_params.seller_currency; + } + seller_worklet_handle_->AuthorizeSubresourceUrls( *seller_info->subresource_url_builder); seller_worklet_handle_->GetSellerWorklet()->ReportResult( @@ -338,12 +351,13 @@ std::move(other_seller), winning_bid_info_.storage_interest_group->interest_group.owner, winning_bid_info_.render_url, - RoundStochasticallyToKBits(seller_info->bid, - kFledgeBidReportingBits.Get()), + RoundStochasticallyToKBits(bid, kFledgeBidReportingBits.Get()), + bid_currency, RoundStochasticallyToKBits(seller_info->score, kFledgeScoreReportingBits.Get()), - RoundStochasticallyToKBits(seller_info->highest_scoring_other_bid, + RoundStochasticallyToKBits(highest_scoring_other_bid, kFledgeBidReportingBits.Get()), + bid_currency, std::move(browser_signals_component_auction_report_result_params), seller_info->scoring_signals_data_version.value_or(0), seller_info->scoring_signals_data_version.has_value(), @@ -542,6 +556,20 @@ noised_and_masked_modeling_signals = NoiseAndMaskModelingSignals(*winning_bid_info_.modeling_signals); } + + double highest_scoring_other_bid; + absl::optional<blink::AdCurrency> highest_scoring_other_bid_currency; + bool made_highest_scoring_other_bid; + InterestGroupAuction::PostAuctionSignals:: + FillRelevantHighestScoringOtherBidInfo( + winning_bid_info_.storage_interest_group->interest_group.owner, + seller_info.highest_scoring_other_bid_owner, + seller_info.highest_scoring_other_bid, + seller_info.highest_scoring_other_bid_in_seller_currency, + auction_config->non_shared_params.seller_currency, + made_highest_scoring_other_bid, highest_scoring_other_bid, + highest_scoring_other_bid_currency); + bidder_worklet_handle_->GetBidderWorklet()->ReportWin( group_name, auction_config->non_shared_params.auction_signals.value(), per_buyer_signals, @@ -553,12 +581,11 @@ signals_for_winner, winning_bid_info_.render_url, RoundStochasticallyToKBits(winning_bid_info_.bid, kFledgeBidReportingBits.Get()), + winning_bid_info_.bid_currency, /*browser_signal_highest_scoring_other_bid=*/ - RoundStochasticallyToKBits(seller_info.highest_scoring_other_bid, + RoundStochasticallyToKBits(highest_scoring_other_bid, kFledgeBidReportingBits.Get()), - seller_info.highest_scoring_other_bid_owner.has_value() && - winning_bid_info_.storage_interest_group->interest_group.owner == - seller_info.highest_scoring_other_bid_owner.value(), + highest_scoring_other_bid_currency, made_highest_scoring_other_bid, rounded_ad_cost, noised_and_masked_modeling_signals, NoiseAndBucketJoinCount( // Browser signals may be null in tests.
diff --git a/content/browser/interest_group/interest_group_auction_reporter.h b/content/browser/interest_group/interest_group_auction_reporter.h index 6ce44077..25848f1 100644 --- a/content/browser/interest_group/interest_group_auction_reporter.h +++ b/content/browser/interest_group/interest_group_auction_reporter.h
@@ -118,11 +118,13 @@ // returned by the component seller. Otherwise, it's the bid from the // bidder. double bid; + double bid_in_seller_currency; // Score this seller assigned the bid. double score; double highest_scoring_other_bid; + absl::optional<double> highest_scoring_other_bid_in_seller_currency; absl::optional<url::Origin> highest_scoring_other_bid_owner; absl::optional<uint32_t> scoring_signals_data_version; @@ -149,6 +151,9 @@ // Bid returned by the bidder. double bid; + // Currency the bid is in. + absl::optional<blink::AdCurrency> bid_currency; + // Ad cost returned by the bidder. absl::optional<double> ad_cost;
diff --git a/content/browser/interest_group/interest_group_auction_reporter_unittest.cc b/content/browser/interest_group/interest_group_auction_reporter_unittest.cc index 71955ed..47c7eb19d 100644 --- a/content/browser/interest_group/interest_group_auction_reporter_unittest.cc +++ b/content/browser/interest_group/interest_group_auction_reporter_unittest.cc
@@ -67,6 +67,7 @@ // they don't have default initializers, so have to set them to placate memory // tools. out.bid = 1; + out.bid_in_seller_currency = 10; out.score = 1; out.highest_scoring_other_bid = 0; out.trace_id = 0; @@ -203,7 +204,8 @@ CreateSellerWinningBidInfo(&component_auction_config); component_seller_winning_bid_info_->component_auction_modified_bid_params = auction_worklet::mojom::ComponentAuctionModifiedBidParams::New( - /*ad=*/"null", /*bid=*/0, /*bid_currency=*/"", /*has_bid=*/false); + /*ad=*/"null", /*bid=*/0, /*bid_currency=*/absl::nullopt, + /*has_bid=*/false); } void SetUpReporterAndStart() {
diff --git a/content/browser/interest_group/interest_group_browsertest.cc b/content/browser/interest_group/interest_group_browsertest.cc index 431368c..b5b4b2c 100644 --- a/content/browser/interest_group/interest_group_browsertest.cc +++ b/content/browser/interest_group/interest_group_browsertest.cc
@@ -8844,7 +8844,8 @@ perBuyerTimeouts: {$4: 110, $5: 120, '*': 150}, perBuyerCumulativeTimeouts: {$4: 13000, $5: 14000, '*': 16000}, perBuyerPrioritySignals: {$4: {foo: 1}, '*': {BaR: -2}}, - perBuyerCurrencies: {$4: 'USD', $5: 'CAD', '*': 'EUR'} + perBuyerCurrencies: {$4: 'USD', $5: 'CAD', '*': 'EUR'}, + sellerCurrency: 'EUR' }); })())", seller_origin, seller_script_url, @@ -8975,7 +8976,8 @@ perBuyerTimeouts: {$4: 110, $5: 120, '*': 150}, perBuyerCumulativeTimeouts: {$4: 13000, $5: 14000, '*': 16000}, perBuyerPrioritySignals: {$4: {foo: 1}, '*': {BaR: -2}}, - perBuyerCurrencies: {$4: 'USD', $5: 'CAD', '*': 'EUR'} + perBuyerCurrencies: {$4: 'USD', $5: 'CAD', '*': 'EUR'}, + sellerCurrency: 'EUR' }); })())", seller_origin, seller_script_url,
diff --git a/content/browser/interest_group/mock_auction_process_manager.cc b/content/browser/interest_group/mock_auction_process_manager.cc index 731b658..1129e4d 100644 --- a/content/browser/interest_group/mock_auction_process_manager.cc +++ b/content/browser/interest_group/mock_auction_process_manager.cc
@@ -122,7 +122,10 @@ const std::string& seller_signals_json, const GURL& browser_signal_render_url, double browser_signal_bid, + const absl::optional<blink::AdCurrency>& browser_signal_bid_currency, double browser_signal_highest_scoring_other_bid, + const absl::optional<blink::AdCurrency>& + browser_signal_highest_scoring_other_bid_currency, bool browser_signal_made_highest_scoring_other_bid, absl::optional<double> browser_signal_ad_cost, absl::optional<uint16_t> browser_signal_modeling_signals, @@ -153,7 +156,7 @@ const absl::optional<std::string>& auction_signals_json, const absl::optional<std::string>& per_buyer_signals_json, const absl::optional<base::TimeDelta> per_buyer_timeout, - const std::string& per_buyer_currency, + const absl::optional<blink::AdCurrency>& per_buyer_currency, const absl::optional<GURL>& direct_from_seller_per_buyer_signals, const absl::optional<GURL>& direct_from_seller_auction_signals) { // per_buyer_timeout passed to GenerateBid() should not be empty, because @@ -191,7 +194,7 @@ void MockBidderWorklet::InvokeGenerateBidCallback( absl::optional<double> bid, - const std::string& bid_currency, + const absl::optional<blink::AdCurrency>& bid_currency, const blink::AdDescriptor& ad_descriptor, auction_worklet::mojom::BidderWorkletKAnonEnforcedBidPtr mojo_kanon_bid, absl::optional<std::vector<blink::AdDescriptor>> ad_component_descriptors, @@ -312,14 +315,14 @@ void MockSellerWorklet::ScoreAd( const std::string& ad_metadata_json, double bid, - const std::string& bid_currency, + const absl::optional<blink::AdCurrency>& bid_currency, const blink::AuctionConfig::NonSharedParams& auction_ad_config_non_shared_params, const absl::optional<GURL>& direct_from_seller_seller_signals, const absl::optional<GURL>& direct_from_seller_auction_signals, auction_worklet::mojom::ComponentAuctionOtherSellerPtr browser_signals_other_seller, - const absl::optional<std::string>& component_expect_bid_currency, + const absl::optional<blink::AdCurrency>& component_expect_bid_currency, const url::Origin& browser_signal_interest_group_owner, const GURL& browser_signal_render_url, const std::vector<GURL>& browser_signal_ad_components, @@ -366,8 +369,11 @@ const url::Origin& browser_signal_interest_group_owner, const GURL& browser_signal_render_url, double browser_signal_bid, + const absl::optional<blink::AdCurrency>& browser_signal_bid_currency, double browser_signal_desirability, double browser_signal_highest_scoring_other_bid, + const absl::optional<blink::AdCurrency>& + browser_signal_highest_scoring_other_bid_currency, auction_worklet::mojom::ComponentAuctionReportResultParamsPtr browser_signals_component_auction_report_result_params, uint32_t browser_signal_data_version,
diff --git a/content/browser/interest_group/mock_auction_process_manager.h b/content/browser/interest_group/mock_auction_process_manager.h index 6b7752f..54e27f4 100644 --- a/content/browser/interest_group/mock_auction_process_manager.h +++ b/content/browser/interest_group/mock_auction_process_manager.h
@@ -84,7 +84,10 @@ const std::string& seller_signals_json, const GURL& browser_signal_render_url, double browser_signal_bid, + const absl::optional<blink::AdCurrency>& browser_signal_bid_currency, double browser_signal_highest_scoring_other_bid, + const absl::optional<blink::AdCurrency>& + browser_signal_highest_scoring_other_bid_currency, bool browser_signal_made_highest_scoring_other_bid, absl::optional<double> browser_signal_ad_cost, absl::optional<uint16_t> browser_signal_modeling_signals, @@ -105,7 +108,7 @@ const absl::optional<std::string>& auction_signals_json, const absl::optional<std::string>& per_buyer_signals_json, const absl::optional<base::TimeDelta> per_buyer_timeout, - const std::string& per_buyer_currency, + const absl::optional<blink::AdCurrency>& per_buyer_currency, const absl::optional<GURL>& direct_from_seller_per_buyer_signals, const absl::optional<GURL>& direct_from_seller_auction_signals) override; @@ -122,7 +125,7 @@ // should be offered. Waits for the GenerateBid() call first, if needed. void InvokeGenerateBidCallback( absl::optional<double> bid, - const std::string& bid_currency = blink::kUnspecifiedAdCurrency, + const absl::optional<blink::AdCurrency>& bid_currency = absl::nullopt, const blink::AdDescriptor& ad_descriptor = blink::AdDescriptor(), auction_worklet::mojom::BidderWorkletKAnonEnforcedBidPtr mojo_kanon_bid = auction_worklet::mojom::BidderWorkletKAnonEnforcedBidPtr(), @@ -213,24 +216,25 @@ ~MockSellerWorklet() override; // auction_worklet::mojom::SellerWorklet implementation: - void ScoreAd(const std::string& ad_metadata_json, - double bid, - const std::string& bid_currency, - const blink::AuctionConfig::NonSharedParams& - auction_ad_config_non_shared_params, - const absl::optional<GURL>& direct_from_seller_seller_signals, - const absl::optional<GURL>& direct_from_seller_auction_signals, - auction_worklet::mojom::ComponentAuctionOtherSellerPtr - browser_signals_other_seller, - const absl::optional<std::string>& component_expect_bid_currency, - const url::Origin& browser_signal_interest_group_owner, - const GURL& browser_signal_render_url, - const std::vector<GURL>& browser_signal_ad_components, - uint32_t browser_signal_bidding_duration_msecs, - const absl::optional<base::TimeDelta> seller_timeout, - uint64_t trace_id, - mojo::PendingRemote<auction_worklet::mojom::ScoreAdClient> - score_ad_client) override; + void ScoreAd( + const std::string& ad_metadata_json, + double bid, + const absl::optional<blink::AdCurrency>& bid_currency, + const blink::AuctionConfig::NonSharedParams& + auction_ad_config_non_shared_params, + const absl::optional<GURL>& direct_from_seller_seller_signals, + const absl::optional<GURL>& direct_from_seller_auction_signals, + auction_worklet::mojom::ComponentAuctionOtherSellerPtr + browser_signals_other_seller, + const absl::optional<blink::AdCurrency>& component_expect_bid_currency, + const url::Origin& browser_signal_interest_group_owner, + const GURL& browser_signal_render_url, + const std::vector<GURL>& browser_signal_ad_components, + uint32_t browser_signal_bidding_duration_msecs, + const absl::optional<base::TimeDelta> seller_timeout, + uint64_t trace_id, + mojo::PendingRemote<auction_worklet::mojom::ScoreAdClient> + score_ad_client) override; void SendPendingSignalsRequests() override; void ReportResult( const blink::AuctionConfig::NonSharedParams& @@ -242,8 +246,11 @@ const url::Origin& browser_signal_interest_group_owner, const GURL& browser_signal_render_url, double browser_signal_bid, + const absl::optional<blink::AdCurrency>& browser_signal_bid_currency, double browser_signal_desirability, double browser_signal_highest_scoring_other_bid, + const absl::optional<blink::AdCurrency>& + browser_signal_highest_scoring_other_bid_currency, auction_worklet::mojom::ComponentAuctionReportResultParamsPtr browser_signals_component_auction_report_result_params, uint32_t browser_signal_data_version,
diff --git a/content/browser/renderer_host/frame_tree_node.cc b/content/browser/renderer_host/frame_tree_node.cc index bc8c8a7..ba54eadd 100644 --- a/content/browser/renderer_host/frame_tree_node.cc +++ b/content/browser/renderer_host/frame_tree_node.cc
@@ -1001,10 +1001,6 @@ bool FrameTreeNode::IsErrorPageIsolationEnabled() const { // Error page isolation is enabled for main frames only (crbug.com/1092524). - // Note that this will also enable error page isolation for fenced frames in - // MPArch mode, but not ShadowDOM mode. - // See the issue in crbug.com/1264224#c7 for why it can't be enabled for - // ShadowDOM mode. return SiteIsolationPolicy::IsErrorPageIsolationEnabled(IsMainFrame()); }
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc index 31314df9..031a5861 100644 --- a/content/browser/renderer_host/render_frame_host_impl.cc +++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -4694,6 +4694,11 @@ ChromeTrackEvent::kRenderFrameHost, this, "url", params->url.possibly_invalid_spec()); + // TODO(peilinwang): remove after the + // kReduceToolbarUpdatesForSameDocNavigations experiment is complete. + SCOPED_UMA_HISTOGRAM_TIMER( + "Navigation.DidCommitSameDocumentNavigation.Duration"); + ScopedActiveURL scoped_active_url(params->url, GetMainFrame()->GetLastCommittedOrigin()); ScopedCommitStateResetter commit_state_resetter(this);
diff --git a/content/browser/renderer_host/render_process_host_browsertest.cc b/content/browser/renderer_host/render_process_host_browsertest.cc index 9100a786..39cc594 100644 --- a/content/browser/renderer_host/render_process_host_browsertest.cc +++ b/content/browser/renderer_host/render_process_host_browsertest.cc
@@ -2,7 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <memory> #include <string> +#include <utility> #include "base/command_line.h" #include "base/functional/bind.h" @@ -31,6 +33,7 @@ #include "content/public/browser/child_process_launcher_utils.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" +#include "content/public/browser/render_process_host_creation_observer.h" #include "content/public/browser/render_process_host_observer.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_observer.h" @@ -2185,4 +2188,92 @@ } } +class CreationObserver : public RenderProcessHostCreationObserver { + public: + explicit CreationObserver( + base::RepeatingClosure closure = base::RepeatingClosure()) + : closure_(std::move(closure)) {} + + // content::RenderProcessHostCreationObserver: + void OnRenderProcessHostCreated(RenderProcessHost* process_host) override { + if (closure_) { + closure_.Run(); + } + } + + private: + base::RepeatingClosure closure_; +}; + +IN_PROC_BROWSER_TEST_P(RenderProcessHostTest, HostCreationObserved) { + int created_count = 0; + CreationObserver creation_observer( + base::BindLambdaForTesting([&created_count]() { ++created_count; })); + RenderProcessHost* process = RenderProcessHostImpl::CreateRenderProcessHost( + ShellContentBrowserClient::Get()->browser_context(), nullptr); + RenderProcessHostWatcher process_watcher( + process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_READY); + process->Init(); + process_watcher.Wait(); + ASSERT_TRUE(process->IsReady()); + EXPECT_EQ(1, created_count); + process->Cleanup(); +} + +// Notification of RenderProcessHost creation should not crash if creation +// observers are added during notification of another creation observer. +IN_PROC_BROWSER_TEST_P(RenderProcessHostTest, + HostCreationObserversAddedDuringNotification) { + std::vector<std::unique_ptr<CreationObserver>> added_creation_observers; + const int kObserversToAdd = 1000; + int added_observer_notification_count = 0; + const auto increment_added_observer_notification_count = + base::BindLambdaForTesting([&added_observer_notification_count]() { + ++added_observer_notification_count; + }); + CreationObserver creation_observer1(base::BindLambdaForTesting( + [&added_creation_observers, + increment_added_observer_notification_count]() { + for (int i = 0; i < kObserversToAdd; ++i) { + added_creation_observers.push_back(std::make_unique<CreationObserver>( + increment_added_observer_notification_count)); + } + })); + CreationObserver creation_observer2; + + RenderProcessHost* process = RenderProcessHostImpl::CreateRenderProcessHost( + ShellContentBrowserClient::Get()->browser_context(), nullptr); + RenderProcessHostWatcher process_watcher( + process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_READY); + process->Init(); + process_watcher.Wait(); + EXPECT_TRUE(process->IsReady()); + EXPECT_EQ(kObserversToAdd, added_observer_notification_count); + process->Cleanup(); +} + +// Notification of RenderProcessHost creation should not crash if a creation +// observer is destroyed during notification of another creation observer. +IN_PROC_BROWSER_TEST_P(RenderProcessHostTest, + HostCreationObserversDestroyedDuringNotification) { + base::OnceClosure destroy_second_observer; + CreationObserver creation_observer1( + base::BindLambdaForTesting([&destroy_second_observer]() { + std::move(destroy_second_observer).Run(); + })); + auto creation_observer2 = std::make_unique<CreationObserver>(); + destroy_second_observer = base::BindLambdaForTesting( + [&creation_observer2]() { creation_observer2.reset(); }); + + RenderProcessHost* process = RenderProcessHostImpl::CreateRenderProcessHost( + ShellContentBrowserClient::Get()->browser_context(), nullptr); + RenderProcessHostWatcher process_watcher( + process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_READY); + process->Init(); + process_watcher.Wait(); + EXPECT_TRUE(process->IsReady()); + EXPECT_EQ(nullptr, creation_observer2.get()); + process->Cleanup(); +} + } // namespace content
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index b7007ab..5ee1648 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -9,6 +9,7 @@ #include <algorithm> #include <limits> +#include <list> #include <map> #include <memory> #include <set> @@ -317,9 +318,11 @@ return *s_all_hosts; } -// Returns the global list of RenderProcessHostCreationObserver objects. -std::vector<RenderProcessHostCreationObserver*>& GetAllCreationObservers() { - static base::NoDestructor<std::vector<RenderProcessHostCreationObserver*>> +// Returns the global list of RenderProcessHostCreationObserver objects. Uses +// std::list to ensure iterators remain valid if observers are created or +// removed during iteration. +std::list<RenderProcessHostCreationObserver*>& GetAllCreationObservers() { + static base::NoDestructor<std::list<RenderProcessHostCreationObserver*>> s_all_creation_observers; return *s_all_creation_observers; }
diff --git a/content/browser/resources/gpu/BUILD.gn b/content/browser/resources/gpu/BUILD.gn index aa76b187..d93a472 100644 --- a/content/browser/resources/gpu/BUILD.gn +++ b/content/browser/resources/gpu/BUILD.gn
@@ -47,6 +47,18 @@ deps = [ ":html_wrapper_files" ] } +generate_grd("build_mojo_grdp") { + out_grd = "$target_gen_dir/mojo_resources.grdp" + grd_prefix = "gpu" + input_files = [ + "vulkan_info.mojom-webui.js", + "vulkan_types.mojom-webui.js", + ] + input_files_base_dir = + rebase_path("${root_gen_dir}/mojom-webui/gpu/ipc/common", root_build_dir) + deps = [ "//gpu/ipc/common:vulkan_interface_js__generator" ] +} + generate_grd("build_grd") { out_grd = generated_grd grd_prefix = "gpu" @@ -54,9 +66,15 @@ [ "gpu_internals.html" ] + web_component_files + non_component_files input_files_base_dir = rebase_path(".", "//") - grdp_files = filter_include(get_target_outputs(":build_html_wrapper_grdp"), - [ "*.grdp" ]) - deps = [ ":build_html_wrapper_grdp" ] + grdp_files = [ + "$target_gen_dir/html_wrapper_resources.grdp", + "$target_gen_dir/mojo_resources.grdp", + ] + + deps = [ + ":build_html_wrapper_grdp", + ":build_mojo_grdp", + ] } grit("resources") {
diff --git a/content/content_resources.grd b/content/content_resources.grd index 16999d8..d843cc53 100644 --- a/content/content_resources.grd +++ b/content/content_resources.grd
@@ -31,8 +31,6 @@ <include name="IDR_UNGUESSABLE_TOKEN_MOJO_JS" file="${root_gen_dir}/mojo/public/mojom/base/unguessable_token.mojom-lite.js" resource_path="mojo/mojo/public/mojom/base/unguessable_token.mojom-lite.js" use_base_dir="false" type="BINDATA" /> <include name="IDR_URL_MOJO_JS" file="${root_gen_dir}/url/mojom/url.mojom-lite.js" resource_path="mojo/url/mojom/url.mojom-lite.js" use_base_dir="false" type="BINDATA" /> </if> - <include name="IDR_VULKAN_INFO_MOJO_JS" file="${root_gen_dir}/mojom-webui/gpu/ipc/common/vulkan_info.mojom-webui.js" resource_path="gpu/ipc/common/vulkan_info.mojom-webui.js" use_base_dir="false" type="BINDATA" /> - <include name="IDR_VULKAN_TYPES_MOJO_JS" file="${root_gen_dir}/mojom-webui/gpu/ipc/common/vulkan_types.mojom-webui.js" resource_path="gpu/ipc/common/vulkan_types.mojom-webui.js" use_base_dir="false" type="BINDATA" /> </includes> </release> </grit>
diff --git a/content/public/android/java/src/org/chromium/content/browser/selection/SelectionPopupControllerImpl.java b/content/public/android/java/src/org/chromium/content/browser/selection/SelectionPopupControllerImpl.java index 1395c32..d25029d 100644 --- a/content/public/android/java/src/org/chromium/content/browser/selection/SelectionPopupControllerImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/selection/SelectionPopupControllerImpl.java
@@ -166,6 +166,10 @@ // Tracks whether a touch selection is currently active. private boolean mHasSelection; + // If we are currently processing a Select All request from the menu. Used to + // dismiss the old menu so that it won't be preserved and redrawn at a new anchor. + private boolean mIsProcessingSelectAll; + // Lazily created paste popup menu, triggered either via long press in an // editable region or from tapping the insertion handle. private PastePopupMenu mPastePopupMenu; @@ -1056,6 +1060,7 @@ */ @VisibleForTesting public void selectAll() { + mIsProcessingSelectAll = true; mWebContents.selectAll(); mClassificationResult = null; // Even though the above statement logged a SelectAll user action, we want to @@ -1440,7 +1445,7 @@ @CalledByNative /* package */ void onSelectionChanged(String text) { final boolean unSelected = TextUtils.isEmpty(text) && hasSelection(); - if (unSelected) { + if (unSelected || mIsProcessingSelectAll) { if (mSmartSelectionEventProcessor != null) { mSmartSelectionEventProcessor.onSelectionAction(mLastSelectedText, mLastSelectionOffset, SelectionEvent.ACTION_ABANDON, @@ -1452,6 +1457,7 @@ if (mSelectionClient != null) { mSelectionClient.onSelectionChanged(text); } + mIsProcessingSelectAll = false; } /**
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityTest.java b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityTest.java index 0c8220b..6cdef29 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityTest.java
@@ -91,11 +91,11 @@ import org.junit.runner.RunWith; import org.chromium.base.FeatureList; -import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.test.util.Criteria; import org.chromium.base.test.util.CriteriaHelper; import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.DoNotBatch; +import org.chromium.base.test.util.HistogramWatcher; import org.chromium.base.test.util.Restriction; import org.chromium.base.test.util.UrlUtils; import org.chromium.content_public.browser.ContentFeatureList; @@ -397,33 +397,21 @@ AccessibilityState.setOnlyPasswordManagersEnabledForTesting(false); }); + var histogramWatcher = + HistogramWatcher.newBuilder() + .expectIntRecord(PERCENTAGE_DROPPED_HISTOGRAM, 0) + .expectIntRecord(PERCENTAGE_DROPPED_HISTOGRAM_AXMODE_COMPLETE, 0) + .expectNoRecords(PERCENTAGE_DROPPED_HISTOGRAM_AXMODE_FORM_CONTROLS) + .expectNoRecords(PERCENTAGE_DROPPED_HISTOGRAM_AXMODE_BASIC) + .expectIntRecord(EVENTS_DROPPED_HISTOGRAM, 0) + .expectNoRecords(ONE_HUNDRED_PERCENT_HISTOGRAM) + .expectNoRecords(ONE_HUNDRED_PERCENT_HISTOGRAM_AXMODE_COMPLETE) + .expectNoRecords(ONE_HUNDRED_PERCENT_HISTOGRAM_AXMODE_FORM_CONTROLS) + .expectNoRecords(ONE_HUNDRED_PERCENT_HISTOGRAM_AXMODE_BASIC) + .build(); performHistogramActions(); - // Verify results were recorded in histograms. - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 1, - RecordHistogram.getHistogramTotalCountForTesting(PERCENTAGE_DROPPED_HISTOGRAM)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 1, - RecordHistogram.getHistogramTotalCountForTesting( - PERCENTAGE_DROPPED_HISTOGRAM_AXMODE_COMPLETE)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 0, - RecordHistogram.getHistogramTotalCountForTesting( - PERCENTAGE_DROPPED_HISTOGRAM_AXMODE_FORM_CONTROLS)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 0, - RecordHistogram.getHistogramTotalCountForTesting( - PERCENTAGE_DROPPED_HISTOGRAM_AXMODE_BASIC)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 1, - RecordHistogram.getHistogramTotalCountForTesting(EVENTS_DROPPED_HISTOGRAM)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 0, - RecordHistogram.getHistogramTotalCountForTesting(ONE_HUNDRED_PERCENT_HISTOGRAM)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 0, - RecordHistogram.getHistogramTotalCountForTesting( - ONE_HUNDRED_PERCENT_HISTOGRAM_AXMODE_COMPLETE)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 0, - RecordHistogram.getHistogramTotalCountForTesting( - ONE_HUNDRED_PERCENT_HISTOGRAM_AXMODE_FORM_CONTROLS)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 0, - RecordHistogram.getHistogramTotalCountForTesting( - ONE_HUNDRED_PERCENT_HISTOGRAM_AXMODE_BASIC)); + histogramWatcher.assertExpected(); } /** @@ -442,35 +430,25 @@ TestThreadUtils.runOnUiThreadBlocking(() -> { AccessibilityState.setScreenReaderEnabledForTesting(false); AccessibilityState.setOnlyPasswordManagersEnabledForTesting(true); + }); + var histogramWatcher = + HistogramWatcher.newBuilder() + .expectIntRecord(PERCENTAGE_DROPPED_HISTOGRAM, 0) + .expectNoRecords(PERCENTAGE_DROPPED_HISTOGRAM_AXMODE_COMPLETE) + .expectIntRecord(PERCENTAGE_DROPPED_HISTOGRAM_AXMODE_FORM_CONTROLS, 0) + .expectNoRecords(PERCENTAGE_DROPPED_HISTOGRAM_AXMODE_BASIC) + .expectIntRecord(EVENTS_DROPPED_HISTOGRAM, 0) + .expectNoRecords(ONE_HUNDRED_PERCENT_HISTOGRAM) + .expectNoRecords(ONE_HUNDRED_PERCENT_HISTOGRAM_AXMODE_COMPLETE) + .expectNoRecords(ONE_HUNDRED_PERCENT_HISTOGRAM_AXMODE_FORM_CONTROLS) + .expectNoRecords(ONE_HUNDRED_PERCENT_HISTOGRAM_AXMODE_BASIC) + .build(); + performHistogramActions(); - // Verify results were recorded in histograms. - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 1, - RecordHistogram.getHistogramTotalCountForTesting(PERCENTAGE_DROPPED_HISTOGRAM)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 0, - RecordHistogram.getHistogramTotalCountForTesting( - PERCENTAGE_DROPPED_HISTOGRAM_AXMODE_COMPLETE)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 1, - RecordHistogram.getHistogramTotalCountForTesting( - PERCENTAGE_DROPPED_HISTOGRAM_AXMODE_FORM_CONTROLS)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 0, - RecordHistogram.getHistogramTotalCountForTesting( - PERCENTAGE_DROPPED_HISTOGRAM_AXMODE_BASIC)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 1, - RecordHistogram.getHistogramTotalCountForTesting(EVENTS_DROPPED_HISTOGRAM)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 0, - RecordHistogram.getHistogramTotalCountForTesting(ONE_HUNDRED_PERCENT_HISTOGRAM)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 0, - RecordHistogram.getHistogramTotalCountForTesting( - ONE_HUNDRED_PERCENT_HISTOGRAM_AXMODE_COMPLETE)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 0, - RecordHistogram.getHistogramTotalCountForTesting( - ONE_HUNDRED_PERCENT_HISTOGRAM_AXMODE_FORM_CONTROLS)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 0, - RecordHistogram.getHistogramTotalCountForTesting( - ONE_HUNDRED_PERCENT_HISTOGRAM_AXMODE_BASIC)); + histogramWatcher.assertExpected(); } /** @@ -491,33 +469,22 @@ AccessibilityState.setOnlyPasswordManagersEnabledForTesting(false); }); + var histogramWatcher = + HistogramWatcher.newBuilder() + .expectIntRecord(PERCENTAGE_DROPPED_HISTOGRAM, 0) + .expectNoRecords(PERCENTAGE_DROPPED_HISTOGRAM_AXMODE_COMPLETE) + .expectNoRecords(PERCENTAGE_DROPPED_HISTOGRAM_AXMODE_FORM_CONTROLS) + .expectIntRecord(PERCENTAGE_DROPPED_HISTOGRAM_AXMODE_BASIC, 0) + .expectIntRecord(EVENTS_DROPPED_HISTOGRAM, 0) + .expectNoRecords(ONE_HUNDRED_PERCENT_HISTOGRAM) + .expectNoRecords(ONE_HUNDRED_PERCENT_HISTOGRAM_AXMODE_COMPLETE) + .expectNoRecords(ONE_HUNDRED_PERCENT_HISTOGRAM_AXMODE_FORM_CONTROLS) + .expectNoRecords(ONE_HUNDRED_PERCENT_HISTOGRAM_AXMODE_BASIC) + .build(); + performHistogramActions(); - // Verify results were recorded in histograms. - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 1, - RecordHistogram.getHistogramTotalCountForTesting(PERCENTAGE_DROPPED_HISTOGRAM)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 0, - RecordHistogram.getHistogramTotalCountForTesting( - PERCENTAGE_DROPPED_HISTOGRAM_AXMODE_COMPLETE)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 0, - RecordHistogram.getHistogramTotalCountForTesting( - PERCENTAGE_DROPPED_HISTOGRAM_AXMODE_FORM_CONTROLS)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 1, - RecordHistogram.getHistogramTotalCountForTesting( - PERCENTAGE_DROPPED_HISTOGRAM_AXMODE_BASIC)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 1, - RecordHistogram.getHistogramTotalCountForTesting(EVENTS_DROPPED_HISTOGRAM)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 0, - RecordHistogram.getHistogramTotalCountForTesting(ONE_HUNDRED_PERCENT_HISTOGRAM)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 0, - RecordHistogram.getHistogramTotalCountForTesting( - ONE_HUNDRED_PERCENT_HISTOGRAM_AXMODE_COMPLETE)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 0, - RecordHistogram.getHistogramTotalCountForTesting( - ONE_HUNDRED_PERCENT_HISTOGRAM_AXMODE_FORM_CONTROLS)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 0, - RecordHistogram.getHistogramTotalCountForTesting( - ONE_HUNDRED_PERCENT_HISTOGRAM_AXMODE_BASIC)); + histogramWatcher.assertExpected(); } /** @@ -526,7 +493,6 @@ */ @Test @SmallTest - @DisabledTest(message = "https://crbug.com/1360513") public void testUMAHistograms_OnDemand_AXModeComplete_100Percent() throws Throwable { // Build a simple web page with a few nodes to traverse. setupTestWithHTML("<p>This is a test 1</p>\n" @@ -541,33 +507,22 @@ AccessibilityState.setOnlyPasswordManagersEnabledForTesting(false); }); + var histogramWatcher = + HistogramWatcher.newBuilder() + .expectIntRecord(PERCENTAGE_DROPPED_HISTOGRAM, 100) + .expectIntRecord(PERCENTAGE_DROPPED_HISTOGRAM_AXMODE_COMPLETE, 100) + .expectNoRecords(PERCENTAGE_DROPPED_HISTOGRAM_AXMODE_FORM_CONTROLS) + .expectNoRecords(PERCENTAGE_DROPPED_HISTOGRAM_AXMODE_BASIC) + .expectIntRecord(EVENTS_DROPPED_HISTOGRAM, 3) + .expectIntRecord(ONE_HUNDRED_PERCENT_HISTOGRAM, 3) + .expectIntRecord(ONE_HUNDRED_PERCENT_HISTOGRAM_AXMODE_COMPLETE, 3) + .expectNoRecords(ONE_HUNDRED_PERCENT_HISTOGRAM_AXMODE_FORM_CONTROLS) + .expectNoRecords(ONE_HUNDRED_PERCENT_HISTOGRAM_AXMODE_BASIC) + .build(); + performHistogramActions(); - // Verify results were recorded in histograms. - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 1, - RecordHistogram.getHistogramTotalCountForTesting(PERCENTAGE_DROPPED_HISTOGRAM)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 1, - RecordHistogram.getHistogramTotalCountForTesting( - PERCENTAGE_DROPPED_HISTOGRAM_AXMODE_COMPLETE)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 0, - RecordHistogram.getHistogramTotalCountForTesting( - PERCENTAGE_DROPPED_HISTOGRAM_AXMODE_FORM_CONTROLS)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 0, - RecordHistogram.getHistogramTotalCountForTesting( - PERCENTAGE_DROPPED_HISTOGRAM_AXMODE_BASIC)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 1, - RecordHistogram.getHistogramTotalCountForTesting(EVENTS_DROPPED_HISTOGRAM)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 1, - RecordHistogram.getHistogramTotalCountForTesting(ONE_HUNDRED_PERCENT_HISTOGRAM)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 1, - RecordHistogram.getHistogramTotalCountForTesting( - ONE_HUNDRED_PERCENT_HISTOGRAM_AXMODE_COMPLETE)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 0, - RecordHistogram.getHistogramTotalCountForTesting( - ONE_HUNDRED_PERCENT_HISTOGRAM_AXMODE_FORM_CONTROLS)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 0, - RecordHistogram.getHistogramTotalCountForTesting( - ONE_HUNDRED_PERCENT_HISTOGRAM_AXMODE_BASIC)); + histogramWatcher.assertExpected(); } /** @@ -590,33 +545,22 @@ AccessibilityState.setOnlyPasswordManagersEnabledForTesting(true); }); + var histogramWatcher = + HistogramWatcher.newBuilder() + .expectIntRecord(PERCENTAGE_DROPPED_HISTOGRAM, 100) + .expectNoRecords(PERCENTAGE_DROPPED_HISTOGRAM_AXMODE_COMPLETE) + .expectIntRecord(PERCENTAGE_DROPPED_HISTOGRAM_AXMODE_FORM_CONTROLS, 100) + .expectNoRecords(PERCENTAGE_DROPPED_HISTOGRAM_AXMODE_BASIC) + .expectIntRecord(EVENTS_DROPPED_HISTOGRAM, 3) + .expectIntRecord(ONE_HUNDRED_PERCENT_HISTOGRAM, 3) + .expectNoRecords(ONE_HUNDRED_PERCENT_HISTOGRAM_AXMODE_COMPLETE) + .expectIntRecord(ONE_HUNDRED_PERCENT_HISTOGRAM_AXMODE_FORM_CONTROLS, 3) + .expectNoRecords(ONE_HUNDRED_PERCENT_HISTOGRAM_AXMODE_BASIC) + .build(); + performHistogramActions(); - // Verify results were recorded in histograms. - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 1, - RecordHistogram.getHistogramTotalCountForTesting(PERCENTAGE_DROPPED_HISTOGRAM)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 0, - RecordHistogram.getHistogramTotalCountForTesting( - PERCENTAGE_DROPPED_HISTOGRAM_AXMODE_COMPLETE)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 1, - RecordHistogram.getHistogramTotalCountForTesting( - PERCENTAGE_DROPPED_HISTOGRAM_AXMODE_FORM_CONTROLS)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 0, - RecordHistogram.getHistogramTotalCountForTesting( - PERCENTAGE_DROPPED_HISTOGRAM_AXMODE_BASIC)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 1, - RecordHistogram.getHistogramTotalCountForTesting(EVENTS_DROPPED_HISTOGRAM)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 1, - RecordHistogram.getHistogramTotalCountForTesting(ONE_HUNDRED_PERCENT_HISTOGRAM)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 0, - RecordHistogram.getHistogramTotalCountForTesting( - ONE_HUNDRED_PERCENT_HISTOGRAM_AXMODE_COMPLETE)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 1, - RecordHistogram.getHistogramTotalCountForTesting( - ONE_HUNDRED_PERCENT_HISTOGRAM_AXMODE_FORM_CONTROLS)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 0, - RecordHistogram.getHistogramTotalCountForTesting( - ONE_HUNDRED_PERCENT_HISTOGRAM_AXMODE_BASIC)); + histogramWatcher.assertExpected(); } /** @@ -639,33 +583,22 @@ AccessibilityState.setOnlyPasswordManagersEnabledForTesting(false); }); + var histogramWatcher = + HistogramWatcher.newBuilder() + .expectIntRecord(PERCENTAGE_DROPPED_HISTOGRAM, 100) + .expectNoRecords(PERCENTAGE_DROPPED_HISTOGRAM_AXMODE_COMPLETE) + .expectNoRecords(PERCENTAGE_DROPPED_HISTOGRAM_AXMODE_FORM_CONTROLS) + .expectIntRecord(PERCENTAGE_DROPPED_HISTOGRAM_AXMODE_BASIC, 100) + .expectIntRecord(EVENTS_DROPPED_HISTOGRAM, 3) + .expectIntRecord(ONE_HUNDRED_PERCENT_HISTOGRAM, 3) + .expectNoRecords(ONE_HUNDRED_PERCENT_HISTOGRAM_AXMODE_COMPLETE) + .expectNoRecords(ONE_HUNDRED_PERCENT_HISTOGRAM_AXMODE_FORM_CONTROLS) + .expectIntRecord(ONE_HUNDRED_PERCENT_HISTOGRAM_AXMODE_BASIC, 3) + .build(); + performHistogramActions(); - // Verify results were recorded in histograms. - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 1, - RecordHistogram.getHistogramTotalCountForTesting(PERCENTAGE_DROPPED_HISTOGRAM)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 0, - RecordHistogram.getHistogramTotalCountForTesting( - PERCENTAGE_DROPPED_HISTOGRAM_AXMODE_COMPLETE)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 0, - RecordHistogram.getHistogramTotalCountForTesting( - PERCENTAGE_DROPPED_HISTOGRAM_AXMODE_FORM_CONTROLS)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 1, - RecordHistogram.getHistogramTotalCountForTesting( - PERCENTAGE_DROPPED_HISTOGRAM_AXMODE_BASIC)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 1, - RecordHistogram.getHistogramTotalCountForTesting(EVENTS_DROPPED_HISTOGRAM)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 1, - RecordHistogram.getHistogramTotalCountForTesting(ONE_HUNDRED_PERCENT_HISTOGRAM)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 0, - RecordHistogram.getHistogramTotalCountForTesting( - ONE_HUNDRED_PERCENT_HISTOGRAM_AXMODE_COMPLETE)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 0, - RecordHistogram.getHistogramTotalCountForTesting( - ONE_HUNDRED_PERCENT_HISTOGRAM_AXMODE_FORM_CONTROLS)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 1, - RecordHistogram.getHistogramTotalCountForTesting( - ONE_HUNDRED_PERCENT_HISTOGRAM_AXMODE_BASIC)); + histogramWatcher.assertExpected(); } /** @@ -680,14 +613,15 @@ + "<p>This is a test 2</p>\n" + "<p>This is a test 3</p>"); + var histogramWatcher = + HistogramWatcher.newBuilder() + .expectIntRecord(CACHE_MAX_NODES_HISTOGRAM, 3) + .expectAnyRecord(CACHE_PERCENTAGE_RETRIEVED_FROM_CACHE_HISTOGRAM) + .build(); + performHistogramActions(); - // Verify results were recorded in histograms. - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 1, - RecordHistogram.getHistogramTotalCountForTesting(CACHE_MAX_NODES_HISTOGRAM)); - Assert.assertEquals(UMA_HISTOGRAM_ERROR, 1, - RecordHistogram.getHistogramTotalCountForTesting( - CACHE_PERCENTAGE_RETRIEVED_FROM_CACHE_HISTOGRAM)); + histogramWatcher.assertExpected(); } /**
diff --git a/content/services/auction_worklet/auction_v8_helper_unittest.cc b/content/services/auction_worklet/auction_v8_helper_unittest.cc index 648c82e..d640458 100644 --- a/content/services/auction_worklet/auction_v8_helper_unittest.cc +++ b/content/services/auction_worklet/auction_v8_helper_unittest.cc
@@ -94,7 +94,10 @@ const std::string& seller_signals_json, const GURL& browser_signal_render_url, double browser_signal_bid, + const absl::optional<blink::AdCurrency>& browser_signal_bid_currency, double browser_signal_highest_scoring_other_bid, + const absl::optional<blink::AdCurrency>& + browser_signal_highest_scoring_other_bid_currency, bool browser_signal_made_highest_scoring_other_bid, absl::optional<double> browser_signal_ad_cost, absl::optional<uint16_t> browser_signal_modeling_signals,
diff --git a/content/services/auction_worklet/bidder_worklet.cc b/content/services/auction_worklet/bidder_worklet.cc index 4f2ecdd..1bb6cc6 100644 --- a/content/services/auction_worklet/bidder_worklet.cc +++ b/content/services/auction_worklet/bidder_worklet.cc
@@ -51,6 +51,7 @@ #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/public/common/features.h" #include "third_party/blink/public/common/interest_group/ad_auction_constants.h" +#include "third_party/blink/public/common/interest_group/ad_auction_currencies.h" #include "third_party/blink/public/mojom/interest_group/interest_group_types.mojom.h" #include "url/gurl.h" #include "url/origin.h" @@ -316,7 +317,10 @@ const std::string& seller_signals_json, const GURL& browser_signal_render_url, double browser_signal_bid, + const absl::optional<blink::AdCurrency>& browser_signal_bid_currency, double browser_signal_highest_scoring_other_bid, + const absl::optional<blink::AdCurrency>& + browser_signal_highest_scoring_other_bid_currency, bool browser_signal_made_highest_scoring_other_bid, absl::optional<double> browser_signal_ad_cost, absl::optional<uint16_t> browser_signal_modeling_signals, @@ -338,8 +342,11 @@ report_win_task->seller_signals_json = seller_signals_json; report_win_task->browser_signal_render_url = browser_signal_render_url; report_win_task->browser_signal_bid = browser_signal_bid; + report_win_task->browser_signal_bid_currency = browser_signal_bid_currency; report_win_task->browser_signal_highest_scoring_other_bid = browser_signal_highest_scoring_other_bid; + report_win_task->browser_signal_highest_scoring_other_bid_currency = + browser_signal_highest_scoring_other_bid_currency; report_win_task->browser_signal_made_highest_scoring_other_bid = browser_signal_made_highest_scoring_other_bid; report_win_task->browser_signal_ad_cost = browser_signal_ad_cost; @@ -408,7 +415,7 @@ const absl::optional<std::string>& auction_signals_json, const absl::optional<std::string>& per_buyer_signals_json, const absl::optional<base::TimeDelta> per_buyer_timeout, - const std::string& expected_buyer_currency, + const absl::optional<blink::AdCurrency>& expected_buyer_currency, const absl::optional<GURL>& direct_from_seller_per_buyer_signals, const absl::optional<GURL>& direct_from_seller_auction_signals) { GenerateBidTaskList::iterator task = finalize_receiver_set_.current_context(); @@ -515,7 +522,10 @@ const std::string& seller_signals_json, const GURL& browser_signal_render_url, double browser_signal_bid, + const absl::optional<blink::AdCurrency>& browser_signal_bid_currency, double browser_signal_highest_scoring_other_bid, + const absl::optional<blink::AdCurrency>& + browser_signal_highest_scoring_other_bid_currency, bool browser_signal_made_highest_scoring_other_bid, const absl::optional<double>& browser_signal_ad_cost, const absl::optional<uint16_t>& browser_signal_modeling_signals, @@ -565,6 +575,9 @@ !browser_signals_dict.Set("renderUrl", browser_signal_render_url.spec()) || !browser_signals_dict.Set("bid", browser_signal_bid) || + !browser_signals_dict.Set( + "bidCurrency", + blink::PrintableAdCurrency(browser_signal_bid_currency)) || (browser_signal_ad_cost.has_value() && !browser_signals_dict.Set("adCost", *browser_signal_ad_cost)) || (browser_signal_modeling_signals.has_value() && @@ -578,6 +591,10 @@ !browser_signals_dict.Set("highestScoringOtherBid", browser_signal_highest_scoring_other_bid) || !browser_signals_dict.Set( + "highestScoringOtherBidCurrency", + blink::PrintableAdCurrency( + browser_signal_highest_scoring_other_bid_currency)) || + !browser_signals_dict.Set( "madeHighestScoringOtherBid", browser_signal_made_highest_scoring_other_bid) || !browser_signals_dict.Set("seller", @@ -692,7 +709,7 @@ DirectFromSellerSignalsRequester::Result direct_from_seller_result_auction_signals, const absl::optional<base::TimeDelta> per_buyer_timeout, - const std::string& expected_buyer_currency, + const absl::optional<blink::AdCurrency>& expected_buyer_currency, const url::Origin& browser_signal_seller_origin, const absl::optional<url::Origin>& browser_signal_top_level_seller_origin, mojom::BiddingBrowserSignalsPtr bidding_browser_signals, @@ -815,7 +832,7 @@ const DirectFromSellerSignalsRequester::Result& direct_from_seller_result_auction_signals, const absl::optional<base::TimeDelta> per_buyer_timeout, - const std::string& expected_buyer_currency, + const absl::optional<blink::AdCurrency>& expected_buyer_currency, const url::Origin& browser_signal_seller_origin, const url::Origin* browser_signal_top_level_seller_origin, const mojom::BiddingBrowserSignalsPtr& bidding_browser_signals, @@ -1683,7 +1700,9 @@ std::move(task->seller_signals_json), std::move(task->browser_signal_render_url), std::move(task->browser_signal_bid), + std::move(task->browser_signal_bid_currency), std::move(task->browser_signal_highest_scoring_other_bid), + std::move(task->browser_signal_highest_scoring_other_bid_currency), std::move(task->browser_signal_made_highest_scoring_other_bid), std::move(task->browser_signal_ad_cost), std::move(task->browser_signal_modeling_signals),
diff --git a/content/services/auction_worklet/bidder_worklet.h b/content/services/auction_worklet/bidder_worklet.h index 44996dc..b0b4f1e 100644 --- a/content/services/auction_worklet/bidder_worklet.h +++ b/content/services/auction_worklet/bidder_worklet.h
@@ -149,7 +149,10 @@ const std::string& seller_signals_json, const GURL& browser_signal_render_url, double browser_signal_bid, + const absl::optional<blink::AdCurrency>& browser_signal_bid_currency, double browser_signal_highest_scoring_other_bid, + const absl::optional<blink::AdCurrency>& + browser_signal_highest_scoring_other_bid_currency, bool browser_signal_made_highest_scoring_other_bid, absl::optional<double> browser_signal_ad_cost, absl::optional<uint16_t> browser_signal_modeling_signals, @@ -170,7 +173,7 @@ const absl::optional<std::string>& auction_signals_json, const absl::optional<std::string>& per_buyer_signals_json, const absl::optional<base::TimeDelta> per_buyer_timeout, - const std::string& expected_buyer_currency, + const absl::optional<blink::AdCurrency>& expected_buyer_currency, const absl::optional<GURL>& direct_from_seller_per_buyer_signals, const absl::optional<GURL>& direct_from_seller_auction_signals) override; @@ -188,7 +191,7 @@ absl::optional<std::string> auction_signals_json; absl::optional<std::string> per_buyer_signals_json; absl::optional<base::TimeDelta> per_buyer_timeout; - std::string expected_buyer_currency; + absl::optional<blink::AdCurrency> expected_buyer_currency; url::Origin browser_signal_seller_origin; absl::optional<url::Origin> browser_signal_top_level_seller_origin; mojom::BiddingBrowserSignalsPtr bidding_browser_signals; @@ -253,7 +256,10 @@ std::string seller_signals_json; GURL browser_signal_render_url; double browser_signal_bid; + absl::optional<blink::AdCurrency> browser_signal_bid_currency; double browser_signal_highest_scoring_other_bid; + absl::optional<blink::AdCurrency> + browser_signal_highest_scoring_other_bid_currency; bool browser_signal_made_highest_scoring_other_bid; absl::optional<double> browser_signal_ad_cost; absl::optional<uint16_t> browser_signal_modeling_signals; @@ -380,7 +386,10 @@ const std::string& seller_signals_json, const GURL& browser_signal_render_url, double browser_signal_bid, + const absl::optional<blink::AdCurrency>& browser_signal_bid_currency, double browser_signal_highest_scoring_other_bid, + const absl::optional<blink::AdCurrency>& + browser_signal_highest_scoring_other_bid_currency, bool browser_signal_made_highest_scoring_other_bid, const absl::optional<double>& browser_signal_ad_cost, const absl::optional<uint16_t>& browser_signal_modeling_signals, @@ -404,7 +413,7 @@ DirectFromSellerSignalsRequester::Result direct_from_seller_result_auction_signals, const absl::optional<base::TimeDelta> per_buyer_timeout, - const std::string& expected_buyer_currency, + const absl::optional<blink::AdCurrency>& expected_buyer_currency, const url::Origin& browser_signal_seller_origin, const absl::optional<url::Origin>& browser_signal_top_level_seller_origin, @@ -436,7 +445,7 @@ const DirectFromSellerSignalsRequester::Result& direct_from_seller_result_auction_signals, const absl::optional<base::TimeDelta> per_buyer_timeout, - const std::string& expected_buyer_currency, + const absl::optional<blink::AdCurrency>& expected_buyer_currency, const url::Origin& browser_signal_seller_origin, const url::Origin* browser_signal_top_level_seller_origin, const mojom::BiddingBrowserSignalsPtr& bidding_browser_signals,
diff --git a/content/services/auction_worklet/bidder_worklet_unittest.cc b/content/services/auction_worklet/bidder_worklet_unittest.cc index a592f1a..3cf5b54 100644 --- a/content/services/auction_worklet/bidder_worklet_unittest.cc +++ b/content/services/auction_worklet/bidder_worklet_unittest.cc
@@ -314,7 +314,7 @@ auction_signals_ = "[\"auction_signals\"]"; per_buyer_signals_ = "[\"per_buyer_signals\"]"; per_buyer_timeout_ = absl::nullopt; - per_buyer_currency_ = blink::kUnspecifiedAdCurrency; + per_buyer_currency_ = absl::nullopt; top_window_origin_ = url::Origin::Create(GURL("https://top.window.test/")); permissions_policy_state_ = mojom::AuctionWorkletPermissionsPolicyState::New( @@ -327,7 +327,9 @@ seller_signals_ = "[\"seller_signals\"]"; browser_signal_render_url_ = GURL("https://render_url.test/"); browser_signal_bid_ = 1; + browser_signal_bid_currency_ = absl::nullopt; browser_signal_highest_scoring_other_bid_ = 0.5; + browser_signal_highest_scoring_other_bid_currency_ = absl::nullopt; browser_signal_made_highest_scoring_other_bid_ = false; browser_signal_ad_cost_.reset(); browser_signal_modeling_signals_.reset(); @@ -349,13 +351,13 @@ expression.c_str())); RunGenerateBidWithJavascriptExpectingResult( - script, - mojom::BidderWorkletBid::New( - /*ad=*/"null", - /*bid=*/1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, - blink::AdDescriptor(GURL("https://response.test/")), - /*ad_component_descriptors=*/absl::nullopt, - /*modeling_signals=*/absl::nullopt, base::TimeDelta())); + script, mojom::BidderWorkletBid::New( + /*ad=*/"null", + /*bid=*/1, /*bid_currency=*/absl::nullopt, + /*ad_cost=*/absl::nullopt, + blink::AdDescriptor(GURL("https://response.test/")), + /*ad_component_descriptors=*/absl::nullopt, + /*modeling_signals=*/absl::nullopt, base::TimeDelta())); } // Configures `url_loader_factory_` to return a generateBid() script with the @@ -434,7 +436,8 @@ if (expected_bid && bid_) { EXPECT_EQ(expected_bid->ad, bid_->ad); EXPECT_EQ(expected_bid->bid, bid_->bid); - EXPECT_EQ(expected_bid->bid_currency, bid_->bid_currency); + EXPECT_EQ(blink::PrintableAdCurrency(expected_bid->bid_currency), + blink::PrintableAdCurrency(bid_->bid_currency)); EXPECT_EQ(expected_bid->ad_descriptor.url, bid_->ad_descriptor.url); if (!expected_bid->ad_component_descriptors) { EXPECT_FALSE(bid_->ad_component_descriptors); @@ -506,7 +509,8 @@ direct_from_seller_per_buyer_signals_, direct_from_seller_auction_signals_, seller_signals_, browser_signal_render_url_, browser_signal_bid_, - browser_signal_highest_scoring_other_bid_, + browser_signal_bid_currency_, browser_signal_highest_scoring_other_bid_, + browser_signal_highest_scoring_other_bid_currency_, browser_signal_made_highest_scoring_other_bid_, browser_signal_ad_cost_, browser_signal_modeling_signals_, browser_signal_join_count_, browser_signal_recency_, browser_signal_seller_origin_, @@ -823,7 +827,7 @@ absl::optional<GURL> direct_from_seller_per_buyer_signals_; absl::optional<GURL> direct_from_seller_auction_signals_; absl::optional<base::TimeDelta> per_buyer_timeout_; - std::string per_buyer_currency_; + absl::optional<blink::AdCurrency> per_buyer_currency_; url::Origin top_window_origin_; mojom::AuctionWorkletPermissionsPolicyStatePtr permissions_policy_state_; absl::optional<uint16_t> experiment_group_id_; @@ -837,7 +841,10 @@ absl::optional<uint32_t> data_version_; GURL browser_signal_render_url_; double browser_signal_bid_; + absl::optional<blink::AdCurrency> browser_signal_bid_currency_; double browser_signal_highest_scoring_other_bid_; + absl::optional<blink::AdCurrency> + browser_signal_highest_scoring_other_bid_currency_; bool browser_signal_made_highest_scoring_other_bid_; absl::optional<double> browser_signal_ad_cost_; absl::optional<uint16_t> browser_signal_modeling_signals_; @@ -925,7 +932,7 @@ RunGenerateBidWithReturnValueExpectingResult( R"({bid:1, render:"https://response.test/"})", mojom::BidderWorkletBid::New( - "null", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "null", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta())); @@ -935,7 +942,7 @@ RunGenerateBidWithReturnValueExpectingResult( R"({ad: globalThis.not_defined, bid:1, render:"https://response.test/"})", mojom::BidderWorkletBid::New( - "null", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "null", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta())); @@ -944,14 +951,15 @@ RunGenerateBidWithReturnValueExpectingResult( R"({ad: "ad", bid:1, render:"https://response.test/"})", mojom::BidderWorkletBid::New( - "\"ad\"", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "\"ad\"", 1, /*bid_currency=*/absl::nullopt, + /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta())); RunGenerateBidWithReturnValueExpectingResult( R"({ad: ["ad"], bid:1, render:"https://response.test/"})", mojom::BidderWorkletBid::New( - R"(["ad"])", 1, blink::kUnspecifiedAdCurrency, + R"(["ad"])", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -959,7 +967,7 @@ RunGenerateBidWithReturnValueExpectingResult( R"({ad: {a:1,b:null}, bid:1, render:"https://response.test/"})", mojom::BidderWorkletBid::New( - R"({"a":1,"b":null})", 1, blink::kUnspecifiedAdCurrency, + R"({"a":1,"b":null})", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -967,7 +975,7 @@ RunGenerateBidWithReturnValueExpectingResult( R"({ad: [2.5,[]], bid:1, render:"https://response.test/"})", mojom::BidderWorkletBid::New( - "[2.5,[]]", 1, blink::kUnspecifiedAdCurrency, + "[2.5,[]]", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -975,7 +983,7 @@ RunGenerateBidWithReturnValueExpectingResult( R"({ad: -5, bid:1, render:"https://response.test/"})", mojom::BidderWorkletBid::New( - "-5", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "-5", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta())); @@ -983,21 +991,23 @@ RunGenerateBidWithReturnValueExpectingResult( R"({ad: 0/0, bid:1, render:"https://response.test/"})", mojom::BidderWorkletBid::New( - "null", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "null", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta())); RunGenerateBidWithReturnValueExpectingResult( R"({ad: [globalThis.not_defined], bid:1, render:"https://response.test/"})", mojom::BidderWorkletBid::New( - "[null]", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "[null]", 1, /*bid_currency=*/absl::nullopt, + /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta())); RunGenerateBidWithReturnValueExpectingResult( R"({ad: [function() {return 1;}], bid:1, render:"https://response.test/"})", mojom::BidderWorkletBid::New( - "[null]", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "[null]", 1, /*bid_currency=*/absl::nullopt, + /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta())); @@ -1044,14 +1054,15 @@ RunGenerateBidWithReturnValueExpectingResult( R"({ad: "ad", bid:1, render:"https://response.test/"})", mojom::BidderWorkletBid::New( - "\"ad\"", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "\"ad\"", 1, /*bid_currency=*/absl::nullopt, + /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta())); RunGenerateBidWithReturnValueExpectingResult( R"({ad: "ad", bid:1.5, render:"https://response.test/"})", mojom::BidderWorkletBid::New( - "\"ad\"", 1.5, blink::kUnspecifiedAdCurrency, + "\"ad\"", 1.5, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -1059,14 +1070,15 @@ RunGenerateBidWithReturnValueExpectingResult( R"({ad: "ad", bid:2, render:"https://response.test/"})", mojom::BidderWorkletBid::New( - "\"ad\"", 2, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "\"ad\"", 2, /*bid_currency=*/absl::nullopt, + /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta())); RunGenerateBidWithReturnValueExpectingResult( R"({ad: "ad", bid:0.001, render:"https://response.test/"})", mojom::BidderWorkletBid::New( - "\"ad\"", 0.001, blink::kUnspecifiedAdCurrency, + "\"ad\"", 0.001, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -1124,18 +1136,19 @@ R"({ad: "ad", bid:1, bidCurrency: "USD", render:"https://response.test/"})", mojom::BidderWorkletBid::New( - "\"ad\"", 1, "USD", /*ad_cost=*/absl::nullopt, + "\"ad\"", 1, blink::AdCurrency::From("USD"), + /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta())); - // Not specifying currency explicitly results in - // blink::kUnspecifiedAdCurrency. + // Not specifying currency explicitly results in nullopt tag. RunGenerateBidWithReturnValueExpectingResult( R"({ad: "ad", bid:1, render:"https://response.test/"})", mojom::BidderWorkletBid::New( - "\"ad\"", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "\"ad\"", 1, /*bid_currency=*/absl::nullopt, + /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta())); @@ -1173,14 +1186,15 @@ TEST_F(BidderWorkletTest, GenerateBidReturnBidCurrencyExpectCAD) { // Tests of returning various currency and comparing against expected `CAD`. // - per_buyer_currency_ = "CAD"; + per_buyer_currency_ = blink::AdCurrency::From("CAD"); // Explicitly specified correct one. RunGenerateBidWithReturnValueExpectingResult( R"({ad: "ad", bid:1, bidCurrency: "CAD", render:"https://response.test/"})", mojom::BidderWorkletBid::New( - "\"ad\"", 1, "CAD", /*ad_cost=*/absl::nullopt, + "\"ad\"", 1, blink::AdCurrency::From("CAD"), + /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta())); @@ -1194,13 +1208,14 @@ {"https://url.test/ generateBid() bidCurrency mismatch; " "returned 'USD', expected 'CAD'."}); - // Not specifying currency explicitly results in - // blink::kUnspecifiedAdCurrency, which matches for compatibility reasons. + // Not specifying currency explicitly results in absl::nullopt, which matches + // for compatibility reasons. RunGenerateBidWithReturnValueExpectingResult( R"({ad: "ad", bid:1, render:"https://response.test/"})", mojom::BidderWorkletBid::New( - "\"ad\"", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "\"ad\"", 1, /*bid_currency=*/absl::nullopt, + /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta())); @@ -1224,7 +1239,7 @@ RunGenerateBidWithReturnValueExpectingResult( R"({ad: ["ad"], bid:1, render:"https://response.test/"})", mojom::BidderWorkletBid::New( - "[\"ad\"]", 1, blink::kUnspecifiedAdCurrency, + "[\"ad\"]", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -1333,7 +1348,8 @@ bid:1, render:"https://response.test/"})", mojom::BidderWorkletBid::New( - "\"ad\"", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "\"ad\"", 1, /*bid_currency=*/absl::nullopt, + /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta())); @@ -1343,7 +1359,8 @@ render:"https://response.test/", adComponents:null})", mojom::BidderWorkletBid::New( - "\"ad\"", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "\"ad\"", 1, /*bid_currency=*/absl::nullopt, + /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta())); @@ -1360,7 +1377,8 @@ bid:1, render:"https://response.test/"})", mojom::BidderWorkletBid::New( - "\"ad\"", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "\"ad\"", 1, /*bid_currency=*/absl::nullopt, + /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta())); @@ -1419,7 +1437,8 @@ "https://ad_component.test/" /* 20 */, ]})", mojom::BidderWorkletBid::New( - "\"ad\"", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "\"ad\"", 1, /*bid_currency=*/absl::nullopt, + /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/ std::vector<blink::AdDescriptor>{ @@ -1487,7 +1506,7 @@ RunGenerateBidWithReturnValueExpectingResult( kGenerateBidBody, mojom::BidderWorkletBid::New( - "null", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "null", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/123u, base::TimeDelta())); @@ -1500,7 +1519,7 @@ RunGenerateBidWithReturnValueExpectingResult( kGenerateBidBody, mojom::BidderWorkletBid::New( - "null", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "null", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta())); @@ -1513,7 +1532,7 @@ RunGenerateBidWithReturnValueExpectingResult( kGenerateBidBody, mojom::BidderWorkletBid::New( - "null", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "null", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta())); @@ -1526,7 +1545,7 @@ RunGenerateBidWithReturnValueExpectingResult( kGenerateBidBody, mojom::BidderWorkletBid::New( - "null", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "null", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta())); @@ -1539,7 +1558,7 @@ RunGenerateBidWithReturnValueExpectingResult( kGenerateBidBody, mojom::BidderWorkletBid::New( - "null", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "null", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta())); @@ -1552,7 +1571,7 @@ RunGenerateBidWithReturnValueExpectingResult( kGenerateBidBody, mojom::BidderWorkletBid::New( - "null", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "null", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta())); @@ -1565,7 +1584,7 @@ RunGenerateBidWithReturnValueExpectingResult( kGenerateBidBody, mojom::BidderWorkletBid::New( - "null", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "null", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/0u, base::TimeDelta())); @@ -1578,7 +1597,7 @@ RunGenerateBidWithReturnValueExpectingResult( kGenerateBidBody, mojom::BidderWorkletBid::New( - "null", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "null", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/123u, base::TimeDelta())); @@ -1591,7 +1610,7 @@ RunGenerateBidWithReturnValueExpectingResult( kGenerateBidBody, mojom::BidderWorkletBid::New( - "null", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "null", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta())); @@ -1604,7 +1623,7 @@ RunGenerateBidWithReturnValueExpectingResult( kGenerateBidBody, mojom::BidderWorkletBid::New( - "null", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "null", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/4095, base::TimeDelta())); @@ -1964,7 +1983,7 @@ RunGenerateBidWithReturnValueExpectingResult( R"({ad: interestGroup.owner, bid:1, render:"https://response.test/"})", mojom::BidderWorkletBid::New( - R"("https://foo.test")", 1, blink::kUnspecifiedAdCurrency, + R"("https://foo.test")", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -1974,7 +1993,7 @@ RunGenerateBidWithReturnValueExpectingResult( R"({ad: interestGroup.owner, bid:1, render:"https://response.test/"})", mojom::BidderWorkletBid::New( - R"("https://[::1]:40000")", 1, blink::kUnspecifiedAdCurrency, + R"("https://[::1]:40000")", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -1989,7 +2008,7 @@ RunGenerateBidWithReturnValueExpectingResult( kGenerateBidBody, mojom::BidderWorkletBid::New( - R"("foo")", 1, blink::kUnspecifiedAdCurrency, + R"("foo")", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -1999,7 +2018,7 @@ RunGenerateBidWithReturnValueExpectingResult( kGenerateBidBody, mojom::BidderWorkletBid::New( - R"("\"foo\"")", 1, blink::kUnspecifiedAdCurrency, + R"("\"foo\"")", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -2009,7 +2028,7 @@ RunGenerateBidWithReturnValueExpectingResult( kGenerateBidBody, mojom::BidderWorkletBid::New( - R"("[1]")", 1, blink::kUnspecifiedAdCurrency, + R"("[1]")", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -2057,7 +2076,7 @@ RunGenerateBidWithReturnValueExpectingResult( kGenerateBidBody, mojom::BidderWorkletBid::New( - R"("https://url.test/")", 1, blink::kUnspecifiedAdCurrency, + R"("https://url.test/")", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -2067,7 +2086,7 @@ RunGenerateBidWithReturnValueExpectingResult( kGenerateBidBody, mojom::BidderWorkletBid::New( - R"("https://url.test/foo")", 1, blink::kUnspecifiedAdCurrency, + R"("https://url.test/foo")", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -2084,7 +2103,7 @@ RunGenerateBidWithReturnValueExpectingResult( kGenerateBidBody, mojom::BidderWorkletBid::New( - R"("missing")", 1, blink::kUnspecifiedAdCurrency, + R"("missing")", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -2096,7 +2115,8 @@ RunGenerateBidWithReturnValueExpectingResult( kGenerateBidBody, mojom::BidderWorkletBid::New( - R"("https://foo.test/helper.wasm")", 1, blink::kUnspecifiedAdCurrency, + R"("https://foo.test/helper.wasm")", 1, + /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -2121,7 +2141,7 @@ RunGenerateBidWithReturnValueExpectingResult( kGenerateBidBody, mojom::BidderWorkletBid::New( - R"("missing")", 1, blink::kUnspecifiedAdCurrency, + R"("missing")", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -2129,7 +2149,7 @@ RunGenerateBidWithReturnValueExpectingResult( kGenerateBidBodyUsingDeprecatedDailyUpdateUrl, mojom::BidderWorkletBid::New( - R"("missing")", 1, blink::kUnspecifiedAdCurrency, + R"("missing")", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -2140,7 +2160,7 @@ kGenerateBidBody, mojom::BidderWorkletBid::New( R"("https://url.test/daily_update")", 1, - blink::kUnspecifiedAdCurrency, + /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -2149,7 +2169,7 @@ kGenerateBidBodyUsingDeprecatedDailyUpdateUrl, mojom::BidderWorkletBid::New( R"("https://url.test/daily_update")", 1, - blink::kUnspecifiedAdCurrency, + /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -2166,7 +2186,7 @@ RunGenerateBidWithReturnValueExpectingResult( kGenerateBidBody, mojom::BidderWorkletBid::New( - R"("missing")", 1, blink::kUnspecifiedAdCurrency, + R"("missing")", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -2185,7 +2205,7 @@ kGenerateBidBody, mojom::BidderWorkletBid::New( R"("https://signals.test/foo.json")", 1, - blink::kUnspecifiedAdCurrency, + /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -2202,7 +2222,7 @@ RunGenerateBidWithReturnValueExpectingResult( kGenerateBidBody, mojom::BidderWorkletBid::New( - R"("missing")", 1, blink::kUnspecifiedAdCurrency, + R"("missing")", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -2213,7 +2233,7 @@ RunGenerateBidWithReturnValueExpectingResult( kGenerateBidBody, mojom::BidderWorkletBid::New( - R"([])", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + R"([])", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta())); @@ -2224,7 +2244,7 @@ RunGenerateBidWithReturnValueExpectingResult( kGenerateBidBody, mojom::BidderWorkletBid::New( - R"(["2","1","3"])", 1, blink::kUnspecifiedAdCurrency, + R"(["2","1","3"])", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -2243,7 +2263,7 @@ RunGenerateBidWithReturnValueExpectingResult( kGenerateBidBody, mojom::BidderWorkletBid::New( - "null", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "null", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta())); @@ -2252,7 +2272,7 @@ RunGenerateBidWithReturnValueExpectingResult( kGenerateBidBody, mojom::BidderWorkletBid::New( - R"("foo")", 1, blink::kUnspecifiedAdCurrency, + R"("foo")", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -2262,7 +2282,7 @@ RunGenerateBidWithReturnValueExpectingResult( kGenerateBidBody, mojom::BidderWorkletBid::New( - "[1]", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "[1]", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta())); @@ -2271,7 +2291,7 @@ RunGenerateBidWithReturnValueExpectingResult( R"({ad: interestGroup.userBiddingSignals === undefined, bid:1, render:"https://response.test/"})", mojom::BidderWorkletBid::New( - "true", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "true", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta())); @@ -3015,7 +3035,7 @@ RunGenerateBidWithReturnValueExpectingResult( kGenerateBidBody, mojom::BidderWorkletBid::New( - R"("foo")", 1, blink::kUnspecifiedAdCurrency, + R"("foo")", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -3025,7 +3045,7 @@ RunGenerateBidWithReturnValueExpectingResult( kGenerateBidBody, mojom::BidderWorkletBid::New( - "[1]", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "[1]", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta())); @@ -3045,7 +3065,7 @@ RunGenerateBidWithReturnValueExpectingResult( kGenerateBidBody, mojom::BidderWorkletBid::New( - R"("foo")", 1, blink::kUnspecifiedAdCurrency, + R"("foo")", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -3055,7 +3075,7 @@ RunGenerateBidWithReturnValueExpectingResult( kGenerateBidBody, mojom::BidderWorkletBid::New( - "[1]", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "[1]", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta())); @@ -3064,7 +3084,7 @@ RunGenerateBidWithReturnValueExpectingResult( R"({ad: perBuyerSignals === null, bid:1, render:"https://response.test/"})", mojom::BidderWorkletBid::New( - "true", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "true", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta())); @@ -3076,7 +3096,7 @@ RunGenerateBidWithReturnValueExpectingResult( R"({ad: browserSignals.seller, bid:1, render:"https://response.test/"})", mojom::BidderWorkletBid::New( - R"("https://foo.test")", 1, blink::kUnspecifiedAdCurrency, + R"("https://foo.test")", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -3087,7 +3107,7 @@ RunGenerateBidWithReturnValueExpectingResult( R"({ad: browserSignals.seller, bid:1, render:"https://response.test/"})", mojom::BidderWorkletBid::New( - R"("https://[::1]:40000")", 1, blink::kUnspecifiedAdCurrency, + R"("https://[::1]:40000")", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -3101,7 +3121,7 @@ bid:1, render:"https://response.test/"})", mojom::BidderWorkletBid::New( - "false", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "false", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta())); @@ -3114,7 +3134,7 @@ R"({ad: browserSignals.topLevelSeller, bid:1, render:"https://response.test/", allowComponentAuction: true})", mojom::BidderWorkletBid::New( - R"("https://foo.test")", 1, blink::kUnspecifiedAdCurrency, + R"("https://foo.test")", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -3126,7 +3146,7 @@ RunGenerateBidWithReturnValueExpectingResult( R"({ad: browserSignals.topWindowHostname, bid:1, render:"https://response.test/"})", mojom::BidderWorkletBid::New( - R"("top.window.test")", 1, blink::kUnspecifiedAdCurrency, + R"("top.window.test")", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -3152,7 +3172,7 @@ R"({ad: %s, bid:1, render:"https://response.test/"})", test_case.name), mojom::BidderWorkletBid::New( - "0", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "0", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta())); @@ -3163,7 +3183,7 @@ R"({ad: %s, bid:1, render:"https://response.test/"})", test_case.name), mojom::BidderWorkletBid::New( - "10", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "10", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta())); @@ -3190,7 +3210,7 @@ "[{\"renderUrl\":\"https://response.test/\"}," "{\"renderUrl\":\"https://response2.test/" "\",\"metadata\":[\"metadata\"]}]", - 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response2.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta())); @@ -3199,7 +3219,7 @@ RunGenerateBidWithReturnValueExpectingResult( R"({ad: interestGroup.ads[1].metadata[0], bid:1, render:"https://response.test/"})", mojom::BidderWorkletBid::New( - "\"metadata\"", 1, blink::kUnspecifiedAdCurrency, + "\"metadata\"", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -3211,7 +3231,7 @@ RunGenerateBidWithReturnValueExpectingResult( R"({ad: 0, bid:1, render:"https://response.test/", adComponents:["https://ad_component.test/"]})", mojom::BidderWorkletBid::New( - "0", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "0", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), std::vector<blink::AdDescriptor>{ blink::AdDescriptor(GURL("https://ad_component.test/"))}, @@ -3220,7 +3240,7 @@ RunGenerateBidWithReturnValueExpectingResult( R"({ad: 0, bid:1, render:"https://response.test/", adComponents:[]})", mojom::BidderWorkletBid::New( - "0", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "0", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), std::vector<blink::AdDescriptor>(), /*modeling_signals=*/absl::nullopt, base::TimeDelta())); @@ -3248,7 +3268,7 @@ "[{\"renderUrl\":\"https://ad_component.test/\"}," "{\"renderUrl\":\"https://ad_component2.test/" "\",\"metadata\":[\"metadata\"]}]", - 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), std::vector<blink::AdDescriptor>{ blink::AdDescriptor(GURL("https://ad_component.test/")), @@ -3261,7 +3281,7 @@ TEST_F(BidderWorkletTest, GenerateBidAllowComponentAuction) { // In all success cases, this is the returned bid. const auto kBidOnSuccess = mojom::BidderWorkletBid::New( - "null", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "null", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta()); @@ -3377,7 +3397,7 @@ RunGenerateBidWithJavascriptExpectingResult( bid_script, mojom::BidderWorkletBid::New( R"([{"name":"test_const","kind":"global"}])", 1, - blink::kUnspecifiedAdCurrency, + /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -3405,7 +3425,8 @@ direct_from_seller_per_buyer_signals_, direct_from_seller_auction_signals_, seller_signals_, browser_signal_render_url_, browser_signal_bid_, - browser_signal_highest_scoring_other_bid_, + browser_signal_bid_currency_, browser_signal_highest_scoring_other_bid_, + browser_signal_highest_scoring_other_bid_currency_, browser_signal_made_highest_scoring_other_bid_, browser_signal_ad_cost_, browser_signal_modeling_signals_, browser_signal_join_count_, browser_signal_recency_, browser_signal_seller_origin_, @@ -3616,7 +3637,7 @@ R"({ad: %s, bid:1, render:"https://response.test/"})", test_case.ad), mojom::BidderWorkletBid::New( - test_case.expected_ad, 1, blink::kUnspecifiedAdCurrency, + test_case.expected_ad, 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -3649,7 +3670,7 @@ RunGenerateBidWithReturnValueExpectingResult( R"({ad: trustedBiddingSignals, bid:1, render:"https://response.test/"})", mojom::BidderWorkletBid::New( - "null", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "null", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta())); @@ -3662,7 +3683,7 @@ RunGenerateBidWithReturnValueExpectingResult( R"({ad: trustedBiddingSignals, bid:1, render:"https://response.test/"})", mojom::BidderWorkletBid::New( - "null", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "null", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta())); @@ -3677,7 +3698,7 @@ RunGenerateBidWithReturnValueExpectingResult( R"({ad: trustedBiddingSignals, bid:1, render:"https://response.test/"})", mojom::BidderWorkletBid::New( - "null", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "null", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta())); @@ -3690,7 +3711,7 @@ RunGenerateBidWithReturnValueExpectingResult( R"({ad: trustedBiddingSignals, bid:1, render:"https://response.test/"})", mojom::BidderWorkletBid::New( - "null", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "null", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta())); @@ -3706,7 +3727,7 @@ RunGenerateBidWithReturnValueExpectingResult( R"({ad: trustedBiddingSignals, bid:1, render:"https://response.test/"})", mojom::BidderWorkletBid::New( - "null", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "null", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta()), @@ -3723,7 +3744,7 @@ RunGenerateBidWithReturnValueExpectingResult( R"({ad: trustedBiddingSignals, bid:1, render:"https://response.test/"})", mojom::BidderWorkletBid::New( - R"({"key1":1,"key2":[2]})", 1, blink::kUnspecifiedAdCurrency, + R"({"key1":1,"key2":[2]})", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -3755,7 +3776,7 @@ RunGenerateBidWithReturnValueExpectingResult( R"({ad: trustedBiddingSignals, bid:1, render:"https://response.test/"})", mojom::BidderWorkletBid::New( - R"({"key1":1,"key2":[2]})", 1, blink::kUnspecifiedAdCurrency, + R"({"key1":1,"key2":[2]})", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -4043,7 +4064,7 @@ RunGenerateBidWithReturnValueExpectingResult( R"({ad: "ad", bid:browserSignals.dataVersion, render:"https://response.test/"})", mojom::BidderWorkletBid::New( - R"("ad")", 7, blink::kUnspecifiedAdCurrency, + R"("ad")", 7, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -4062,7 +4083,7 @@ RunGenerateBidWithReturnValueExpectingResult( R"({ad: "ad", bid:browserSignals.dataVersion, render:"https://response.test/"})", mojom::BidderWorkletBid::New( - R"("ad")", 7, blink::kUnspecifiedAdCurrency, + R"("ad")", 7, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -4085,7 +4106,7 @@ )"), /*expected_bid=*/ mojom::BidderWorkletBid::New( - "\"returned\"", 2, blink::kUnspecifiedAdCurrency, + "\"returned\"", 2, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/replacement")), /*ad_component_descriptors=*/absl::nullopt, @@ -4117,7 +4138,7 @@ RunGenerateBidWithReturnValueExpectingResult( R"({ad: "ad", bid:123, render:"https://response.test/"})", mojom::BidderWorkletBid::New( - R"("ad")", 123, blink::kUnspecifiedAdCurrency, + R"("ad")", 123, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -4174,7 +4195,8 @@ )"), /*expected_bid=*/ mojom::BidderWorkletBid::New( - "\"ad\"", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "\"ad\"", 1, /*bid_currency=*/absl::nullopt, + /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, AuctionV8Helper::kScriptTimeout), @@ -4225,7 +4247,7 @@ )"), /*expected_bid=*/ mojom::BidderWorkletBid::New( - "\"ad2\"", 2, blink::kUnspecifiedAdCurrency, + "\"ad2\"", 2, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/replacement")), /*ad_component_descriptors=*/absl::nullopt, @@ -4287,7 +4309,8 @@ )"), /*expected_bid=*/ mojom::BidderWorkletBid::New( - "\"ad\"", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "\"ad\"", 1, /*bid_currency=*/absl::nullopt, + /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta()), @@ -4350,7 +4373,8 @@ )"), /*expected_bid=*/ mojom::BidderWorkletBid::New( - "\"ad\"", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "\"ad\"", 1, /*bid_currency=*/absl::nullopt, + /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta()), @@ -4441,7 +4465,7 @@ )"), /*expected_bid=*/ mojom::BidderWorkletBid::New( - "null", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "null", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta()), @@ -4460,7 +4484,7 @@ )"), /*expected_bid=*/ mojom::BidderWorkletBid::New( - "null", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "null", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta()), @@ -4479,7 +4503,7 @@ )"), /*expected_bid=*/ mojom::BidderWorkletBid::New( - "null", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "null", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta()), @@ -4498,7 +4522,7 @@ )"), /*expected_bid=*/ mojom::BidderWorkletBid::New( - "null", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "null", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta()), @@ -4520,7 +4544,7 @@ )"), /*expected_bid=*/ mojom::BidderWorkletBid::New( - "null", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "null", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta()), @@ -4541,7 +4565,7 @@ )"), /*expected_bid=*/ mojom::BidderWorkletBid::New( - "null", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "null", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta()), @@ -4633,7 +4657,7 @@ CreateBasicGenerateBidScriptWithDebuggingReport( R"(forDebuggingOnly.reportAdAuctionLoss("https://loss.url"))"), mojom::BidderWorkletBid::New( - "[\"ad\"]", 1, blink::kUnspecifiedAdCurrency, + "[\"ad\"]", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -4643,7 +4667,7 @@ CreateBasicGenerateBidScriptWithDebuggingReport( R"(forDebuggingOnly.reportAdAuctionWin("https://win.url"))"), mojom::BidderWorkletBid::New( - "[\"ad\"]", 1, blink::kUnspecifiedAdCurrency, + "[\"ad\"]", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -4663,7 +4687,8 @@ direct_from_seller_per_buyer_signals_, direct_from_seller_auction_signals_, seller_signals_, browser_signal_render_url_, browser_signal_bid_, - browser_signal_highest_scoring_other_bid_, + browser_signal_bid_currency_, browser_signal_highest_scoring_other_bid_, + browser_signal_highest_scoring_other_bid_currency_, browser_signal_made_highest_scoring_other_bid_, browser_signal_ad_cost_, browser_signal_modeling_signals_, browser_signal_join_count_, browser_signal_recency_, browser_signal_seller_origin_, @@ -4710,7 +4735,9 @@ direct_from_seller_per_buyer_signals_, direct_from_seller_auction_signals_, seller_signals_, browser_signal_render_url_, browser_signal_bid_, + browser_signal_bid_currency_, browser_signal_highest_scoring_other_bid_, + browser_signal_highest_scoring_other_bid_currency_, browser_signal_made_highest_scoring_other_bid_, browser_signal_ad_cost_, browser_signal_modeling_signals_, browser_signal_join_count_, browser_signal_recency_, @@ -4759,7 +4786,8 @@ direct_from_seller_per_buyer_signals_, direct_from_seller_auction_signals_, seller_signals_, browser_signal_render_url_, browser_signal_bid_, - browser_signal_highest_scoring_other_bid_, + browser_signal_bid_currency_, browser_signal_highest_scoring_other_bid_, + browser_signal_highest_scoring_other_bid_currency_, browser_signal_made_highest_scoring_other_bid_, browser_signal_ad_cost_, browser_signal_modeling_signals_, browser_signal_join_count_, browser_signal_recency_, browser_signal_seller_origin_, @@ -4961,6 +4989,36 @@ GURL("https://jumboshrimp.test")); } +TEST_F(BidderWorkletTest, ReportWinBrowserSignalBidCurrency) { + browser_signal_bid_currency_ = absl::nullopt; + RunReportWinWithFunctionBodyExpectingResult( + R"(if (browserSignals.bidCurrency === "???") + sendReportTo("https://jumboshrimp.test"))", + GURL("https://jumboshrimp.test")); + + browser_signal_bid_currency_ = blink::AdCurrency::From("USD"); + RunReportWinWithFunctionBodyExpectingResult( + R"(if (browserSignals.bidCurrency === "USD") + sendReportTo("https://jumboshrimp.test"))", + GURL("https://jumboshrimp.test")); +} + +TEST_F(BidderWorkletTest, + ReportWinBrowserSignalHighestScoringOtherBidCurrency) { + browser_signal_highest_scoring_other_bid_currency_ = + blink::AdCurrency::From("CAD"); + RunReportWinWithFunctionBodyExpectingResult( + R"(if (browserSignals.highestScoringOtherBidCurrency === "CAD") + sendReportTo("https://jumboshrimp.test"))", + GURL("https://jumboshrimp.test")); + + browser_signal_highest_scoring_other_bid_currency_ = absl::nullopt; + RunReportWinWithFunctionBodyExpectingResult( + R"(if (browserSignals.highestScoringOtherBidCurrency === "???") + sendReportTo("https://jumboshrimp.test"))", + GURL("https://jumboshrimp.test")); +} + TEST_F(BidderWorkletTest, ReportWinBrowserSignalIsHighestScoringOtherBidMe) { browser_signal_made_highest_scoring_other_bid_ = true; RunReportWinWithFunctionBodyExpectingResult( @@ -5068,7 +5126,8 @@ direct_from_seller_per_buyer_signals_, direct_from_seller_auction_signals_, seller_signals_, browser_signal_render_url_, browser_signal_bid_, - browser_signal_highest_scoring_other_bid_, + browser_signal_bid_currency_, browser_signal_highest_scoring_other_bid_, + browser_signal_highest_scoring_other_bid_currency_, browser_signal_made_highest_scoring_other_bid_, browser_signal_ad_cost_, browser_signal_modeling_signals_, browser_signal_join_count_, browser_signal_recency_, browser_signal_seller_origin_, @@ -5826,7 +5885,8 @@ direct_from_seller_per_buyer_signals_, direct_from_seller_auction_signals_, seller_signals_, browser_signal_render_url_, browser_signal_bid_, - browser_signal_highest_scoring_other_bid_, + browser_signal_bid_currency_, browser_signal_highest_scoring_other_bid_, + browser_signal_highest_scoring_other_bid_currency_, browser_signal_made_highest_scoring_other_bid_, browser_signal_ad_cost_, browser_signal_modeling_signals_, browser_signal_join_count_, browser_signal_recency_, browser_signal_seller_origin_, @@ -5896,7 +5956,7 @@ R"(forDebuggingOnly.reportAdAuctionLoss("https://loss.url"); forDebuggingOnly.reportAdAuctionWin("https://win.url"))"), mojom::BidderWorkletBid::New( - "[\"ad\"]", 1, blink::kUnspecifiedAdCurrency, + "[\"ad\"]", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -5910,7 +5970,7 @@ CreateBasicGenerateBidScriptWithDebuggingReport( R"(forDebuggingOnly.reportAdAuctionLoss("https://loss.url"))"), mojom::BidderWorkletBid::New( - "[\"ad\"]", 1, blink::kUnspecifiedAdCurrency, + "[\"ad\"]", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -5922,7 +5982,7 @@ CreateBasicGenerateBidScriptWithDebuggingReport( R"(forDebuggingOnly.reportAdAuctionWin("https://win.url"))"), mojom::BidderWorkletBid::New( - "[\"ad\"]", 1, blink::kUnspecifiedAdCurrency, + "[\"ad\"]", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -5976,7 +6036,7 @@ R"(try {forDebuggingOnly.reportAdAuctionLoss("http://loss.url")} catch (e) {})"), mojom::BidderWorkletBid::New( - "[\"ad\"]", 1, blink::kUnspecifiedAdCurrency, + "[\"ad\"]", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -5993,7 +6053,7 @@ R"(forDebuggingOnly.reportAdAuctionLoss("https://loss.url"); forDebuggingOnly.reportAdAuctionLoss("https://loss.url2"))"), mojom::BidderWorkletBid::New( - "[\"ad\"]", 1, blink::kUnspecifiedAdCurrency, + "[\"ad\"]", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -6007,7 +6067,7 @@ R"(forDebuggingOnly.reportAdAuctionWin("https://win.url"); forDebuggingOnly.reportAdAuctionWin("https://win.url2"))"), mojom::BidderWorkletBid::New( - "[\"ad\"]", 1, blink::kUnspecifiedAdCurrency, + "[\"ad\"]", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -6247,7 +6307,7 @@ )"), /*expected_bid=*/ mojom::BidderWorkletBid::New( - "\"ad\"", 1, blink::kUnspecifiedAdCurrency, + "\"ad\"", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -6465,7 +6525,7 @@ )"), /*expected_bid=*/ mojom::BidderWorkletBid::New( - "\"ad\"", 1, blink::kUnspecifiedAdCurrency, + "\"ad\"", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -6493,7 +6553,7 @@ )"), /*expected_bid=*/ mojom::BidderWorkletBid::New( - "\"ad\"", 1, blink::kUnspecifiedAdCurrency, + "\"ad\"", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -6523,7 +6583,7 @@ )"), /*expected_bid=*/ mojom::BidderWorkletBid::New( - "\"ad\"", 1, blink::kUnspecifiedAdCurrency, + "\"ad\"", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -6584,7 +6644,7 @@ )"), /*expected_bid=*/ mojom::BidderWorkletBid::New( - "\"ad\"", 1, blink::kUnspecifiedAdCurrency, + "\"ad\"", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -6620,7 +6680,7 @@ )"), /*expected_bid=*/ mojom::BidderWorkletBid::New( - "\"ad\"", 1, blink::kUnspecifiedAdCurrency, + "\"ad\"", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -6688,7 +6748,7 @@ )"), /*expected_bid=*/ mojom::BidderWorkletBid::New( - "\"ad\"", 1, blink::kUnspecifiedAdCurrency, + "\"ad\"", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -6729,7 +6789,7 @@ )"), /*expected_bid=*/ mojom::BidderWorkletBid::New( - "\"ad\"", 1, blink::kUnspecifiedAdCurrency, + "\"ad\"", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -6810,7 +6870,7 @@ )"), /*expected_bid=*/ mojom::BidderWorkletBid::New( - "\"ad\"", 1, blink::kUnspecifiedAdCurrency, + "\"ad\"", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -7090,7 +7150,7 @@ R"({ad: ["ad"], bid:1, render:"https://response.test/"})", kSideEffectScript), mojom::BidderWorkletBid::New( - R"(["ad"])", 1, blink::kUnspecifiedAdCurrency, + R"(["ad"])", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -7113,7 +7173,7 @@ R"({ad: ["ad"], bid:1, render:"https://response.test/"})", kSideEffectScript), mojom::BidderWorkletBid::New( - R"(["ad"])", 1, blink::kUnspecifiedAdCurrency, + R"(["ad"])", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -7138,7 +7198,7 @@ render:interestGroup.ads[interestGroup.ads.length - 1].renderUrl})", kSideEffectScript), mojom::BidderWorkletBid::New( - R"(["ad"])", 2, blink::kUnspecifiedAdCurrency, + R"(["ad"])", 2, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response2.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -7168,7 +7228,7 @@ render:interestGroup.ads[interestGroup.ads.length - 1].renderUrl})", kSideEffectScript), mojom::BidderWorkletBid::New( - R"(["ad"])", 2, blink::kUnspecifiedAdCurrency, + R"(["ad"])", 2, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response2.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -7204,7 +7264,7 @@ kSideEffectScript), /*expected_bid=*/ mojom::BidderWorkletBid::New( - R"(["ad"])", 1, blink::kUnspecifiedAdCurrency, + R"(["ad"])", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -7229,7 +7289,7 @@ R"({ad: ["ad"], bid:1, render:"https://response.test/"})", kSideEffectScript), mojom::BidderWorkletBid::New( - R"(["ad"])", 1, blink::kUnspecifiedAdCurrency, + R"(["ad"])", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -7254,7 +7314,7 @@ render:interestGroup.ads[interestGroup.ads.length - 1].renderUrl})", kSideEffectScript), mojom::BidderWorkletBid::New( - R"(["ad"])", 2, blink::kUnspecifiedAdCurrency, + R"(["ad"])", 2, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response2.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -7284,7 +7344,7 @@ render:interestGroup.ads[interestGroup.ads.length - 1].renderUrl})", kSideEffectScript), mojom::BidderWorkletBid::New( - R"(["ad"])", 2, blink::kUnspecifiedAdCurrency, + R"(["ad"])", 2, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response2.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -7327,7 +7387,7 @@ SCOPED_TRACE(execution_mode_); RunGenerateBidWithJavascriptExpectingResult( kScript, mojom::BidderWorkletBid::New( - R"(["ad"])", 1, blink::kUnspecifiedAdCurrency, + R"(["ad"])", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response2.test/")), /*ad_component_descriptors=*/absl::nullopt, @@ -7547,7 +7607,8 @@ RunGenerateBidWithReturnValueExpectingResult( R"({ad: "ad", bid: 1, render: {url: "https://response.test/"}})", /*expected_bid=*/mojom::BidderWorkletBid::New( - "\"ad\"", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "\"ad\"", 1, /*bid_currency=*/absl::nullopt, + /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), /*ad_component_descriptors=*/absl::nullopt, /*modeling_signals=*/absl::nullopt, base::TimeDelta())); @@ -7565,7 +7626,8 @@ } })", /*expected_bid=*/mojom::BidderWorkletBid::New( - "\"ad\"", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "\"ad\"", 1, /*bid_currency=*/absl::nullopt, + /*ad_cost=*/absl::nullopt, blink::AdDescriptor( GURL("https://response.test/"), blink::AdSize(100, blink::AdSize::LengthUnit::kScreenWidth, 50, @@ -7757,7 +7819,7 @@ ] })", /*expected_bid=*/mojom::BidderWorkletBid::New( - "0", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "0", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), std::vector<blink::AdDescriptor>{ blink::AdDescriptor(GURL("https://ad_component.test/"))}, @@ -7779,7 +7841,7 @@ ] })", /*expected_bid=*/mojom::BidderWorkletBid::New( - "0", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "0", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), std::vector<blink::AdDescriptor>{blink::AdDescriptor( GURL("https://ad_component.test/"), @@ -7805,7 +7867,7 @@ ] })", /*expected_bid=*/mojom::BidderWorkletBid::New( - "0", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "0", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), std::vector<blink::AdDescriptor>{ blink::AdDescriptor( @@ -7834,7 +7896,7 @@ ] })", /*expected_bid=*/mojom::BidderWorkletBid::New( - "0", 1, blink::kUnspecifiedAdCurrency, /*ad_cost=*/absl::nullopt, + "0", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, blink::AdDescriptor(GURL("https://response.test/")), std::vector<blink::AdDescriptor>{ blink::AdDescriptor(
diff --git a/content/services/auction_worklet/context_recycler_unittest.cc b/content/services/auction_worklet/context_recycler_unittest.cc index 6c75ab70..144734c 100644 --- a/content/services/auction_worklet/context_recycler_unittest.cc +++ b/content/services/auction_worklet/context_recycler_unittest.cc
@@ -322,7 +322,7 @@ context_recycler.set_bid_bindings()->ReInitialize( base::TimeTicks::Now(), /*has_top_level_seller_origin=*/false, params.get(), - blink::kUnspecifiedAdCurrency, + /*per_buyer_currency=*/absl::nullopt, /*is_ad_excluded=*/ignore_arg_return_false, /*is_component_ad_excluded=*/ignore_arg_return_false); @@ -357,7 +357,7 @@ context_recycler.set_bid_bindings()->ReInitialize( base::TimeTicks::Now(), /*has_top_level_seller_origin=*/false, params.get(), - blink::kUnspecifiedAdCurrency, + /*per_buyer_currency=*/absl::nullopt, /*is_ad_excluded=*/ignore_arg_return_false, /*is_component_ad_excluded=*/ignore_arg_return_false); @@ -396,7 +396,7 @@ context_recycler.set_bid_bindings()->ReInitialize( base::TimeTicks::Now(), /*has_top_level_seller_origin=*/true, params.get(), - blink::kUnspecifiedAdCurrency, + /*per_buyer_currency=*/absl::nullopt, /*is_ad_excluded=*/ignore_arg_return_false, /*is_component_ad_excluded=*/ignore_arg_return_false); @@ -437,7 +437,7 @@ context_recycler.set_bid_bindings()->ReInitialize( base::TimeTicks::Now(), /*has_top_level_seller_origin=*/true, params.get(), - blink::kUnspecifiedAdCurrency, + /*per_buyer_currency=*/absl::nullopt, /*is_ad_excluded=*/ignore_arg_return_false, /*is_component_ad_excluded=*/ignore_arg_return_false); @@ -491,7 +491,7 @@ context_recycler.set_bid_bindings()->ReInitialize( base::TimeTicks::Now(), /*has_top_level_seller_origin=*/false, params.get(), - blink::kUnspecifiedAdCurrency, + /*per_buyer_currency=*/absl::nullopt, /*is_ad_excluded=*/ignore_arg_return_false, /*is_component_ad_excluded=*/ignore_arg_return_false); @@ -533,7 +533,7 @@ context_recycler.set_bid_bindings()->ReInitialize( base::TimeTicks::Now(), /*has_top_level_seller_origin=*/false, params.get(), - blink::kUnspecifiedAdCurrency, + /*per_buyer_currency=*/absl::nullopt, /*is_ad_excluded=*/matches_ad1, /*is_component_ad_excluded=*/matches_ad1); @@ -566,7 +566,7 @@ context_recycler.set_bid_bindings()->ReInitialize( base::TimeTicks::Now(), /*has_top_level_seller_origin=*/false, params.get(), - blink::kUnspecifiedAdCurrency, + /*per_buyer_currency=*/absl::nullopt, /*is_ad_excluded=*/matches_ad1, /*is_component_ad_excluded=*/matches_ad1); @@ -600,7 +600,8 @@ context_recycler.set_bid_bindings()->ReInitialize( base::TimeTicks::Now(), - /*has_top_level_seller_origin=*/false, params.get(), "USD", + /*has_top_level_seller_origin=*/false, params.get(), + blink::AdCurrency::From("USD"), /*is_ad_excluded=*/matches_ad1, /*is_component_ad_excluded=*/matches_ad1); @@ -619,7 +620,8 @@ context_recycler.set_bid_bindings()->TakeBid(); EXPECT_EQ("https://example.com/ad2", bid->ad_descriptor.url); EXPECT_EQ(10.0, bid->bid); - EXPECT_EQ("USD", bid->bid_currency); + ASSERT_TRUE(bid->bid_currency.has_value()); + EXPECT_EQ("USD", bid->bid_currency->currency_code()); } { @@ -633,7 +635,8 @@ context_recycler.set_bid_bindings()->ReInitialize( base::TimeTicks::Now(), - /*has_top_level_seller_origin=*/false, params.get(), "CAD", + /*has_top_level_seller_origin=*/false, params.get(), + blink::AdCurrency::From("CAD"), /*is_ad_excluded=*/matches_ad1, /*is_component_ad_excluded=*/matches_ad1);
diff --git a/content/services/auction_worklet/public/mojom/bidder_worklet.mojom b/content/services/auction_worklet/public/mojom/bidder_worklet.mojom index f9e7edb3..8a678b64 100644 --- a/content/services/auction_worklet/public/mojom/bidder_worklet.mojom +++ b/content/services/auction_worklet/public/mojom/bidder_worklet.mojom
@@ -95,9 +95,8 @@ // Offered bid value. Always greater than 0. double bid; - // Currency for the bid. Always either a 3-character uppercase ASCII string, - // or blink::kUnspecifiedAdCurrency. - string bid_currency; + // Currency for the bid. + blink.mojom.AdCurrency? bid_currency; // 'adCost' returned by generateBid, if any. double? ad_cost; @@ -273,7 +272,6 @@ // as the one specified `interest_group`. // // `expected_buyer_currency` Currency restriction specified for this buyer. - // Either a currency code or blink::kUnspecifiedAdCurrency. // // `per_buyer_timeout` Restrict the runtime of particular buyer's bidding // scripts. Any timeout higher than 500 ms will be clamped to 500 ms before @@ -287,7 +285,7 @@ string? auction_signals_json, string? per_buyer_signals_json, mojo_base.mojom.TimeDelta? per_buyer_timeout, - string expected_buyer_currency, + blink.mojom.AdCurrency? expected_buyer_currency, url.mojom.Url? direct_from_seller_per_buyer_signals, url.mojom.Url? direct_from_seller_auction_signals); }; @@ -431,10 +429,22 @@ // BidderWorklet's generateBid() method, invoked as part of BidderWorklet // creation. // - // `browser_signal_bid` The numeric value of the winning bid. + // `browser_signal_bid` The numeric value of the winning bid. This is always + // in the bidder's own currency. + // + // `browser_signal_bid_currency` Currency for the winning bid. + // The client should redact the currency if it's not guaranteed by the + // auction configuration to avoid leaking information. // // `browser_signal_highest_scoring_other_bid` The numeric value of the bid - // that got the second highest score. + // that got the second highest score, or 0 if it's not available, either + // because there is no such thing or because sellerCurrency is enabled, and + // the relevant bid was in a different currency without scoreAd providing + // a conversion for it. + // + // `browser_signal_highest_scoring_other_bid_currency` The currency associated + // with `browser_signal_highest_scoring_other_bid`. If a concrete value is + // provided, it's always the sellerCurrency for the auction. // // `browser_signal_made_highest_scoring_other_bid` True only if owner of // the interest group that ReportWin() is being invoked on behalf of made @@ -488,7 +498,9 @@ string seller_signals_json, url.mojom.Url browser_signal_render_url, double browser_signal_bid, + blink.mojom.AdCurrency? browser_signal_bid_currency, double browser_signal_highest_scoring_other_bid, + blink.mojom.AdCurrency? browser_signal_highest_scoring_other_bid_currency, bool browser_signal_made_highest_scoring_other_bid, double? browser_signal_ad_cost, uint16? browser_signal_modeling_signals,
diff --git a/content/services/auction_worklet/public/mojom/seller_worklet.mojom b/content/services/auction_worklet/public/mojom/seller_worklet.mojom index 23b3281..a05f07e 100644 --- a/content/services/auction_worklet/public/mojom/seller_worklet.mojom +++ b/content/services/auction_worklet/public/mojom/seller_worklet.mojom
@@ -32,7 +32,7 @@ // Bid value and currency to send to the top-level seller seller in place of // BidderWorkletBid::bid. Only valid if `has_bid` is true. double bid; - string bid_currency; // currency code or blink::kUnspecifiedAdCurrency. + blink.mojom.AdCurrency? bid_currency; // True to indicate that `bid` has been populated. // TODO(https://crbug.com/657632): Update when optional doubles are supported. @@ -80,6 +80,10 @@ // of 0 indicates either an error running the script, or that the script // indicated the bid should not be used. // + // `bid_in_seller_currency` If present, denotes the conversion of bidder's + // bid to seller's currency. Should be present only when auction + // configuration specifies what the seller currency is. + // // `reject_reason` The reason this bid was rejected by the auction (i.e., the // reason why `score` was non-positive). Default to kNotAvailable if not set. // Will be ignored if `score` is positive. @@ -89,11 +93,7 @@ // in place of values from the original bidder worklet's BidderWorkletBid. // // `scoring_signals_data_version` The value of the Data-Version header served - // with the trusted scoring signals. - // - // `has_scoring_signals_data_version` True to indicate Data-Version header - // was present in the HTTP response for the trusted scoring signals. - // TODO(https://crbug.com/657632): Update when optional integers supported. + // with the trusted scoring signals. nullopt when the header wasn't present. // // `debug_loss_report_url` The URL to request if this bid does not win the // auction. It's requested if the auction runs to completion and this is not @@ -117,8 +117,8 @@ RejectReason reject_reason, ComponentAuctionModifiedBidParams? component_auction_modified_bid_params, - uint32 scoring_signals_data_version, - bool has_scoring_signals_data_version, + double? bid_in_seller_currency, + uint32? scoring_signals_data_version, url.mojom.Url? debug_loss_report_url, url.mojom.Url? debug_win_report_url, array<PrivateAggregationRequest> pa_requests, @@ -149,7 +149,6 @@ // `bid` The numeric value of the bid offered by the BidderWorklet. // // `bid_currency` Currency of the bid offered by the BidderWorklet. - // Either a currency code or blink::kUnspecifiedAdCurrency. // // `auction_ad_config_non_shared_params` Values in an AuctionConfig that can // vary between auctions that can share a SellerWorklet. @@ -175,8 +174,8 @@ // Null if this is the top-level seller scoring its own bids. // // `component_expect_bid_currency` If this is a component auction, specifies - // what currency the top-level auction expects it to provide. Otherwise, - // it's nullopt. + // what currency the top-level auction expects it to provide, if any. + // nullopt for top-level auction. // // `browser_signal_interest_group_owner` The owner of the interest group // that offered the bid. @@ -203,13 +202,13 @@ // OnScoreAdComplete() method will be invoked with the results. ScoreAd(string ad_metadata_json, double bid, - string bid_currency, + blink.mojom.AdCurrency? bid_currency, blink.mojom.AuctionAdConfigNonSharedParams auction_ad_config_non_shared_params, url.mojom.Url? direct_from_seller_seller_signals, url.mojom.Url? direct_from_seller_auction_signals, ComponentAuctionOtherSeller? browser_signals_other_seller, - string? component_expect_bid_currency, + blink.mojom.AdCurrency? component_expect_bid_currency, url.mojom.Origin browser_signal_interest_group_owner, url.mojom.Url browser_signal_render_url, array<url.mojom.Url> browser_signal_ad_component_render_urls, @@ -266,11 +265,22 @@ // // `browser_signal_bid` The numeric value of the winning bid. // + // `browser_signal_bid_currency` The currency the bid is in. This is either + // the sellerCurrency from auction configuration, or unset to denote it's in + // the bidder's currency. + // // `browser_signal_desirability` The score returned by ScoreAd for the // winning bid. // // `browser_signal_highest_scoring_other_bid` The numeric value of the bid - // that got the second highest score. + // that got the second highest score, or 0 if it's not available, either + // because there is no such thing or because no currency conversion was + // performed. + // + // `browser_signal_highest_scoring_other_bid_currency` The currency associated + // with `browser_signal_highest_scoring_other_bid`. This is either the + // sellerCurrency from auction configuration, if it's set, or nullopt to + // denote it's in the bidder's currency. // // `browser_signals_component_auction_report_result_params` Extra parameters // passed to the component auction's ReportResult() method. Should be null @@ -311,8 +321,10 @@ url.mojom.Origin browser_signal_interest_group_owner, url.mojom.Url browser_signal_render_url, double browser_signal_bid, + blink.mojom.AdCurrency? browser_signal_bid_currency, double browser_signal_desirability, double browser_signal_highest_scoring_other_bid, + blink.mojom.AdCurrency? browser_signal_highest_scoring_other_bid_currency, ComponentAuctionReportResultParams? browser_signals_component_auction_report_result_params, uint32 scoring_signals_data_version,
diff --git a/content/services/auction_worklet/seller_worklet.cc b/content/services/auction_worklet/seller_worklet.cc index be07c00..4f73808 100644 --- a/content/services/auction_worklet/seller_worklet.cc +++ b/content/services/auction_worklet/seller_worklet.cc
@@ -138,20 +138,26 @@ if (buyer_currencies.per_buyer_currencies.has_value()) { for (const auto& kv : buyer_currencies.per_buyer_currencies.value()) { - if (!per_buyer_currencies_dict.Set(kv.first.Serialize(), kv.second)) { + if (!per_buyer_currencies_dict.Set(kv.first.Serialize(), + kv.second.currency_code())) { return false; } } } if (buyer_currencies.all_buyers_currency.has_value()) { if (!per_buyer_currencies_dict.Set( - "*", buyer_currencies.all_buyers_currency.value())) { + "*", buyer_currencies.all_buyers_currency->currency_code())) { return false; } } return true; } +// ### some duplication with same in interest_group_auction.cc +bool IsValidBid(double bid) { + return std::isfinite(bid) && (bid > 0.0); +} + // Converts `auction_config` back to JSON format, and appends to args. // Returns true if conversion succeeded. // @@ -287,7 +293,7 @@ if (auction_ad_config_non_shared_params.seller_currency.has_value()) { auction_config_dict.Set( "sellerCurrency", - auction_ad_config_non_shared_params.seller_currency.value()); + auction_ad_config_non_shared_params.seller_currency->currency_code()); } if (auction_ad_config_non_shared_params.per_buyer_priority_signals || @@ -445,13 +451,13 @@ void SellerWorklet::ScoreAd( const std::string& ad_metadata_json, double bid, - const std::string& bid_currency, + const absl::optional<blink::AdCurrency>& bid_currency, const blink::AuctionConfig::NonSharedParams& auction_ad_config_non_shared_params, const absl::optional<GURL>& direct_from_seller_seller_signals, const absl::optional<GURL>& direct_from_seller_auction_signals, mojom::ComponentAuctionOtherSellerPtr browser_signals_other_seller, - const absl::optional<std::string>& component_expect_bid_currency, + const absl::optional<blink::AdCurrency>& component_expect_bid_currency, const url::Origin& browser_signal_interest_group_owner, const GURL& browser_signal_render_url, const std::vector<GURL>& browser_signal_ad_components, @@ -554,8 +560,11 @@ const url::Origin& browser_signal_interest_group_owner, const GURL& browser_signal_render_url, double browser_signal_bid, + const absl::optional<blink::AdCurrency>& browser_signal_bid_currency, double browser_signal_desirability, double browser_signal_highest_scoring_other_bid, + const absl::optional<blink::AdCurrency>& + browser_signal_highest_scoring_other_bid_currency, auction_worklet::mojom::ComponentAuctionReportResultParamsPtr browser_signals_component_auction_report_result_params, uint32_t scoring_signals_data_version, @@ -582,9 +591,13 @@ browser_signal_interest_group_owner; report_result_task->browser_signal_render_url = browser_signal_render_url; report_result_task->browser_signal_bid = browser_signal_bid; + report_result_task->browser_signal_bid_currency = + std::move(browser_signal_bid_currency); report_result_task->browser_signal_desirability = browser_signal_desirability; report_result_task->browser_signal_highest_scoring_other_bid = browser_signal_highest_scoring_other_bid; + report_result_task->browser_signal_highest_scoring_other_bid_currency = + browser_signal_highest_scoring_other_bid_currency; report_result_task->browser_signals_component_auction_report_result_params = std::move(browser_signals_component_auction_report_result_params); report_result_task->trace_id = trace_id; @@ -684,7 +697,7 @@ void SellerWorklet::V8State::ScoreAd( const std::string& ad_metadata_json, double bid, - const std::string& bid_currency, + const absl::optional<blink::AdCurrency>& bid_currency, const blink::AuctionConfig::NonSharedParams& auction_ad_config_non_shared_params, DirectFromSellerSignalsRequester::Result @@ -693,7 +706,7 @@ direct_from_seller_result_auction_signals, scoped_refptr<TrustedSignals::Result> trusted_scoring_signals, mojom::ComponentAuctionOtherSellerPtr browser_signals_other_seller, - const absl::optional<std::string>& component_expect_bid_currency, + const absl::optional<blink::AdCurrency>& component_expect_bid_currency, const url::Origin& browser_signal_interest_group_owner, const GURL& browser_signal_render_url, const std::vector<std::string>& browser_signal_ad_components, @@ -764,7 +777,8 @@ browser_signal_render_url.spec()) || !browser_signals_dict.Set("biddingDurationMsec", browser_signal_bidding_duration_msecs) || - !browser_signals_dict.Set("bidCurrency", bid_currency) || + !browser_signals_dict.Set("bidCurrency", + blink::PrintableAdCurrency(bid_currency)) || (scoring_signals_data_version.has_value() && !browser_signals_dict.Set("dataVersion", scoring_signals_data_version.value()))) { @@ -820,6 +834,7 @@ std::move(callback), /*score=*/0, /*reject_reason=*/mojom::RejectReason::kNotAvailable, /*component_auction_modified_bid_params=*/nullptr, + /*bid_in_seller_currency=*/absl::nullopt, /*scoring_signals_data_version=*/absl::nullopt, /*debug_loss_report_url=*/absl::nullopt, /*debug_win_report_url=*/absl::nullopt, @@ -856,6 +871,7 @@ std::move(callback), /*score=*/0, /*reject_reason=*/mojom::RejectReason::kNotAvailable, /*component_auction_modified_bid_params=*/nullptr, + /*bid_in_seller_currency=*/absl::nullopt, /*scoring_signals_data_version=*/absl::nullopt, /*debug_loss_report_url=*/ context_recycler.for_debugging_only_bindings()->TakeLossReportUrl(), @@ -871,6 +887,7 @@ bool allow_component_auction = false; mojom::ComponentAuctionModifiedBidParamsPtr component_auction_modified_bid_params; + absl::optional<double> bid_in_seller_currency; // Try to parse the result as a number. On success, it's the desirability // score. if (!gin::ConvertFromV8(isolate, score_ad_result, &score)) { @@ -903,6 +920,65 @@ if (!result_dict.Get("allowComponentAuction", &allow_component_auction)) allow_component_auction = false; + // If the bid is already in seller currency, forward it as + // incomingBidInSellerCurrency. + if (bid_currency.has_value() && + auction_ad_config_non_shared_params.seller_currency.has_value() && + bid_currency->currency_code() == + auction_ad_config_non_shared_params.seller_currency + ->currency_code()) { + bid_in_seller_currency = bid; + } + + v8::Local<v8::Value> incoming_bid_in_seller_currency_value; + if (score_ad_object + ->Get(context, v8_helper_->CreateStringFromLiteral( + "incomingBidInSellerCurrency")) + .ToLocal(&incoming_bid_in_seller_currency_value) && + !incoming_bid_in_seller_currency_value->IsUndefined()) { + bool ok = true; + double incoming_bid_in_seller_currency = 0.0; + + if (ok && + !auction_ad_config_non_shared_params.seller_currency.has_value()) { + errors_out.push_back(base::StrCat( + {decision_logic_url_.spec(), + " scoreAd() attempting to set incomingBidInSellerCurrency without " + "a configured sellerCurrency."})); + ok = false; + } + if (ok && + !gin::ConvertFromV8(isolate, incoming_bid_in_seller_currency_value, + &incoming_bid_in_seller_currency)) { + errors_out.push_back(base::StrCat( + {decision_logic_url_.spec(), + " scoreAd() incomingBidInSellerCurrency not a number."})); + ok = false; + } + if (ok && !IsValidBid(incoming_bid_in_seller_currency)) { + errors_out.push_back(base::StrCat( + {decision_logic_url_.spec(), + " scoreAd() incomingBidInSellerCurrency not a valid bid."})); + ok = false; + } + if (bid_in_seller_currency.has_value() && + incoming_bid_in_seller_currency != *bid_in_seller_currency) { + errors_out.push_back(base::StrCat( + {decision_logic_url_.spec(), + " scoreAd() attempting to set incomingBidInSellerCurrency " + "inconsistent with incoming bid already in seller currency."})); + ok = false; + } + if (!ok) { + PostScoreAdCallbackToUserThreadOnError( + std::move(callback), std::move(errors_out), + context_recycler.private_aggregation_bindings() + ->TakePrivateAggregationRequests()); + return; + } + bid_in_seller_currency = incoming_bid_in_seller_currency; + } + v8::Local<v8::Value> reject_reason_value; if (score_ad_object ->Get(context, v8_helper_->CreateStringFromLiteral("rejectReason")) @@ -950,28 +1026,29 @@ if (component_auction_modified_bid_params->has_bid) { bool drop_for_invalid_currency = false; v8::Local<v8::Value> bid_currency_value; - component_auction_modified_bid_params->bid_currency = - blink::kUnspecifiedAdCurrency; + component_auction_modified_bid_params->bid_currency = absl::nullopt; + std::string bid_currency_str; if (score_ad_object ->Get(context, v8_helper_->CreateStringFromLiteral("bidCurrency")) .ToLocal(&bid_currency_value) && !bid_currency_value->IsUndefined()) { - if (!gin::ConvertFromV8( - isolate, bid_currency_value, - &component_auction_modified_bid_params->bid_currency) || - !blink::IsValidAdCurrencyCode( - component_auction_modified_bid_params->bid_currency)) { + if (!gin::ConvertFromV8(isolate, bid_currency_value, + &bid_currency_str) || + !blink::IsValidAdCurrencyCode(bid_currency_str)) { errors_out.push_back( base::StrCat({decision_logic_url_.spec(), " scoreAd() returned an invalid bidCurrency."})); drop_for_invalid_currency = true; } + if (!drop_for_invalid_currency) { + component_auction_modified_bid_params->bid_currency = + blink::AdCurrency::From(bid_currency_str); + } } - std::string expected_seller_currency = - auction_ad_config_non_shared_params.seller_currency.value_or( - blink::kUnspecifiedAdCurrency); + const absl::optional<blink::AdCurrency> expected_seller_currency = + auction_ad_config_non_shared_params.seller_currency; if (!drop_for_invalid_currency && !blink::VerifyAdCurrencyCode( expected_seller_currency, @@ -980,20 +1057,25 @@ {decision_logic_url_.spec(), " scoreAd() bidCurrency mismatch vs own sellerCurrency, " "expected '", - expected_seller_currency, "' got '", - component_auction_modified_bid_params->bid_currency, "'."})); + blink::PrintableAdCurrency(expected_seller_currency), "' got '", + blink::PrintableAdCurrency( + component_auction_modified_bid_params->bid_currency), + "'."})); drop_for_invalid_currency = true; } - if (!drop_for_invalid_currency && component_expect_bid_currency && + if (!drop_for_invalid_currency && !blink::VerifyAdCurrencyCode( - component_expect_bid_currency.value(), + component_expect_bid_currency, component_auction_modified_bid_params->bid_currency)) { errors_out.push_back(base::StrCat( {decision_logic_url_.spec(), " scoreAd() bidCurrency mismatch in component auction " "vs parent auction bidderCurrency, expected '", - component_expect_bid_currency.value(), "' got '", - component_auction_modified_bid_params->bid_currency, "'."})); + blink::PrintableAdCurrency(component_expect_bid_currency), + "' got '", + blink::PrintableAdCurrency( + component_auction_modified_bid_params->bid_currency), + "'."})); drop_for_invalid_currency = true; } @@ -1036,7 +1118,7 @@ PostScoreAdCallbackToUserThread( std::move(callback), /*score=*/0, reject_reason, /*component_auction_modified_bid_params=*/nullptr, - scoring_signals_data_version, + /*bid_in_seller_currency=*/absl::nullopt, scoring_signals_data_version, context_recycler.for_debugging_only_bindings()->TakeLossReportUrl(), context_recycler.for_debugging_only_bindings()->TakeWinReportUrl(), context_recycler.private_aggregation_bindings() @@ -1051,8 +1133,7 @@ if (component_auction_modified_bid_params && component_auction_modified_bid_params->has_bid) { // Fail if the new bid is not valid or is 0 or less. - if (!std::isfinite(component_auction_modified_bid_params->bid) || - component_auction_modified_bid_params->bid <= 0.0) { + if (!IsValidBid(component_auction_modified_bid_params->bid)) { errors_out.push_back(base::StrCat( {decision_logic_url_.spec(), " scoreAd() returned an invalid bid."})); PostScoreAdCallbackToUserThreadOnError( @@ -1066,7 +1147,7 @@ PostScoreAdCallbackToUserThread( std::move(callback), score, /*reject_reason=*/mojom::RejectReason::kNotAvailable, - std::move(component_auction_modified_bid_params), + std::move(component_auction_modified_bid_params), bid_in_seller_currency, scoring_signals_data_version, context_recycler.for_debugging_only_bindings()->TakeLossReportUrl(), context_recycler.for_debugging_only_bindings()->TakeWinReportUrl(), @@ -1086,8 +1167,11 @@ const url::Origin& browser_signal_interest_group_owner, const GURL& browser_signal_render_url, double browser_signal_bid, + const absl::optional<blink::AdCurrency>& browser_signal_bid_currency, double browser_signal_desirability, double browser_signal_highest_scoring_other_bid, + const absl::optional<blink::AdCurrency>& + browser_signal_highest_scoring_other_bid_currency, auction_worklet::mojom::ComponentAuctionReportResultParamsPtr browser_signals_component_auction_report_result_params, absl::optional<uint32_t> scoring_signals_data_version, @@ -1131,9 +1215,16 @@ !browser_signals_dict.Set("renderUrl", browser_signal_render_url.spec()) || !browser_signals_dict.Set("bid", browser_signal_bid) || + !browser_signals_dict.Set( + "bidCurrency", + blink::PrintableAdCurrency(browser_signal_bid_currency)) || !browser_signals_dict.Set("desirability", browser_signal_desirability) || !browser_signals_dict.Set("highestScoringOtherBid", browser_signal_highest_scoring_other_bid) || + !browser_signals_dict.Set( + "highestScoringOtherBidCurrency", + blink::PrintableAdCurrency( + browser_signal_highest_scoring_other_bid_currency)) || (scoring_signals_data_version.has_value() && !browser_signals_dict.Set("dataVersion", scoring_signals_data_version.value()))) { @@ -1305,6 +1396,7 @@ std::move(callback), /*score=*/0, /*reject_reason=*/mojom::RejectReason::kNotAvailable, /*component_auction_modified_bid_params=*/nullptr, + /*bid_in_seller_currency=*/absl::nullopt, /*scoring_signals_data_version=*/absl::nullopt, /*debug_loss_report_url=*/absl::nullopt, /*debug_win_report_url=*/absl::nullopt, std::move(pa_requests), @@ -1317,6 +1409,7 @@ mojom::RejectReason reject_reason, mojom::ComponentAuctionModifiedBidParamsPtr component_auction_modified_bid_params, + absl::optional<double> bid_in_seller_currency, absl::optional<uint32_t> scoring_signals_data_version, absl::optional<GURL> debug_loss_report_url, absl::optional<GURL> debug_win_report_url, @@ -1327,7 +1420,7 @@ FROM_HERE, base::BindOnce(std::move(callback), score, reject_reason, std::move(component_auction_modified_bid_params), - scoring_signals_data_version, + bid_in_seller_currency, scoring_signals_data_version, std::move(debug_loss_report_url), std::move(debug_win_report_url), std::move(pa_requests), std::move(errors))); @@ -1554,6 +1647,7 @@ mojom::RejectReason reject_reason, mojom::ComponentAuctionModifiedBidParamsPtr component_auction_modified_bid_params, + absl::optional<double> bid_in_seller_currency, absl::optional<uint32_t> scoring_signals_data_version, absl::optional<GURL> debug_loss_report_url, absl::optional<GURL> debug_win_report_url, @@ -1573,9 +1667,9 @@ // unclear how useful it would be. task->score_ad_client->OnScoreAdComplete( score, reject_reason, std::move(component_auction_modified_bid_params), - scoring_signals_data_version.value_or(0), - scoring_signals_data_version.has_value(), debug_loss_report_url, - debug_win_report_url, std::move(pa_requests), std::move(errors)); + std::move(bid_in_seller_currency), scoring_signals_data_version, + debug_loss_report_url, debug_win_report_url, std::move(pa_requests), + std::move(errors)); score_ad_tasks_.erase(task); } @@ -1652,8 +1746,10 @@ std::move(task->browser_signals_other_seller), std::move(task->browser_signal_interest_group_owner), std::move(task->browser_signal_render_url), task->browser_signal_bid, + std::move(task->browser_signal_bid_currency), task->browser_signal_desirability, task->browser_signal_highest_scoring_other_bid, + std::move(task->browser_signal_highest_scoring_other_bid_currency), std::move( task->browser_signals_component_auction_report_result_params), task->scoring_signals_data_version, task->trace_id,
diff --git a/content/services/auction_worklet/seller_worklet.h b/content/services/auction_worklet/seller_worklet.h index bf3901f..17a8836 100644 --- a/content/services/auction_worklet/seller_worklet.h +++ b/content/services/auction_worklet/seller_worklet.h
@@ -96,13 +96,13 @@ void ScoreAd( const std::string& ad_metadata_json, double bid, - const std::string& bid_currency, + const absl::optional<blink::AdCurrency>& bid_currency, const blink::AuctionConfig::NonSharedParams& auction_ad_config_non_shared_params, const absl::optional<GURL>& direct_from_seller_seller_signals, const absl::optional<GURL>& direct_from_seller_auction_signals, mojom::ComponentAuctionOtherSellerPtr browser_signals_other_seller, - const absl::optional<std::string>& component_expect_bid_currency, + const absl::optional<blink::AdCurrency>& component_expect_bid_currency, const url::Origin& browser_signal_interest_group_owner, const GURL& browser_signal_render_url, const std::vector<GURL>& browser_signal_ad_components, @@ -121,8 +121,11 @@ const url::Origin& browser_signal_interest_group_owner, const GURL& browser_signal_render_url, double browser_signal_bid, + const absl::optional<blink::AdCurrency>& browser_signal_bid_currency, double browser_signal_desirability, double browser_signal_highest_scoring_other_bid, + const absl::optional<blink::AdCurrency>& + browser_signal_highest_scoring_other_bid_currency, auction_worklet::mojom::ComponentAuctionReportResultParamsPtr browser_signals_component_auction_report_result_params, uint32_t scoring_signals_data_version, @@ -148,10 +151,10 @@ // safe to access after that happens. std::string ad_metadata_json; double bid; - std::string bid_currency; + absl::optional<blink::AdCurrency> bid_currency; blink::AuctionConfig::NonSharedParams auction_ad_config_non_shared_params; mojom::ComponentAuctionOtherSellerPtr browser_signals_other_seller; - absl::optional<std::string> component_expect_bid_currency; + absl::optional<blink::AdCurrency> component_expect_bid_currency; url::Origin browser_signal_interest_group_owner; GURL browser_signal_render_url; // While these are URLs, it's more concenient to store these as strings @@ -209,8 +212,11 @@ url::Origin browser_signal_interest_group_owner; GURL browser_signal_render_url; double browser_signal_bid; + absl::optional<blink::AdCurrency> browser_signal_bid_currency; double browser_signal_desirability; double browser_signal_highest_scoring_other_bid; + absl::optional<blink::AdCurrency> + browser_signal_highest_scoring_other_bid_currency; auction_worklet::mojom::ComponentAuctionReportResultParamsPtr browser_signals_component_auction_report_result_params; absl::optional<uint32_t> scoring_signals_data_version; @@ -253,6 +259,7 @@ mojom::RejectReason reject_reason, mojom::ComponentAuctionModifiedBidParamsPtr component_auction_modified_bid_params, + absl::optional<double> bid_in_seller_currency, absl::optional<uint32_t> scoring_signals_data_version, absl::optional<GURL> debug_loss_report_url, absl::optional<GURL> debug_win_report_url, @@ -282,7 +289,7 @@ void ScoreAd( const std::string& ad_metadata_json, double bid, - const std::string& bid_currency, + const absl::optional<blink::AdCurrency>& bid_currency, const blink::AuctionConfig::NonSharedParams& auction_ad_config_non_shared_params, DirectFromSellerSignalsRequester::Result @@ -291,7 +298,7 @@ direct_from_seller_result_auction_signals, scoped_refptr<TrustedSignals::Result> trusted_scoring_signals, mojom::ComponentAuctionOtherSellerPtr browser_signals_other_seller, - const absl::optional<std::string>& component_expect_bid_currency, + const absl::optional<blink::AdCurrency>& component_expect_bid_currency, const url::Origin& browser_signal_interest_group_owner, const GURL& browser_signal_render_url, const std::vector<std::string>& browser_signal_ad_components, @@ -312,8 +319,11 @@ const url::Origin& browser_signal_interest_group_owner, const GURL& browser_signal_render_url, double browser_signal_bid, + const absl::optional<blink::AdCurrency>& browser_signal_bid_currency, double browser_signal_desirability, double browser_signal_highest_scoring_other_bid, + const absl::optional<blink::AdCurrency>& + browser_signal_highest_scoring_other_bid_currency, auction_worklet::mojom::ComponentAuctionReportResultParamsPtr browser_signals_component_auction_report_result_params, absl::optional<uint32_t> scoring_signals_data_version, @@ -344,6 +354,7 @@ mojom::RejectReason reject_reason, mojom::ComponentAuctionModifiedBidParamsPtr component_auction_modified_bid_params, + absl::optional<double> bid_in_seller_currency, absl::optional<uint32_t> scoring_signals_data_version, absl::optional<GURL> debug_loss_report_url, absl::optional<GURL> debug_win_report_url, @@ -424,6 +435,7 @@ mojom::RejectReason reject_reason, mojom::ComponentAuctionModifiedBidParamsPtr component_auction_modified_bid_params, + absl::optional<double> bid_in_seller_currency, absl::optional<uint32_t> scoring_signals_data_version, absl::optional<GURL> debug_loss_report_url, absl::optional<GURL> debug_win_report_url,
diff --git a/content/services/auction_worklet/seller_worklet_unittest.cc b/content/services/auction_worklet/seller_worklet_unittest.cc index dbe4984d..e35ce24 100644 --- a/content/services/auction_worklet/seller_worklet_unittest.cc +++ b/content/services/auction_worklet/seller_worklet_unittest.cc
@@ -108,17 +108,17 @@ // A ScoreAdClient that takes a callback to call in OnScoreAdComplete(). class TestScoreAdClient : public mojom::ScoreAdClient { public: - using ScoreAdCompleteCallback = - base::OnceCallback<void(double score, - mojom::RejectReason reject_reason, - mojom::ComponentAuctionModifiedBidParamsPtr - component_auction_modified_bid_params, - uint32_t scoring_signals_data_version, - bool has_scoring_signals_data_version, - const absl::optional<GURL>& debug_loss_report_url, - const absl::optional<GURL>& debug_win_report_url, - PrivateAggregationRequests pa_requests, - const std::vector<std::string>& errors)>; + using ScoreAdCompleteCallback = base::OnceCallback<void( + double score, + mojom::RejectReason reject_reason, + mojom::ComponentAuctionModifiedBidParamsPtr + component_auction_modified_bid_params, + absl::optional<double> bid_in_seller_currency, + absl::optional<uint32_t> scoring_signals_data_version, + const absl::optional<GURL>& debug_loss_report_url, + const absl::optional<GURL>& debug_win_report_url, + PrivateAggregationRequests pa_requests, + const std::vector<std::string>& errors)>; explicit TestScoreAdClient(ScoreAdCompleteCallback score_ad_complete_callback) : score_ad_complete_callback_(std::move(score_ad_complete_callback)) {} @@ -140,8 +140,8 @@ mojom::RejectReason reject_reason, mojom::ComponentAuctionModifiedBidParamsPtr component_auction_modified_bid_params, - uint32_t scoring_signals_data_version, - bool has_scoring_signals_data_version, + absl::optional<double> bid_in_seller_currency, + absl::optional<uint32_t> scoring_signals_data_version, const absl::optional<GURL>& debug_loss_report_url, const absl::optional<GURL>& debug_win_report_url, PrivateAggregationRequests pa_requests, @@ -149,23 +149,24 @@ std::move(score_ad_complete_callback_) .Run(score, reject_reason, std::move(component_auction_modified_bid_params), - scoring_signals_data_version, has_scoring_signals_data_version, - debug_loss_report_url, debug_win_report_url, - std::move(pa_requests), errors); + std::move(bid_in_seller_currency), + std::move(scoring_signals_data_version), debug_loss_report_url, + debug_win_report_url, std::move(pa_requests), errors); } static ScoreAdCompleteCallback ScoreAdNeverInvokedCallback() { - return base::BindOnce([](double score, mojom::RejectReason reject_reason, - mojom::ComponentAuctionModifiedBidParamsPtr - component_auction_modified_bid_params, - uint32_t scoring_signals_data_version, - bool has_scoring_signals_data_version, - const absl::optional<GURL>& debug_loss_report_url, - const absl::optional<GURL>& debug_win_report_url, - PrivateAggregationRequests pa_requests, - const std::vector<std::string>& errors) { - ADD_FAILURE() << "Callback should not be invoked"; - }); + return base::BindOnce( + [](double score, mojom::RejectReason reject_reason, + mojom::ComponentAuctionModifiedBidParamsPtr + component_auction_modified_bid_params, + absl::optional<double> bid_in_seller_currency, + absl::optional<uint32_t> scoring_signals_data_version, + const absl::optional<GURL>& debug_loss_report_url, + const absl::optional<GURL>& debug_win_report_url, + PrivateAggregationRequests pa_requests, + const std::vector<std::string>& errors) { + ADD_FAILURE() << "Callback should not be invoked"; + }); } private: @@ -213,7 +214,7 @@ void SetDefaultParameters() { ad_metadata_ = "[1]"; bid_ = 1; - bid_currency_ = blink::kUnspecifiedAdCurrency; + bid_currency_ = absl::nullopt; decision_logic_url_ = GURL("https://url.test/"); trusted_scoring_signals_url_.reset(); auction_ad_config_non_shared_params_ = @@ -235,6 +236,7 @@ browser_signal_desireability_ = 1; seller_timeout_ = absl::nullopt; browser_signal_highest_scoring_other_bid_ = 0; + browser_signal_highest_scoring_other_bid_currency_ = absl::nullopt; } // Configures `url_loader_factory_` to return a script with the specified @@ -253,13 +255,14 @@ const absl::optional<GURL>& expected_debug_win_report_url = absl::nullopt, mojom::RejectReason expected_reject_reason = mojom::RejectReason::kNotAvailable, - PrivateAggregationRequests expected_pa_requests = {}) { + PrivateAggregationRequests expected_pa_requests = {}, + absl::optional<double> expected_bid_in_seller_currency = absl::nullopt) { RunScoreAdWithJavascriptExpectingResult( CreateScoreAdScript(raw_return_value), expected_score, expected_errors, std::move(expected_component_auction_modified_bid_params), expected_data_version, expected_debug_loss_report_url, expected_debug_win_report_url, expected_reject_reason, - std::move(expected_pa_requests)); + std::move(expected_pa_requests), expected_bid_in_seller_currency); } // Behaves just like RunScoreAdWithReturnValueExpectingResult(), but @@ -282,7 +285,8 @@ const absl::optional<GURL>& expected_debug_win_report_url = absl::nullopt, mojom::RejectReason expected_reject_reason = mojom::RejectReason::kNotAvailable, - PrivateAggregationRequests expected_pa_requests = {}) { + PrivateAggregationRequests expected_pa_requests = {}, + absl::optional<double> expected_bid_in_seller_currency = absl::nullopt) { AddJavascriptResponse(&url_loader_factory_, decision_logic_url_, CreateScoreAdScript(raw_return_value)); auto seller_worklet = CreateWorklet(); @@ -293,7 +297,8 @@ std::move(expected_component_auction_modified_bid_params), expected_data_version, expected_debug_loss_report_url, expected_debug_win_report_url, expected_reject_reason, - std::move(expected_pa_requests), run_loop.QuitClosure()); + std::move(expected_pa_requests), expected_bid_in_seller_currency, + run_loop.QuitClosure()); task_environment_.FastForwardBy(expected_duration - kTinyTime); EXPECT_FALSE(run_loop.AnyQuitCalled()); task_environment_.FastForwardBy(kTinyTime); @@ -316,7 +321,8 @@ const absl::optional<GURL>& expected_debug_win_report_url = absl::nullopt, mojom::RejectReason expected_reject_reason = mojom::RejectReason::kNotAvailable, - PrivateAggregationRequests expected_pa_requests = {}) { + PrivateAggregationRequests expected_pa_requests = {}, + absl::optional<double> expected_bid_in_seller_currency = absl::nullopt) { SCOPED_TRACE(javascript); AddJavascriptResponse(&url_loader_factory_, decision_logic_url_, javascript); @@ -325,7 +331,7 @@ std::move(expected_component_auction_modified_bid_params), expected_data_version, expected_debug_loss_report_url, expected_debug_win_report_url, expected_reject_reason, - std::move(expected_pa_requests)); + std::move(expected_pa_requests), expected_bid_in_seller_currency); } // Runs score_ad() script, checking result and invoking provided closure @@ -341,6 +347,7 @@ const absl::optional<GURL>& expected_debug_win_report_url, mojom::RejectReason expected_reject_reason, PrivateAggregationRequests expected_pa_requests, + absl::optional<double> expected_bid_in_seller_currency, base::OnceClosure done_closure) { seller_worklet->ScoreAd( ad_metadata_, bid_, bid_currency_, auction_ad_config_non_shared_params_, @@ -359,19 +366,18 @@ const absl::optional<GURL>& expected_debug_loss_report_url, const absl::optional<GURL>& expected_debug_win_report_url, PrivateAggregationRequests expected_pa_requests, + absl::optional<double> expected_bid_in_seller_currency, std::vector<std::string> expected_errors, base::OnceClosure done_closure, double score, mojom::RejectReason reject_reason, mojom::ComponentAuctionModifiedBidParamsPtr component_auction_modified_bid_params, - uint32_t data_version, bool has_data_version, + absl::optional<double> bid_in_seller_currency, + absl::optional<uint32_t> scoring_signals_data_version, const absl::optional<GURL>& debug_loss_report_url, const absl::optional<GURL>& debug_win_report_url, PrivateAggregationRequests pa_requests, const std::vector<std::string>& errors) { - absl::optional<uint32_t> maybe_data_version; - if (has_data_version) - maybe_data_version = data_version; EXPECT_EQ(expected_score, score); EXPECT_EQ(static_cast<int>(expected_reject_reason), static_cast<int>(reject_reason)); @@ -392,7 +398,9 @@ } EXPECT_EQ(expected_debug_loss_report_url, debug_loss_report_url); EXPECT_EQ(expected_debug_win_report_url, debug_win_report_url); - EXPECT_EQ(expected_data_version, maybe_data_version); + EXPECT_EQ(expected_data_version, scoring_signals_data_version); + EXPECT_EQ(expected_bid_in_seller_currency, + bid_in_seller_currency); EXPECT_EQ(expected_pa_requests, pa_requests); EXPECT_EQ(expected_errors, errors); std::move(done_closure).Run(); @@ -401,7 +409,8 @@ std::move(expected_component_auction_modified_bid_params), expected_data_version, expected_debug_loss_report_url, expected_debug_win_report_url, std::move(expected_pa_requests), - expected_errors, std::move(done_closure)))); + expected_bid_in_seller_currency, expected_errors, + std::move(done_closure)))); } void RunScoreAdOnWorkletExpectingCallbackNeverInvoked( @@ -433,14 +442,16 @@ const absl::optional<GURL>& expected_debug_win_report_url = absl::nullopt, mojom::RejectReason expected_reject_reason = mojom::RejectReason::kNotAvailable, - PrivateAggregationRequests expected_pa_requests = {}) { + PrivateAggregationRequests expected_pa_requests = {}, + absl::optional<double> expected_bid_in_seller_currency = absl::nullopt) { base::RunLoop run_loop; RunScoreAdOnWorkletAsync( seller_worklet, expected_score, expected_errors, std::move(expected_component_auction_modified_bid_params), expected_data_version, expected_debug_loss_report_url, expected_debug_win_report_url, expected_reject_reason, - std::move(expected_pa_requests), run_loop.QuitClosure()); + std::move(expected_pa_requests), expected_bid_in_seller_currency, + run_loop.QuitClosure()); run_loop.Run(); } @@ -458,7 +469,8 @@ const absl::optional<GURL>& expected_debug_win_report_url = absl::nullopt, mojom::RejectReason expected_reject_reason = mojom::RejectReason::kNotAvailable, - PrivateAggregationRequests expected_pa_requests = {}) { + PrivateAggregationRequests expected_pa_requests = {}, + absl::optional<double> expected_bid_in_seller_currency = absl::nullopt) { auto seller_worklet = CreateWorklet(); ASSERT_TRUE(seller_worklet); RunScoreAdExpectingResultOnWorklet( @@ -466,7 +478,7 @@ std::move(expected_component_auction_modified_bid_params), expected_data_version, expected_debug_loss_report_url, expected_debug_win_report_url, expected_reject_reason, - std::move(expected_pa_requests)); + std::move(expected_pa_requests), expected_bid_in_seller_currency); } // Configures `url_loader_factory_` to return a report_result() script created @@ -526,8 +538,9 @@ direct_from_seller_seller_signals_, direct_from_seller_auction_signals_, browser_signals_other_seller_.Clone(), browser_signal_interest_group_owner_, browser_signal_render_url_, bid_, - browser_signal_desireability_, + bid_currency_, browser_signal_desireability_, browser_signal_highest_scoring_other_bid_, + browser_signal_highest_scoring_other_bid_currency_, browser_signals_component_auction_report_result_params_.Clone(), browser_signal_data_version_.value_or(0), browser_signal_data_version_.has_value(), @@ -572,8 +585,9 @@ direct_from_seller_seller_signals_, direct_from_seller_auction_signals_, browser_signals_other_seller_.Clone(), browser_signal_interest_group_owner_, browser_signal_render_url_, bid_, - browser_signal_desireability_, + bid_currency_, browser_signal_desireability_, browser_signal_highest_scoring_other_bid_, + browser_signal_highest_scoring_other_bid_currency_, browser_signals_component_auction_report_result_params_.Clone(), browser_signal_data_version_.value_or(0), browser_signal_data_version_.has_value(), @@ -688,7 +702,7 @@ // `bid_` is a browser signal for report_result(), but a direct parameter for // score_bid(). double bid_; - std::string bid_currency_; + absl::optional<blink::AdCurrency> bid_currency_; GURL decision_logic_url_; absl::optional<GURL> trusted_scoring_signals_url_; blink::AuctionConfig::NonSharedParams auction_ad_config_non_shared_params_; @@ -698,13 +712,15 @@ mojom::AuctionWorkletPermissionsPolicyStatePtr permissions_policy_state_; absl::optional<uint16_t> experiment_group_id_; mojom::ComponentAuctionOtherSellerPtr browser_signals_other_seller_; - absl::optional<std::string> component_expect_bid_currency_; + absl::optional<blink::AdCurrency> component_expect_bid_currency_; url::Origin browser_signal_interest_group_owner_; GURL browser_signal_render_url_; std::vector<GURL> browser_signal_ad_components_; uint32_t browser_signal_bidding_duration_msecs_; double browser_signal_desireability_; double browser_signal_highest_scoring_other_bid_; + absl::optional<blink::AdCurrency> + browser_signal_highest_scoring_other_bid_currency_; mojom::ComponentAuctionReportResultParamsPtr browser_signals_component_auction_report_result_params_; absl::optional<uint32_t> browser_signal_data_version_; @@ -833,7 +849,8 @@ const mojom::ComponentAuctionModifiedBidParamsPtr kExpectedComponentAuctionModifiedBidParams = mojom::ComponentAuctionModifiedBidParams::New( - /*ad=*/"null", /*bid=*/0, /*bid_currency=*/"", /*has_bid=*/false); + /*ad=*/"null", /*bid=*/0, /*bid_currency=*/absl::nullopt, + /*has_bid=*/false); // With a null `browser_signals_other_seller_`, returning a raw score is // allowed, and if returning an object, `allowComponentAuction` doesn't @@ -934,23 +951,26 @@ RunScoreAdWithReturnValueExpectingResult( "{desirability:1, allowComponentAuction:true}", 1, /*expected_errors=*/{}, mojom::ComponentAuctionModifiedBidParams::New( - /*ad=*/"null", /*bid=*/0, /*bid_currency=*/"", /*has_bid=*/false)); + /*ad=*/"null", /*bid=*/0, /*bid_currency=*/absl::nullopt, + /*has_bid=*/false)); RunScoreAdWithReturnValueExpectingResult( "{ad:null, desirability:1, allowComponentAuction:true}", 1, /*expected_errors=*/{}, mojom::ComponentAuctionModifiedBidParams::New( - /*ad=*/"null", /*bid=*/0, /*bid_currency=*/"", /*has_bid=*/false)); + /*ad=*/"null", /*bid=*/0, /*bid_currency=*/absl::nullopt, + /*has_bid=*/false)); RunScoreAdWithReturnValueExpectingResult( R"({ad:"foo", desirability:1, allowComponentAuction:true})", 1, /*expected_errors=*/{}, mojom::ComponentAuctionModifiedBidParams::New( - /*ad=*/R"("foo")", /*bid=*/0, /*bid_currency=*/"", + /*ad=*/R"("foo")", /*bid=*/0, /*bid_currency=*/absl::nullopt, /*has_bid=*/false)); RunScoreAdWithReturnValueExpectingResult( "{ad:[[35]], desirability:1, allowComponentAuction:true}", 1, /*expected_errors=*/{}, mojom::ComponentAuctionModifiedBidParams::New( - /*ad=*/"[[35]]", /*bid=*/0, /*bid_currency=*/"", /*has_bid=*/false)); + /*ad=*/"[[35]]", /*bid=*/0, /*bid_currency=*/absl::nullopt, + /*has_bid=*/false)); } // Test the `rejectReason` output field of scoreAd(). @@ -1050,13 +1070,13 @@ "{ad:null, desirability:1, allowComponentAuction:true, bid:13}", 1, /*expected_errors=*/{}, mojom::ComponentAuctionModifiedBidParams::New( - /*ad=*/"null", /*bid=*/13, blink::kUnspecifiedAdCurrency, + /*ad=*/"null", /*bid=*/13, /*bid_currency=*/absl::nullopt, /*has_bid=*/true)); RunScoreAdWithReturnValueExpectingResult( "{ad:null, desirability:1, allowComponentAuction:true, bid:1.2}", 1, /*expected_errors=*/{}, mojom::ComponentAuctionModifiedBidParams::New( - /*ad=*/"null", /*bid=*/1.2, blink::kUnspecifiedAdCurrency, + /*ad=*/"null", /*bid=*/1.2, /*bid_currency=*/absl::nullopt, /*has_bid=*/true)); // Can also specify the currency. @@ -1066,7 +1086,8 @@ 1, /*expected_errors=*/{}, mojom::ComponentAuctionModifiedBidParams::New( - /*ad=*/"null", /*bid=*/1.2, /*bid_currency=*/"USD", + /*ad=*/"null", /*bid=*/1.2, + /*bid_currency=*/blink::AdCurrency::From("USD"), /*has_bid=*/true)); // Not providing a bid is fine. @@ -1074,19 +1095,22 @@ "{ad:null, desirability:1, allowComponentAuction:true}", 1, /*expected_errors=*/{}, mojom::ComponentAuctionModifiedBidParams::New( - /*ad=*/"null", /*bid=*/0, /*bid_currency=*/"", /*has_bid=*/false)); + /*ad=*/"null", /*bid=*/0, /*bid_currency=*/absl::nullopt, + /*has_bid=*/false)); // Non-numeric bids are ignored. RunScoreAdWithReturnValueExpectingResult( R"({ad:null, desirability:1, allowComponentAuction:true, bid:"5"})", 1, /*expected_errors=*/{}, mojom::ComponentAuctionModifiedBidParams::New( - /*ad=*/"null", /*bid=*/0, /*bid_currency=*/"", /*has_bid=*/false)); + /*ad=*/"null", /*bid=*/0, /*bid_currency=*/absl::nullopt, + /*has_bid=*/false)); RunScoreAdWithReturnValueExpectingResult( "{ad:null, desirability:1, allowComponentAuction:true, bid:[4]}", 1, /*expected_errors=*/{}, mojom::ComponentAuctionModifiedBidParams::New( - /*ad=*/"null", /*bid=*/0, /*bid_currency=*/"", /*has_bid=*/false)); + /*ad=*/"null", /*bid=*/0, /*bid_currency=*/absl::nullopt, + /*has_bid=*/false)); // Invalid bids result in errors. RunScoreAdWithReturnValueExpectingResult( @@ -1116,7 +1140,8 @@ "{ad:null, desirability:1, allowComponentAuction:true, " "bid:1.2, bidCurrency: 'USSD'}", 0, {"https://url.test/ scoreAd() returned an invalid bidCurrency."}); - auction_ad_config_non_shared_params_.seller_currency = "CAD"; + auction_ad_config_non_shared_params_.seller_currency = + blink::AdCurrency::From("CAD"); RunScoreAdWithReturnValueExpectingResult( "{ad:null, desirability:1, allowComponentAuction:true, " "bid:1.2, bidCurrency: 'USD'}", @@ -1129,13 +1154,14 @@ 1, /*expected_errors=*/{}, mojom::ComponentAuctionModifiedBidParams::New( - /*ad=*/"null", /*bid=*/1.2, /*bid_currency=*/"CAD", + /*ad=*/"null", /*bid=*/1.2, + /*bid_currency=*/blink::AdCurrency::From("CAD"), /*has_bid=*/true)); auction_ad_config_non_shared_params_.seller_currency = absl::nullopt; // In component auctions, there is also verification against parent auction's // bidderCurrencies. - component_expect_bid_currency_ = "EUR"; + component_expect_bid_currency_ = blink::AdCurrency::From("EUR"); RunScoreAdWithReturnValueExpectingResult( "{ad:null, desirability:1, allowComponentAuction:true, " "bid:1.2, bidCurrency: 'USD'}", @@ -1148,7 +1174,8 @@ 1, /*expected_errors=*/{}, mojom::ComponentAuctionModifiedBidParams::New( - /*ad=*/"null", /*bid=*/1.2, /*bid_currency=*/"EUR", + /*ad=*/"null", /*bid=*/1.2, + /*bid_currency=*/blink::AdCurrency::From("EUR"), /*has_bid=*/true)); component_expect_bid_currency_ = absl::nullopt; @@ -1158,6 +1185,80 @@ "{ad:null, desirability:0, allowComponentAuction:true, bid:0}", 0); } +// Test the `incomingBidInSellerCurrency` output field of scoreAd() +TEST_F(SellerWorkletTest, ScoreAdIncomingBidInSellerCurrency) { + // Configure bid currency to make sure checks for passthrough are done. + bid_currency_ = blink::AdCurrency::From("USD"); + + // If seller currency isn't configured, can't set it. + auction_ad_config_non_shared_params_.seller_currency = absl::nullopt; + + RunScoreAdWithReturnValueExpectingResult( + "{desirability:1, incomingBidInSellerCurrency: 4}", 0, + {"https://url.test/ scoreAd() attempting to set " + "incomingBidInSellerCurrency without a configured sellerCurrency."}); + + auction_ad_config_non_shared_params_.seller_currency = + blink::AdCurrency::From("CAD"); + RunScoreAdWithReturnValueExpectingResult( + "{desirability:1, incomingBidInSellerCurrency: 'foo'}", 0, + {"https://url.test/ scoreAd() incomingBidInSellerCurrency not " + "a number."}); + + RunScoreAdWithReturnValueExpectingResult( + "{desirability:1, incomingBidInSellerCurrency: -100}", 0, + {"https://url.test/ scoreAd() incomingBidInSellerCurrency not " + "a valid bid."}); + + // Now pass in a valid one. + RunScoreAdWithReturnValueExpectingResult( + "{desirability:1, incomingBidInSellerCurrency: 100}", 1, + /*expected_errors=*/std::vector<std::string>(), + mojom::ComponentAuctionModifiedBidParamsPtr(), + /*expected_data_version=*/absl::nullopt, + /*expected_debug_loss_report_url=*/absl::nullopt, + /*expected_debug_win_report_url=*/absl::nullopt, + /*expected_reject_reason=*/ + mojom::RejectReason::kNotAvailable, + /*expected_pa_requests=*/{}, + /*expected_bid_in_seller_currency=*/100); + + // When bid currency matches seller currency, incomingBidInSellerCurrency + // should only be be accepted if it matches the incoming value. + bid_currency_ = blink::AdCurrency::From("CAD"); + RunScoreAdWithReturnValueExpectingResult( + "{desirability:1, incomingBidInSellerCurrency: 100}", 0, + {"https://url.test/ scoreAd() attempting to set " + "incomingBidInSellerCurrency inconsistent with incoming bid already in " + "seller currency."}); + + RunScoreAdWithReturnValueExpectingResult( + "{desirability:1, incomingBidInSellerCurrency: 1}", 1, + /*expected_errors=*/std::vector<std::string>(), + mojom::ComponentAuctionModifiedBidParamsPtr(), + /*expected_data_version=*/absl::nullopt, + /*expected_debug_loss_report_url=*/absl::nullopt, + /*expected_debug_win_report_url=*/absl::nullopt, + /*expected_reject_reason=*/ + mojom::RejectReason::kNotAvailable, + /*expected_pa_requests=*/{}, + /*expected_bid_in_seller_currency=*/1); + + // ...can also have that same-currency bid directly forwarded. + bid_ = 3.14; + RunScoreAdWithReturnValueExpectingResult( + "{desirability:1}", 1, + /*expected_errors=*/std::vector<std::string>(), + mojom::ComponentAuctionModifiedBidParamsPtr(), + /*expected_data_version=*/absl::nullopt, + /*expected_debug_loss_report_url=*/absl::nullopt, + /*expected_debug_win_report_url=*/absl::nullopt, + /*expected_reject_reason=*/ + mojom::RejectReason::kNotAvailable, + /*expected_pa_requests=*/{}, + /*expected_bid_in_seller_currency=*/3.14); +} + TEST_F(SellerWorkletTest, ScoreAdDateNotAvailable) { RunScoreAdWithReturnValueExpectingResult( "Date.parse(Date().toString())", 0, @@ -1205,7 +1306,8 @@ {desirability: 2, allowComponentAuction: true} : 0)", 2, /*expected_errors=*/{}, mojom::ComponentAuctionModifiedBidParams::New( - /*ad=*/"null", /*bid=*/0, /*bid_currency=*/"", /*has_bid=*/false)); + /*ad=*/"null", /*bid=*/0, /*bid_currency=*/absl::nullopt, + /*has_bid=*/false)); // `topLevelSeller` should be empty when a component seller is scoring a bid. // Must set `allowComponentAuction` to true for any value to be returned. @@ -1236,7 +1338,8 @@ 0 : {desirability: 2, allowComponentAuction: true})", 2, /*expected_errors=*/{}, mojom::ComponentAuctionModifiedBidParams::New( - /*ad=*/"null", /*bid=*/0, /*bid_currency=*/"", /*has_bid=*/false)); + /*ad=*/"null", /*bid=*/0, /*bid_currency=*/absl::nullopt, + /*has_bid=*/false)); // `componentSeller` should be set when a component seller is scoring a bid. // Must set `allowComponentAuction` to true for any value to be returned. @@ -1309,7 +1412,7 @@ RunScoreAdWithReturnValueExpectingResult( "browserSignals.bidCurrency === '???' ? 2 : 0", 2); - bid_currency_ = "USD"; + bid_currency_ = blink::AdCurrency::From("USD"); RunScoreAdWithReturnValueExpectingResult( "browserSignals.bidCurrency === 'USD' ? 2 : 0", 2); } @@ -1488,6 +1591,7 @@ /*expected_reject_reason=*/ mojom::RejectReason::kNotAvailable, /*expected_pa_requests=*/{}, + /*expected_bid_in_seller_currency=*/absl::nullopt, base::BindLambdaForTesting([&]() { ++num_completed_worklets; if (num_completed_worklets == kNumWorklets) @@ -1532,6 +1636,7 @@ /*expected_reject_reason=*/ mojom::RejectReason::kNotAvailable, /*expected_pa_requests=*/{}, + /*expected_bid_in_seller_currency=*/absl::nullopt, base::BindLambdaForTesting([&]() { ++num_completed_worklets; if (num_completed_worklets == kNumWorklets) @@ -1598,6 +1703,7 @@ /*expected_reject_reason=*/ mojom::RejectReason::kNotAvailable, /*expected_pa_requests=*/{}, + /*expected_bid_in_seller_currency=*/absl::nullopt, base::BindLambdaForTesting([&]() { ++num_completed_worklets; if (num_completed_worklets == kNumWorklets) @@ -1667,6 +1773,7 @@ /*expected_reject_reason=*/ mojom::RejectReason::kNotAvailable, /*expected_pa_requests=*/{}, + /*expected_bid_in_seller_currency=*/absl::nullopt, base::BindLambdaForTesting([&]() { ++num_completed_worklets; if (num_completed_worklets == kNumWorklets) @@ -1727,6 +1834,7 @@ /*expected_reject_reason=*/ mojom::RejectReason::kNotAvailable, /*expected_pa_requests=*/{}, + /*expected_bid_in_seller_currency=*/absl::nullopt, base::BindLambdaForTesting([&]() { ++num_completed_worklets; if (num_completed_worklets == kNumWorklets) @@ -1796,6 +1904,7 @@ /*expected_reject_reason=*/ mojom::RejectReason::kNotAvailable, /*expected_pa_requests=*/{}, + /*expected_bid_in_seller_currency=*/absl::nullopt, base::BindLambdaForTesting([&]() { ++num_completed_worklets; if (num_completed_worklets == kNumWorklets) @@ -1884,15 +1993,17 @@ mojo::Remote<mojom::SellerWorklet> seller_worklet = CreateWorklet(); url_loader_factory_.ClearResponses(); auto run_loop = std::make_unique<base::RunLoop>(); - RunScoreAdOnWorkletAsync( - seller_worklet.get(), /*expected_score=*/1.0, - /*expected_errors=*/{}, mojom::ComponentAuctionModifiedBidParamsPtr(), - /*expected_data_version=*/absl::nullopt, - /*expected_debug_loss_report_url=*/absl::nullopt, - /*expected_debug_win_report_url=*/absl::nullopt, - /*expected_reject_reason=*/ - mojom::RejectReason::kNotAvailable, - /*expected_pa_requests=*/{}, run_loop->QuitClosure()); + RunScoreAdOnWorkletAsync(seller_worklet.get(), /*expected_score=*/1.0, + /*expected_errors=*/{}, + mojom::ComponentAuctionModifiedBidParamsPtr(), + /*expected_data_version=*/absl::nullopt, + /*expected_debug_loss_report_url=*/absl::nullopt, + /*expected_debug_win_report_url=*/absl::nullopt, + /*expected_reject_reason=*/ + mojom::RejectReason::kNotAvailable, + /*expected_pa_requests=*/{}, + /*expected_bid_in_seller_currency=*/absl::nullopt, + run_loop->QuitClosure()); for (size_t i = 0; i < std::size(kResponses); ++i) { SCOPED_TRACE(i); const Response& response = @@ -1982,27 +2093,31 @@ &alternate_url_loader_factory_, decision_logic_url_, CreateScoreAdScript("1", /*extra_code=*/kWorklet2ExtraCode)); auto run_loop = std::make_unique<base::RunLoop>(); - RunScoreAdOnWorkletAsync( - seller_worklet1.get(), /*expected_score=*/1.0, - /*expected_errors=*/{}, mojom::ComponentAuctionModifiedBidParamsPtr(), - /*expected_data_version=*/absl::nullopt, - /*expected_debug_loss_report_url=*/absl::nullopt, - /*expected_debug_win_report_url=*/absl::nullopt, - /*expected_reject_reason=*/ - mojom::RejectReason::kNotAvailable, - /*expected_pa_requests=*/{}, run_loop->QuitClosure()); + RunScoreAdOnWorkletAsync(seller_worklet1.get(), /*expected_score=*/1.0, + /*expected_errors=*/{}, + mojom::ComponentAuctionModifiedBidParamsPtr(), + /*expected_data_version=*/absl::nullopt, + /*expected_debug_loss_report_url=*/absl::nullopt, + /*expected_debug_win_report_url=*/absl::nullopt, + /*expected_reject_reason=*/ + mojom::RejectReason::kNotAvailable, + /*expected_pa_requests=*/{}, + /*expected_bid_in_seller_currency=*/absl::nullopt, + run_loop->QuitClosure()); run_loop->Run(); run_loop = std::make_unique<base::RunLoop>(); - RunScoreAdOnWorkletAsync( - seller_worklet2.get(), /*expected_score=*/1.0, - /*expected_errors=*/{}, mojom::ComponentAuctionModifiedBidParamsPtr(), - /*expected_data_version=*/absl::nullopt, - /*expected_debug_loss_report_url=*/absl::nullopt, - /*expected_debug_win_report_url=*/absl::nullopt, - /*expected_reject_reason=*/ - mojom::RejectReason::kNotAvailable, - /*expected_pa_requests=*/{}, run_loop->QuitClosure()); + RunScoreAdOnWorkletAsync(seller_worklet2.get(), /*expected_score=*/1.0, + /*expected_errors=*/{}, + mojom::ComponentAuctionModifiedBidParamsPtr(), + /*expected_data_version=*/absl::nullopt, + /*expected_debug_loss_report_url=*/absl::nullopt, + /*expected_debug_win_report_url=*/absl::nullopt, + /*expected_reject_reason=*/ + mojom::RejectReason::kNotAvailable, + /*expected_pa_requests=*/{}, + /*expected_bid_in_seller_currency=*/absl::nullopt, + run_loop->QuitClosure()); run_loop->Run(); } @@ -2527,6 +2642,14 @@ /*expected_report_url=*/absl::nullopt); } +TEST_F(SellerWorkletTest, ReportResultBidCurrency) { + bid_currency_ = blink::AdCurrency::From("EUR"); + RunReportResultCreatedScriptExpectingResult( + "browserSignals.bidCurrency + typeof browserSignals.bidCurrency", + /*extra_code=*/std::string(), R"("EURstring")", + /*expected_report_url=*/absl::nullopt); +} + TEST_F(SellerWorkletTest, ReportResultDesireability) { browser_signal_desireability_ = 10; RunReportResultCreatedScriptExpectingResult( @@ -2544,6 +2667,16 @@ /*expected_report_url=*/absl::nullopt); } +TEST_F(SellerWorkletTest, ReportResultHighestScoringOtherBidCurrency) { + browser_signal_highest_scoring_other_bid_currency_ = + blink::AdCurrency::From("EUR"); + RunReportResultCreatedScriptExpectingResult( + "browserSignals.highestScoringOtherBidCurrency + typeof " + "browserSignals.highestScoringOtherBidCurrency", + /*extra_code=*/std::string(), R"("EURstring")", + /*expected_report_url=*/absl::nullopt); +} + TEST_F(SellerWorkletTest, ReportResultAuctionConfigParam) { // Empty AuctionAdConfig, with nothing filled in, except the seller and // decision logic URL. @@ -2602,8 +2735,9 @@ blink::AuctionConfig::BuyerCurrencies buyer_currencies; buyer_currencies.per_buyer_currencies.emplace(); buyer_currencies.per_buyer_currencies - .value()[url::Origin::Create(GURL("https://example.ca"))] = "CAD"; - buyer_currencies.all_buyers_currency = "USD"; + .value()[url::Origin::Create(GURL("https://example.ca"))] = + blink::AdCurrency::From("CAD"); + buyer_currencies.all_buyers_currency = blink::AdCurrency::From("USD"); auction_ad_config_non_shared_params_.buyer_currencies = blink::AuctionConfig::MaybePromiseBuyerCurrencies::FromValue( std::move(buyer_currencies)); @@ -2849,14 +2983,14 @@ [&run_loop](double score, mojom::RejectReason reject_reason, mojom::ComponentAuctionModifiedBidParamsPtr component_auction_modified_bid_params, - uint32_t scoring_signals_data_version, - bool has_scoring_signals_data_version, + absl::optional<double> bid_in_seller_currency, + absl::optional<uint32_t> scoring_signals_data_version, const absl::optional<GURL>& debug_loss_report_url, const absl::optional<GURL>& debug_win_report_url, PrivateAggregationRequests pa_requests, const std::vector<std::string>& errors) { EXPECT_EQ(2, score); - EXPECT_FALSE(has_scoring_signals_data_version); + EXPECT_FALSE(scoring_signals_data_version.has_value()); EXPECT_TRUE(errors.empty()); run_loop.Quit(); }))); @@ -2871,8 +3005,9 @@ direct_from_seller_auction_signals_, browser_signals_other_seller_.Clone(), browser_signal_interest_group_owner_, browser_signal_render_url_, - bid_, browser_signal_desireability_, + bid_, bid_currency_, browser_signal_desireability_, browser_signal_highest_scoring_other_bid_, + browser_signal_highest_scoring_other_bid_currency_, browser_signals_component_auction_report_result_params_.Clone(), browser_signal_data_version_.value_or(0), browser_signal_data_version_.has_value(), @@ -2931,7 +3066,9 @@ direct_from_seller_auction_signals_, browser_signals_other_seller_.Clone(), browser_signal_interest_group_owner_, browser_signal_render_url_, bid_, - browser_signal_desireability_, browser_signal_highest_scoring_other_bid_, + bid_currency_, browser_signal_desireability_, + browser_signal_highest_scoring_other_bid_, + browser_signal_highest_scoring_other_bid_currency_, browser_signals_component_auction_report_result_params_.Clone(), browser_signal_data_version_.value_or(0), browser_signal_data_version_.has_value(), @@ -2970,7 +3107,9 @@ /*expected_debug_win_report_url=*/absl::nullopt, /*expected_reject_reason=*/ mojom::RejectReason::kNotAvailable, - /*expected_pa_requests=*/{}, run_loop.QuitClosure()); + /*expected_pa_requests=*/{}, + /*expected_bid_in_seller_currency=*/absl::nullopt, + run_loop.QuitClosure()); // Give it a chance to fetch. task_environment_.RunUntilIdle(); @@ -3046,30 +3185,34 @@ auto worklet1 = CreateWorklet( /*pause_for_debugger_on_start=*/true, &worklet_impl1); base::RunLoop run_loop1; - RunScoreAdOnWorkletAsync( - worklet1.get(), /*expected_score=*/1, - /*expected_errors=*/{}, mojom::ComponentAuctionModifiedBidParamsPtr(), - /*expected_data_version=*/absl::nullopt, - /*expected_debug_loss_report_url=*/absl::nullopt, - /*expected_debug_win_report_url=*/absl::nullopt, - /*expected_reject_reason=*/ - mojom::RejectReason::kNotAvailable, - /*expected_pa_requests=*/{}, run_loop1.QuitClosure()); + RunScoreAdOnWorkletAsync(worklet1.get(), /*expected_score=*/1, + /*expected_errors=*/{}, + mojom::ComponentAuctionModifiedBidParamsPtr(), + /*expected_data_version=*/absl::nullopt, + /*expected_debug_loss_report_url=*/absl::nullopt, + /*expected_debug_win_report_url=*/absl::nullopt, + /*expected_reject_reason=*/ + mojom::RejectReason::kNotAvailable, + /*expected_pa_requests=*/{}, + /*expected_bid_in_seller_currency=*/absl::nullopt, + run_loop1.QuitClosure()); decision_logic_url_ = kUrl2; SellerWorklet* worklet_impl2 = nullptr; auto worklet2 = CreateWorklet( /*pause_for_debugger_on_start=*/true, &worklet_impl2); base::RunLoop run_loop2; - RunScoreAdOnWorkletAsync( - worklet2.get(), /*expected_score=*/2, - /*expected_errors=*/{}, mojom::ComponentAuctionModifiedBidParamsPtr(), - /*expected_data_version=*/absl::nullopt, - /*expected_debug_loss_report_url=*/absl::nullopt, - /*expected_debug_win_report_url=*/absl::nullopt, - /*expected_reject_reason=*/ - mojom::RejectReason::kNotAvailable, - /*expected_pa_requests=*/{}, run_loop2.QuitClosure()); + RunScoreAdOnWorkletAsync(worklet2.get(), /*expected_score=*/2, + /*expected_errors=*/{}, + mojom::ComponentAuctionModifiedBidParamsPtr(), + /*expected_data_version=*/absl::nullopt, + /*expected_debug_loss_report_url=*/absl::nullopt, + /*expected_debug_win_report_url=*/absl::nullopt, + /*expected_reject_reason=*/ + mojom::RejectReason::kNotAvailable, + /*expected_pa_requests=*/{}, + /*expected_bid_in_seller_currency=*/absl::nullopt, + run_loop2.QuitClosure()); int id1 = worklet_impl1->context_group_id_for_testing(); int id2 = worklet_impl2->context_group_id_for_testing(); @@ -3183,15 +3326,17 @@ decision_logic_url_ = GURL(kUrl1); auto worklet1 = CreateWorklet(/*pause_for_debugger_on_start=*/true); base::RunLoop run_loop1; - RunScoreAdOnWorkletAsync( - worklet1.get(), /*expected_score=*/100.5, /*expected_errors=*/{}, - mojom::ComponentAuctionModifiedBidParamsPtr(), - /*expected_data_version=*/absl::nullopt, - /*expected_debug_loss_report_url=*/absl::nullopt, - /*expected_debug_win_report_url=*/absl::nullopt, - /*expected_reject_reason=*/ - mojom::RejectReason::kNotAvailable, - /*expected_pa_requests=*/{}, run_loop1.QuitClosure()); + RunScoreAdOnWorkletAsync(worklet1.get(), /*expected_score=*/100.5, + /*expected_errors=*/{}, + mojom::ComponentAuctionModifiedBidParamsPtr(), + /*expected_data_version=*/absl::nullopt, + /*expected_debug_loss_report_url=*/absl::nullopt, + /*expected_debug_win_report_url=*/absl::nullopt, + /*expected_reject_reason=*/ + mojom::RejectReason::kNotAvailable, + /*expected_pa_requests=*/{}, + /*expected_bid_in_seller_currency=*/absl::nullopt, + run_loop1.QuitClosure()); decision_logic_url_ = GURL(kUrl2); auto worklet2 = CreateWorklet(/*pause_for_debugger_on_start=*/true); @@ -3206,6 +3351,7 @@ /*expected_reject_reason=*/ mojom::RejectReason::kNotAvailable, /*expected_pa_requests=*/{}, + /*expected_bid_in_seller_currency=*/absl::nullopt, run_loop2.QuitClosure()); mojo::AssociatedRemote<blink::mojom::DevToolsAgent> agent1, agent2; @@ -3356,7 +3502,9 @@ /*expected_debug_win_report_url=*/absl::nullopt, /*expected_reject_reason=*/ mojom::RejectReason::kNotAvailable, - /*expected_pa_requests=*/{}, run_loop.QuitClosure()); + /*expected_pa_requests=*/{}, + /*expected_bid_in_seller_currency=*/absl::nullopt, + run_loop.QuitClosure()); mojo::AssociatedRemote<blink::mojom::DevToolsAgent> agent; worklet->ConnectDevToolsAgent(agent.BindNewEndpointAndPassReceiver()); @@ -3428,15 +3576,17 @@ // Running another scoreAd will trigger the breakpoint again, since we didn't // remove it. base::RunLoop run_loop3; - RunScoreAdOnWorkletAsync( - worklet.get(), /*expected_score=*/1.0, /*expected_errors=*/{}, - mojom::ComponentAuctionModifiedBidParamsPtr(), - /*expected_data_version=*/absl::nullopt, - /*expected_debug_loss_report_url=*/absl::nullopt, - /*expected_debug_win_report_url=*/absl::nullopt, - /*expected_reject_reason=*/ - mojom::RejectReason::kNotAvailable, - /*expected_pa_requests=*/{}, run_loop3.QuitClosure()); + RunScoreAdOnWorkletAsync(worklet.get(), /*expected_score=*/1.0, + /*expected_errors=*/{}, + mojom::ComponentAuctionModifiedBidParamsPtr(), + /*expected_data_version=*/absl::nullopt, + /*expected_debug_loss_report_url=*/absl::nullopt, + /*expected_debug_win_report_url=*/absl::nullopt, + /*expected_reject_reason=*/ + mojom::RejectReason::kNotAvailable, + /*expected_pa_requests=*/{}, + /*expected_bid_in_seller_currency=*/absl::nullopt, + run_loop3.QuitClosure()); TestDevToolsAgentClient::Event breakpoint_hit3 = debug.WaitForMethodNotification("Debugger.paused"); @@ -3501,7 +3651,8 @@ /*expected_debug_win_report_url=*/absl::nullopt, /*expected_reject_reason=*/ mojom::RejectReason::kNotAvailable, - /*expected_pa_requests=*/{}, base::BindOnce([]() { + /*expected_pa_requests=*/{}, + /*expected_bid_in_seller_currency=*/absl::nullopt, base::BindOnce([]() { ADD_FAILURE() << "scoreAd shouldn't actually get to finish."; })); @@ -4134,8 +4285,8 @@ [&run_loop](double score, mojom::RejectReason reject_reason, mojom::ComponentAuctionModifiedBidParamsPtr component_auction_modified_bid_params, - uint32_t scoring_signals_data_version, - bool has_scoring_signals_data_version, + absl::optional<double> bid_in_seller_currency, + absl::optional<uint32_t> scoring_signals_data_version, const absl::optional<GURL>& debug_loss_report_url, const absl::optional<GURL>& debug_win_report_url, PrivateAggregationRequests pa_requests,
diff --git a/content/services/auction_worklet/set_bid_bindings.cc b/content/services/auction_worklet/set_bid_bindings.cc index cd14f62..a8bd862 100644 --- a/content/services/auction_worklet/set_bid_bindings.cc +++ b/content/services/auction_worklet/set_bid_bindings.cc
@@ -144,7 +144,7 @@ base::TimeTicks start, bool has_top_level_seller_origin, const mojom::BidderWorkletNonSharedParams* bidder_worklet_non_shared_params, - const std::string& per_buyer_currency, + const absl::optional<blink::AdCurrency>& per_buyer_currency, base::RepeatingCallback<bool(const GURL&)> is_ad_excluded, base::RepeatingCallback<bool(const GURL&)> is_component_ad_excluded) { DCHECK(bidder_worklet_non_shared_params->ads.has_value()); @@ -171,7 +171,7 @@ bid_.reset(); // Make sure we don't keep any dangling references to auction input. bidder_worklet_non_shared_params_ = nullptr; - per_buyer_currency_.clear(); + per_buyer_currency_ = absl::nullopt; is_ad_excluded_.Reset(); is_component_ad_excluded_.Reset(); } @@ -240,21 +240,23 @@ return true; } - std::string bid_currency = blink::kUnspecifiedAdCurrency; - if (result_dict.Get("bidCurrency", &bid_currency)) { - if (!blink::IsValidAdCurrencyCode(bid_currency)) { + absl::optional<blink::AdCurrency> bid_currency; + std::string bid_currency_str; + if (result_dict.Get("bidCurrency", &bid_currency_str)) { + if (!blink::IsValidAdCurrencyCode(bid_currency_str)) { errors_out.push_back( base::StringPrintf("%sbidCurrency of '%s' is not a currency code.", - error_prefix.c_str(), bid_currency.c_str())); + error_prefix.c_str(), bid_currency_str.c_str())); return false; } + bid_currency = blink::AdCurrency::From(bid_currency_str); } if (!blink::VerifyAdCurrencyCode(per_buyer_currency_, bid_currency)) { errors_out.push_back(base::StringPrintf( "%sbidCurrency mismatch; returned '%s', expected '%s'.", - error_prefix.c_str(), bid_currency.c_str(), - per_buyer_currency_.c_str())); + error_prefix.c_str(), blink::PrintableAdCurrency(bid_currency).c_str(), + blink::PrintableAdCurrency(per_buyer_currency_).c_str())); return false; }
diff --git a/content/services/auction_worklet/set_bid_bindings.h b/content/services/auction_worklet/set_bid_bindings.h index 060d9dd..7862bac4 100644 --- a/content/services/auction_worklet/set_bid_bindings.h +++ b/content/services/auction_worklet/set_bid_bindings.h
@@ -13,6 +13,7 @@ #include "content/services/auction_worklet/context_recycler.h" #include "content/services/auction_worklet/public/mojom/bidder_worklet.mojom-forward.h" #include "third_party/abseil-cpp/absl/types/optional.h" +#include "third_party/blink/public/common/interest_group/ad_auction_currencies.h" #include "third_party/blink/public/common/interest_group/interest_group.h" #include "url/gurl.h" #include "v8/include/v8-forward.h" @@ -35,7 +36,7 @@ bool has_top_level_seller_origin, const mojom::BidderWorkletNonSharedParams* bidder_worklet_non_shared_params, - const std::string& per_buyer_currency, + const absl::optional<blink::AdCurrency>& per_buyer_currency, base::RepeatingCallback<bool(const GURL&)> is_ad_excluded, base::RepeatingCallback<bool(const GURL&)> is_component_ad_excluded); @@ -62,7 +63,7 @@ raw_ptr<const mojom::BidderWorkletNonSharedParams> bidder_worklet_non_shared_params_ = nullptr; - std::string per_buyer_currency_; + absl::optional<blink::AdCurrency> per_buyer_currency_; // Callbacks set by ReInitialize and cleared by Reset which tell if an ad URL // can be used in a valid bid. Used to check the bid for non-k-anonymous ads.
diff --git a/content/test/data/interest_group/bidding_argument_validator.js b/content/test/data/interest_group/bidding_argument_validator.js index 879294b..0c1125f 100644 --- a/content/test/data/interest_group/bidding_argument_validator.js +++ b/content/test/data/interest_group/bidding_argument_validator.js
@@ -182,7 +182,7 @@ if (browserSignals.prevWins.length !== 0) throw 'Wrong prevWins ' + JSON.stringify(browserSignals.prevWins); } else { - if (Object.keys(browserSignals).length !== 11) { + if (Object.keys(browserSignals).length !== 13) { throw 'Wrong number of browser signals fields ' + JSON.stringify(browserSignals); } @@ -194,10 +194,16 @@ throw 'Wrong renderUrl ' + browserSignals.renderUrl; if (browserSignals.bid !== 2) throw 'Wrong bid ' + browserSignals.bid; + if (browserSignals.bidCurrency !== 'USD') + throw 'Wrong bidCurrency ' + browserSignals.bidCurrency; if (browserSignals.highestScoringOtherBid !== 0) { throw 'Wrong highestScoringOtherBid ' + browserSignals.highestScoringOtherBid; } + if (browserSignals.highestScoringOtherBidCurrency !== 'EUR') { + throw 'Wrong highestScoringOtherBidCurrency ' + + browserSignals.highestScoringOtherBidCurrency; + } if (browserSignals.adCost !== 3) throw 'Wrong adCost ' + browserSignals.adCost; }
diff --git a/content/test/data/interest_group/component_auction_bidding_argument_validator.js b/content/test/data/interest_group/component_auction_bidding_argument_validator.js index fc0d955..fcb3d02 100644 --- a/content/test/data/interest_group/component_auction_bidding_argument_validator.js +++ b/content/test/data/interest_group/component_auction_bidding_argument_validator.js
@@ -166,7 +166,7 @@ if (browserSignals.prevWins.length !== 0) throw 'Wrong prevWins ' + JSON.stringify(browserSignals.prevWins); } else { - if (Object.keys(browserSignals).length !== 12) { + if (Object.keys(browserSignals).length !== 14) { throw 'Wrong number of browser signals fields ' + JSON.stringify(browserSignals); } @@ -178,10 +178,16 @@ throw 'Wrong renderUrl ' + browserSignals.renderUrl; if (browserSignals.bid !== 2) throw 'Wrong bid ' + browserSignals.bid; + if (browserSignals.bidCurrency !== 'USD') + throw 'Wrong bidCurrency ' + browserSignals.bidCurrency; if (browserSignals.highestScoringOtherBid !== 0) { throw 'Wrong highestScoringOtherBid ' + browserSignals.highestScoringOtherBid; } + if (browserSignals.highestScoringOtherBidCurrency !== 'CAD') { + throw 'Wrong highestScoringOtherBidCurrency ' + + browserSignals.highestScoringOtherBidCurrency; + } if (browserSignals.adCost !== 3) throw 'Wrong adCost ' + browserSignals.adCost; }
diff --git a/content/test/data/interest_group/component_auction_component_decision_argument_validator.js b/content/test/data/interest_group/component_auction_component_decision_argument_validator.js index e96c907..53bc0150 100644 --- a/content/test/data/interest_group/component_auction_component_decision_argument_validator.js +++ b/content/test/data/interest_group/component_auction_component_decision_argument_validator.js
@@ -159,17 +159,26 @@ if (browserSignals.bidCurrency != 'USD') throw 'Wrong bidCurrency ' + browserSignals.bidCurrency; } else { - if (Object.keys(browserSignals).length !== 10) { + if (Object.keys(browserSignals).length !== 12) { throw 'Wrong number of browser signals fields ' + JSON.stringify(browserSignals); } - validateBid(browserSignals.bid); + // sellerCurrency is CAD, but the incombing bid is in USD, and no conversion + // is provided, so the bid is blanked. + if (browserSignals.bidCurrency !== 'CAD') + throw 'Wrong bidCurrency ' + browserSignals.bidCurrency; + if (browserSignals.bid !== 0) + throw 'Wrong bid ' + browserSignals.bid; if (browserSignals.desirability !== 13) throw 'Wrong desireability ' + browserSignals.desirability; if (browserSignals.highestScoringOtherBid !== 0) { throw 'Wrong highestScoringOtherBid ' + browserSignals.highestScoringOtherBid; } + if (browserSignals.highestScoringOtherBidCurrency !== 'CAD') { + throw 'Wrong highestScoringOtherBidCurrency ' + + browserSignals.highestScoringOtherBidCurrency; + } if (browserSignals.dataVersion !== 5678) throw 'Wrong dataVersion ' + browserSignals.dataVersion; if (browserSignals.modifiedBid !== 42)
diff --git a/content/test/data/interest_group/component_auction_top_level_decision_argument_validator.js b/content/test/data/interest_group/component_auction_top_level_decision_argument_validator.js index 2799f8a..6a3e2ab9 100644 --- a/content/test/data/interest_group/component_auction_top_level_decision_argument_validator.js +++ b/content/test/data/interest_group/component_auction_top_level_decision_argument_validator.js
@@ -170,10 +170,14 @@ if (browserSignals.bidCurrency !== 'CAD') throw 'Wrong bidCurrency ' + browserSignals.bidCurrency; } else { - if (Object.keys(browserSignals).length !== 8) { + if (Object.keys(browserSignals).length !== 10) { throw 'Wrong number of browser signals fields ' + JSON.stringify(browserSignals); } + // We don't have sellerCurrency in top-level, so we just get a blanked out + // indication that bidder currency was used. + if (browserSignals.bidCurrency !== '???') + throw 'Wrong bidCurrency ' + browserSignals.bidCurrency; validateBid(browserSignals.bid); if (browserSignals.desirability !== 37) throw 'Wrong desireability ' + browserSignals.desirability; @@ -181,6 +185,10 @@ throw 'Wrong highestScoringOtherBid ' + browserSignals.highestScoringOtherBid; } + if (browserSignals.highestScoringOtherBidCurrency !== '???') { + throw 'Wrong highestScoringOtherBidCurrency ' + + browserSignals.highestScoringOtherBidCurrency; + } if (browserSignals.dataVersion !== 1234) throw 'Wrong dataVersion ' + browserSignals.dataVersion; }
diff --git a/content/test/data/interest_group/decision_argument_validator.js b/content/test/data/interest_group/decision_argument_validator.js index 6166f36c..c50350f 100644 --- a/content/test/data/interest_group/decision_argument_validator.js +++ b/content/test/data/interest_group/decision_argument_validator.js
@@ -11,6 +11,9 @@ validateTrustedScoringSignals(trustedScoringSignals); validateBrowserSignals(browserSignals, /*isScoreAd=*/true); validateDirectFromSellerSignals(directFromSellerSignals); + if (browserSignals.bidCurrency === 'USD') { + return {desirability: bid, incomingBidInSellerCurrency: bid * 0.91}; + } return bid; } @@ -36,7 +39,7 @@ } function validateAuctionConfig(auctionConfig) { - if (Object.keys(auctionConfig).length !== 12) { + if (Object.keys(auctionConfig).length !== 13) { throw 'Wrong number of auctionConfig fields ' + JSON.stringify(auctionConfig); } @@ -109,6 +112,10 @@ throw 'Wrong perBuyerCurrencies ' + JSON.stringify(auctionConfig.perBuyerCurrencies); } + if (auctionConfig.sellerCurrency !== 'EUR') { + throw 'Wrong sellerCurrency ' + + JSON.stringify(auctionConfig.sellerCurrency); + } const perBuyerPrioritySignals = auctionConfig.perBuyerPrioritySignals; if (Object.keys(perBuyerPrioritySignals).length !== 2 || @@ -167,17 +174,26 @@ if (browserSignals.bidCurrency !== 'USD') throw 'Wrong bidCurrency ' + browserSignals.bidCurrency; } else { - if (Object.keys(browserSignals).length !== 7) { + if (Object.keys(browserSignals).length !== 9) { throw 'Wrong number of browser signals fields ' + JSON.stringify(browserSignals); } - validateBid(browserSignals.bid); + // Test configures sellerCurrency to EUR, and our scoreAd provides + // conversion, so bid should be in euros. + if (browserSignals.bidCurrency !== 'EUR') + throw 'Wrong bidCurrency ' + browserSignals.bidCurrency; + validateBid(browserSignals.bid / 0.91); + if (browserSignals.desirability !== 2) throw 'Wrong desireability ' + browserSignals.desirability; if (browserSignals.highestScoringOtherBid !== 0) { throw 'Wrong highestScoringOtherBid ' + browserSignals.highestScoringOtherBid; } + if (browserSignals.highestScoringOtherBidCurrency !== 'EUR') { + throw 'Wrong highestScoringOtherBidCurrency ' + + browserSignals.highestScoringOtherBidCurrency; + } } }
diff --git a/device/vr/BUILD.gn b/device/vr/BUILD.gn index 8985b8b..031d99f 100644 --- a/device/vr/BUILD.gn +++ b/device/vr/BUILD.gn
@@ -51,6 +51,8 @@ defines = [ "IS_DEVICE_VR_BASE_IMPL" ] sources = [ + "create_anchor_request.cc", + "create_anchor_request.h", "vr_device.h", "vr_device_base.cc", "vr_device_base.h", @@ -191,8 +193,6 @@ "openxr/context_provider_callbacks.h", "openxr/openxr_anchor_manager.cc", "openxr/openxr_anchor_manager.h", - "openxr/openxr_anchor_request.cc", - "openxr/openxr_anchor_request.h", "openxr/openxr_api_wrapper.cc", "openxr/openxr_api_wrapper.h", "openxr/openxr_controller.cc",
diff --git a/device/vr/android/arcore/arcore_impl.cc b/device/vr/android/arcore/arcore_impl.cc index b64e86378f..562de6e 100644 --- a/device/vr/android/arcore/arcore_impl.cc +++ b/device/vr/android/arcore/arcore_impl.cc
@@ -19,6 +19,7 @@ #include "device/vr/android/arcore/arcore_math_utils.h" #include "device/vr/android/arcore/arcore_plane_manager.h" #include "device/vr/android/arcore/type_converters.h" +#include "device/vr/create_anchor_request.h" #include "device/vr/public/mojom/pose.h" #include "device/vr/public/mojom/vr_service.mojom.h" #include "device/vr/public/mojom/xr_session.mojom.h" @@ -2015,39 +2016,11 @@ return std::make_unique<ArCoreImpl>(); } -CreateAnchorRequest::CreateAnchorRequest( - const mojom::XRNativeOriginInformation& native_origin_information, - const gfx::Transform& native_origin_from_anchor, - ArCore::CreateAnchorCallback callback) - : native_origin_information_(native_origin_information.Clone()), - native_origin_from_anchor_(native_origin_from_anchor), - request_start_time_(base::TimeTicks::Now()), - callback_(std::move(callback)) {} -CreateAnchorRequest::CreateAnchorRequest(CreateAnchorRequest&& other) = default; -CreateAnchorRequest::~CreateAnchorRequest() = default; - -const mojom::XRNativeOriginInformation& -CreateAnchorRequest::GetNativeOriginInformation() const { - return *native_origin_information_; -} - -gfx::Transform CreateAnchorRequest::GetNativeOriginFromAnchor() const { - return native_origin_from_anchor_; -} - -base::TimeTicks CreateAnchorRequest::GetRequestStartTime() const { - return request_start_time_; -} - -ArCore::CreateAnchorCallback CreateAnchorRequest::TakeCallback() { - return std::move(callback_); -} - CreatePlaneAttachedAnchorRequest::CreatePlaneAttachedAnchorRequest( const mojom::XRNativeOriginInformation& native_origin_information, const gfx::Transform& native_origin_from_anchor, uint64_t plane_id, - ArCore::CreateAnchorCallback callback) + CreateAnchorCallback callback) : native_origin_information_(native_origin_information.Clone()), native_origin_from_anchor_(native_origin_from_anchor), plane_id_(plane_id), @@ -2075,7 +2048,7 @@ return request_start_time_; } -ArCore::CreateAnchorCallback CreatePlaneAttachedAnchorRequest::TakeCallback() { +CreateAnchorCallback CreatePlaneAttachedAnchorRequest::TakeCallback() { return std::move(callback_); }
diff --git a/device/vr/android/arcore/arcore_impl.h b/device/vr/android/arcore/arcore_impl.h index 510d428..dd653fc 100644 --- a/device/vr/android/arcore/arcore_impl.h +++ b/device/vr/android/arcore/arcore_impl.h
@@ -14,6 +14,7 @@ #include "device/vr/android/arcore/arcore_plane_manager.h" #include "device/vr/android/arcore/arcore_sdk.h" #include "device/vr/android/arcore/scoped_arcore_objects.h" +#include "device/vr/create_anchor_request.h" #include "device/vr/public/mojom/vr_service.mojom.h" #include "device/vr/public/mojom/xr_session.mojom.h" #include "device/vr/util/hit_test_subscription_data.h" @@ -25,29 +26,6 @@ using AnchorId = base::IdTypeU64<class AnchorTag>; -class CreateAnchorRequest { - public: - const mojom::XRNativeOriginInformation& GetNativeOriginInformation() const; - gfx::Transform GetNativeOriginFromAnchor() const; - base::TimeTicks GetRequestStartTime() const; - - ArCore::CreateAnchorCallback TakeCallback(); - - CreateAnchorRequest( - const mojom::XRNativeOriginInformation& native_origin_information, - const gfx::Transform& native_origin_from_anchor, - ArCore::CreateAnchorCallback callback); - CreateAnchorRequest(CreateAnchorRequest&& other); - ~CreateAnchorRequest(); - - private: - mojom::XRNativeOriginInformationPtr native_origin_information_; - const gfx::Transform native_origin_from_anchor_; - const base::TimeTicks request_start_time_; - - ArCore::CreateAnchorCallback callback_; -}; - class CreatePlaneAttachedAnchorRequest { public: uint64_t GetPlaneId() const; @@ -55,13 +33,13 @@ gfx::Transform GetNativeOriginFromAnchor() const; base::TimeTicks GetRequestStartTime() const; - ArCore::CreateAnchorCallback TakeCallback(); + CreateAnchorCallback TakeCallback(); CreatePlaneAttachedAnchorRequest( const mojom::XRNativeOriginInformation& native_origin_information, const gfx::Transform& native_origin_from_anchor, uint64_t plane_id, - ArCore::CreateAnchorCallback callback); + CreateAnchorCallback callback); CreatePlaneAttachedAnchorRequest(CreatePlaneAttachedAnchorRequest&& other); ~CreatePlaneAttachedAnchorRequest(); @@ -71,7 +49,7 @@ const uint64_t plane_id_; const base::TimeTicks request_start_time_; - ArCore::CreateAnchorCallback callback_; + CreateAnchorCallback callback_; }; // This class should be created and accessed entirely on a Gl thread.
diff --git a/device/vr/openxr/openxr_anchor_request.cc b/device/vr/create_anchor_request.cc similarity index 95% rename from device/vr/openxr/openxr_anchor_request.cc rename to device/vr/create_anchor_request.cc index 65c008c..57d7b45b 100644 --- a/device/vr/openxr/openxr_anchor_request.cc +++ b/device/vr/create_anchor_request.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "device/vr/openxr/openxr_anchor_request.h" +#include "device/vr/create_anchor_request.h" namespace device {
diff --git a/device/vr/openxr/openxr_anchor_request.h b/device/vr/create_anchor_request.h similarity index 83% rename from device/vr/openxr/openxr_anchor_request.h rename to device/vr/create_anchor_request.h index 5790fb4..5dc2e95 100644 --- a/device/vr/openxr/openxr_anchor_request.h +++ b/device/vr/create_anchor_request.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 DEVICE_VR_OPENXR_OPENXR_ANCHOR_REQUEST_H_ -#define DEVICE_VR_OPENXR_OPENXR_ANCHOR_REQUEST_H_ +#ifndef DEVICE_VR_CREATE_ANCHOR_REQUEST_H_ +#define DEVICE_VR_CREATE_ANCHOR_REQUEST_H_ +#include "base/component_export.h" #include "base/functional/callback.h" #include "base/time/time.h" #include "device/vr/public/mojom/vr_service.mojom.h" @@ -16,7 +17,7 @@ base::OnceCallback<void(device::mojom::CreateAnchorResult, uint64_t anchor_id)>; -class CreateAnchorRequest { +class COMPONENT_EXPORT(DEVICE_VR_BASE) CreateAnchorRequest { public: const mojom::XRNativeOriginInformation& GetNativeOriginInformation() const; const gfx::Transform& GetNativeOriginFromAnchor() const; @@ -41,4 +42,4 @@ } // namespace device -#endif // DEVICE_VR_OPENXR_OPENXR_ANCHOR_REQUEST_H_ +#endif // DEVICE_VR_CREATE_ANCHOR_REQUEST_H_
diff --git a/device/vr/openxr/openxr_anchor_manager.h b/device/vr/openxr/openxr_anchor_manager.h index acfc7d3d..28dc92c0 100644 --- a/device/vr/openxr/openxr_anchor_manager.h +++ b/device/vr/openxr/openxr_anchor_manager.h
@@ -10,7 +10,7 @@ #include "base/memory/raw_ref.h" #include "base/numerics/checked_math.h" #include "base/numerics/math_constants.h" -#include "device/vr/openxr/openxr_anchor_request.h" +#include "device/vr/create_anchor_request.h" #include "device/vr/openxr/openxr_util.h" #include "device/vr/public/mojom/vr_service.mojom.h" #include "third_party/abseil-cpp/absl/types/optional.h"
diff --git a/docs/speed/metrics_changelog/2023_01_inp.md b/docs/speed/metrics_changelog/2023_01_inp.md new file mode 100644 index 0000000..11f6f029 --- /dev/null +++ b/docs/speed/metrics_changelog/2023_01_inp.md
@@ -0,0 +1,20 @@ +# Interaction to Next Paint Changes in Chrome 109 + +## Chrome prioritizes compositing after input events + +A change in the Chrome scheduler to prioritize rendering after user interaction +resulted in multiple improvements to user-experienced Interaction to Next Paint. + +Applications with a large amount of typing on desktop saw improvements to their +slowest interaction times as many keypresses right after another displayed on +screen more quickly. + +Mobile sites in which users were tapping multiple times due to slow interactions +saw large improvements to interaction times, as 500ms+ interactions no longer +"piled up" waiting for the user to stop tapping before the screen began to update. + +Source code of the change is linked [in the chromium issue tracker](https://bugs.chromium.org/p/chromium/issues/detail?id=853771) + +## When were users affected? + +Chrome 109 was released the week of January 10, 2023.
diff --git a/docs/speed/metrics_changelog/2023_04_inp.md b/docs/speed/metrics_changelog/2023_04_inp.md new file mode 100644 index 0000000..1c519cb --- /dev/null +++ b/docs/speed/metrics_changelog/2023_04_inp.md
@@ -0,0 +1,20 @@ +# Interaction to Next Paint Changes in Chrome 111 + +## Bug fix: Event Timing API no longer reports very long durations when interaction leads to "open in new tab" + +This bug fix causes the Event Timing API to ignore the presentation time if +the page visibility changed. Before the bug fix, if the interaction caused the +page to be hidden, the `duration` in Event Timing would report the time the +page became visible again. This is technically the "next paint", but since it +involves waiting for the user to switch back to the page, it's not representative +of performance, so it is now ignored. + +This bug affected the Event Timing API _only_. The correct data has always been +reported to the Chrome User Experience report. So this is an issue developers +may see in real user monitoring analytics. + +[Source code](https://chromium-review.googlesource.com/c/chromium/src/+/3926369) + +## When were users affected? + +Chrome 111 was released the week of March 7, 2023.
diff --git a/docs/speed/metrics_changelog/README.md b/docs/speed/metrics_changelog/README.md index 54e552c..528ee1f 100644 --- a/docs/speed/metrics_changelog/README.md +++ b/docs/speed/metrics_changelog/README.md
@@ -6,7 +6,9 @@ * [First Input Delay](fid.md) * [Cumulative Layout Shift](cls.md) * [First Contentful Paint](fcp.md) + * [Interaction to Next Paint](inp.md) See also: - * [Lighthouse performance scoring changelog](https://web.dev/performance-scoring/) \ No newline at end of file + * [Lighthouse performance scoring changelog](https://web.dev/performance-scoring/) + * [Chrome UX Report Release Notes](https://developer.chrome.com/docs/crux/release-notes/) \ No newline at end of file
diff --git a/docs/speed/metrics_changelog/inp.md b/docs/speed/metrics_changelog/inp.md new file mode 100644 index 0000000..1da0c89e --- /dev/null +++ b/docs/speed/metrics_changelog/inp.md
@@ -0,0 +1,10 @@ +# Interaction to Next Paint Changelog + +This is a list of changes to [Interaction to Next Paint](https://web.dev/inp). + +* Chrome 111 + * Metric bug fix: [Event Timing API no longer reports very long durations when interaction leads to "open in new tab"](2023_04_inp.md) +* Chrome 109 + * Implementation optimizations: [A change in Chrome to prioritize compositing after input events caused a significant improvement to INP](2023_01_inp.md) +* Chrome 96 + * Experimental metric exposed via API: [Event Timing InteractionID](https://web.dev/inp/) available via [PerformanceObserver API](https://www.w3.org/TR/event-timing/)
diff --git a/extensions/common/api/_api_features.json b/extensions/common/api/_api_features.json index 3e2ad0a5..4f018dc 100644 --- a/extensions/common/api/_api_features.json +++ b/extensions/common/api/_api_features.json
@@ -557,7 +557,7 @@ "runtime.getContexts": { "min_manifest_version": 3, "contexts": ["blessed_extension"], - "channel": "trunk", + "channel": "dev", "feature_flag": "ApiRuntimeGetContexts" }, "runtime.getURL": {
diff --git a/extensions/common/extension_features.cc b/extensions/common/extension_features.cc index 3676dedd..a626d23 100644 --- a/extensions/common/extension_features.cc +++ b/extensions/common/extension_features.cc
@@ -14,7 +14,7 @@ // Controls the availability of the runtime.getContexts() API. BASE_FEATURE(kApiRuntimeGetContexts, "ApiRuntimeGetContexts", - base::FEATURE_DISABLED_BY_DEFAULT); + base::FEATURE_ENABLED_BY_DEFAULT); /////////////////////////////////////////////////////////////////////////////// // Other Features
diff --git a/fuchsia_web/webinstance_host/web_instance_host.cc b/fuchsia_web/webinstance_host/web_instance_host.cc index 9f11c0b2..f97b779b 100644 --- a/fuchsia_web/webinstance_host/web_instance_host.cc +++ b/fuchsia_web/webinstance_host/web_instance_host.cc
@@ -250,9 +250,9 @@ return base::unexpected(status); } - return base::ok(base::WrapUnique(new InstanceBuilder( + return base::WrapUnique(new InstanceBuilder( outgoing_directory, realm, std::move(instance_id), - std::move(instance_name), instance_dir_ptr, launch_args))); + std::move(instance_name), instance_dir_ptr, launch_args)); } InstanceBuilder::InstanceBuilder(sys::OutgoingDirectory& outgoing_directory,
diff --git a/gpu/command_buffer/service/copy_shared_image_helper.cc b/gpu/command_buffer/service/copy_shared_image_helper.cc index 828304ff..5952734 100644 --- a/gpu/command_buffer/service/copy_shared_image_helper.cc +++ b/gpu/command_buffer/service/copy_shared_image_helper.cc
@@ -9,6 +9,7 @@ #include "base/check.h" #include "base/strings/string_number_conversions.h" +#include "base/types/expected.h" #include "gpu/command_buffer/common/mailbox.h" #include "gpu/command_buffer/service/shared_context_state.h" #include "gpu/command_buffer/service/shared_image/shared_image_factory.h" @@ -99,21 +100,21 @@ SkYUVAInfo::kMaxPlanes>& yuva_images) { if (yuv_color_space_in < 0 || yuv_color_space_in > kLastEnum_SkYUVColorSpace) { - return base::unexpected<GLError>( + return base::unexpected( GLError(GL_INVALID_ENUM, function_name, "yuv_color_space must be a valid SkYUVColorSpace")); } sk_yuv_color_space = static_cast<SkYUVColorSpace>(yuv_color_space_in); if (plane_config_in < 0 || plane_config_in > static_cast<GLenum>(SkYUVAInfo::PlaneConfig::kLast)) { - return base::unexpected<GLError>( + return base::unexpected( GLError(GL_INVALID_ENUM, function_name, "plane_config must be a valid SkYUVAInfo::PlaneConfig")); } sk_plane_config = static_cast<SkYUVAInfo::PlaneConfig>(plane_config_in); if (subsampling_in < 0 || subsampling_in > static_cast<GLenum>(SkYUVAInfo::Subsampling::kLast)) { - return base::unexpected<GLError>( + return base::unexpected( GLError(GL_INVALID_ENUM, function_name, "subsampling must be a valid SkYUVAInfo::Subsampling")); } @@ -144,14 +145,14 @@ "Attempting to operate on unknown mailbox for plane index " + base::NumberToString(i) + " using plane config " + base::NumberToString(plane_config_in) + "."; - return base::unexpected<GLError>( + return base::unexpected( GLError(GL_INVALID_OPERATION, function_name, msg)); } } rgba_image = representation_factory->ProduceSkia(rgba_mailbox, shared_context_state); if (!rgba_image) { - return base::unexpected<GLError>( + return base::unexpected( GLError(GL_INVALID_OPERATION, "ConvertYUVAMailboxesToRGB", "Attempting to operate on unknown dest mailbox.")); } @@ -330,16 +331,16 @@ rgba_image->BeginScopedReadAccess(&begin_semaphores, &end_semaphores); if (!rgba_scoped_access) { DCHECK(begin_semaphores.empty()); - return base::unexpected<GLError>( - GLError(GL_INVALID_OPERATION, "glConvertYUVAMailboxesToRGB", - "RGBA shared image is not readable")); + return base::unexpected(GLError(GL_INVALID_OPERATION, + "glConvertYUVAMailboxesToRGB", + "RGBA shared image is not readable")); } auto rgba_sk_image = rgba_scoped_access->CreateSkImage(shared_context_state_->gr_context()); if (!rgba_sk_image) { - return base::unexpected<GLError>( - GLError(GL_INVALID_OPERATION, "glReadbackImagePixels", - "Couldn't create SkImage for reading.")); + return base::unexpected(GLError(GL_INVALID_OPERATION, + "glReadbackImagePixels", + "Couldn't create SkImage for reading.")); } std::array<std::unique_ptr<SkiaImageRepresentation::ScopedWriteAccess>, @@ -354,7 +355,7 @@ "Couldn't write shared image for mailbox of plane index " + base::NumberToString(i) + " using plane config " + base::NumberToString(plane_config) + "."; - return base::unexpected<GLError>( + return base::unexpected( GLError(GL_INVALID_OPERATION, "glConvertRGBAToYUVAMailboxes", msg)); } } @@ -417,7 +418,7 @@ SharedImageRepresentation::AllowUnclearedAccess::kYes); if (!dest_scoped_access) { DCHECK(begin_semaphores.empty()); - return base::unexpected<GLError>( + return base::unexpected( GLError(GL_INVALID_VALUE, "glConvertYUVAMailboxesToRGB", "Destination shared image is not writable")); } @@ -436,7 +437,7 @@ "Couldn't access shared image for mailbox of plane index " + base::NumberToString(i) + " using plane config " + base::NumberToString(plane_config) + "."; - result = base::unexpected<GLError>( + result = base::unexpected( GLError(GL_INVALID_OPERATION, "glConvertYUVAMailboxesToRGB", msg)); break; } @@ -475,7 +476,7 @@ shared_context_state_->gr_context(), yuva_backend_textures, src_rgb_color_space); if (!result_image) { - result = base::unexpected<GLError>( + result = base::unexpected( GLError(GL_INVALID_OPERATION, "glConvertYUVAMailboxesToRGB", "Couldn't create destination images from provided sources")); } else { @@ -522,7 +523,7 @@ << "CopySubTexture was passed an invalid mailbox"; if (source_mailbox == dest_mailbox) { - return base::unexpected<GLError>( + return base::unexpected( GLError(GL_INVALID_OPERATION, "glCopySubTexture", "source and destination mailboxes are the same")); } @@ -531,16 +532,15 @@ dest_mailbox, scoped_refptr<gpu::SharedContextState>(shared_context_state_)); if (!dest_shared_image) { - return base::unexpected<GLError>( + return base::unexpected( GLError(GL_INVALID_VALUE, "glCopySubTexture", "unknown mailbox")); } gfx::Size dest_size = dest_shared_image->size(); gfx::Rect dest_rect(xoffset, yoffset, width, height); if (!gfx::Rect(dest_size).Contains(dest_rect)) { - return base::unexpected<GLError>( - GLError(GL_INVALID_VALUE, "glCopySubTexture", - "destination texture bad dimensions.")); + return base::unexpected(GLError(GL_INVALID_VALUE, "glCopySubTexture", + "destination texture bad dimensions.")); } std::vector<GrBackendSemaphore> begin_semaphores; @@ -552,24 +552,21 @@ &begin_semaphores, &end_semaphores, SharedImageRepresentation::AllowUnclearedAccess::kYes); if (!dest_scoped_access) { - return base::unexpected<GLError>( - GLError(GL_INVALID_VALUE, "glCopySubTexture", - "Dest shared image is not writable")); + return base::unexpected(GLError(GL_INVALID_VALUE, "glCopySubTexture", + "Dest shared image is not writable")); } gfx::Rect new_cleared_rect; gfx::Rect old_cleared_rect = dest_shared_image->ClearedRect(); - if (gles2::TextureManager::CombineAdjacentRects(old_cleared_rect, dest_rect, - &new_cleared_rect)) { - DCHECK(old_cleared_rect.IsEmpty() || - new_cleared_rect.Contains(old_cleared_rect)); - } else { + if (!gles2::TextureManager::CombineAdjacentRects(old_cleared_rect, dest_rect, + &new_cleared_rect)) { // No users of RasterDecoder leverage this functionality. Clearing uncleared // regions could be added here if needed. - return base::unexpected<GLError>( - GLError(GL_INVALID_VALUE, "glCopySubTexture", - "Cannot clear non-combineable rects.")); + return base::unexpected(GLError(GL_INVALID_VALUE, "glCopySubTexture", + "Cannot clear non-combineable rects.")); } + DCHECK(old_cleared_rect.IsEmpty() || + new_cleared_rect.Contains(old_cleared_rect)); // Attempt to upload directly from CPU shared memory to destination texture. if (TryCopySubTextureINTERNALMemory( @@ -606,16 +603,15 @@ // Note, that we still generate error for the client to indicate there was // problem. - return base::unexpected<GLError>(GLError( - GL_INVALID_VALUE, "glCopySubTexture", "unknown source image mailbox.")); + return base::unexpected(GLError(GL_INVALID_VALUE, "glCopySubTexture", + "unknown source image mailbox.")); } gfx::Size source_size = source_shared_image->size(); gfx::Rect source_rect(x, y, width, height); if (!gfx::Rect(source_size).Contains(source_rect)) { - return base::unexpected<GLError>(GLError(GL_INVALID_VALUE, - "glCopySubTexture", - "source texture bad dimensions.")); + return base::unexpected(GLError(GL_INVALID_VALUE, "glCopySubTexture", + "source texture bad dimensions.")); } std::unique_ptr<SkiaImageRepresentation::ScopedReadAccess> @@ -632,16 +628,15 @@ FlushSurface(dest_scoped_access.get()); SubmitIfNecessary(std::move(end_semaphores), shared_context_state_, is_drdc_enabled_); - return base::unexpected<GLError>( - GLError(GL_INVALID_VALUE, "glCopySubTexture", - "Source shared image is not accessable")); + return base::unexpected(GLError(GL_INVALID_VALUE, "glCopySubTexture", + "Source shared image is not accessable")); } base::expected<void, GLError> result = base::ok(); auto source_image = source_scoped_access->CreateSkImage(shared_context_state_->gr_context()); if (!source_image) { - result = base::unexpected<GLError>( + result = base::unexpected( GLError(GL_INVALID_VALUE, "glCopySubTexture", "Couldn't create SkImage from source shared image.")); } else { @@ -844,9 +839,8 @@ &begin_semaphores, &end_semaphores); if (!source_scoped_access) { - return base::unexpected<GLError>( - GLError(GL_INVALID_VALUE, "glReadbackImagePixels", - "Source shared image is not accessible")); + return base::unexpected(GLError(GL_INVALID_VALUE, "glReadbackImagePixels", + "Source shared image is not accessible")); } if (!begin_semaphores.empty()) { @@ -869,18 +863,15 @@ } base::expected<void, GLError> result = base::ok(); - if (sk_image) { - bool success = - sk_image->readPixels(dst_info, pixel_address, row_bytes, src_x, src_y); - if (!success) { - result = base::unexpected<GLError>( - GLError(GL_INVALID_OPERATION, "glReadbackImagePixels", - "Failed to read pixels from SkImage")); - } - } else { - result = base::unexpected<GLError>( - GLError(GL_INVALID_OPERATION, "glReadbackImagePixels", - "Couldn't create SkImage for reading.")); + if (!sk_image) { + result = + base::unexpected(GLError(GL_INVALID_OPERATION, "glReadbackImagePixels", + "Couldn't create SkImage for reading.")); + } else if (!sk_image->readPixels(dst_info, pixel_address, row_bytes, src_x, + src_y)) { + result = + base::unexpected(GLError(GL_INVALID_OPERATION, "glReadbackImagePixels", + "Failed to read pixels from SkImage")); } source_scoped_access->ApplyBackendSurfaceEndState();
diff --git a/infra/config/console-header.star b/infra/config/console-header.star index 8580c227..190e6bd 100644 --- a/infra/config/console-header.star +++ b/infra/config/console-header.star
@@ -197,16 +197,16 @@ alt = "Chromium GPU console", ), headers.link( + text = "infra", + url = "/p/{}/g/chromium.infra".format(settings.project), + alt = "Chromium Infra console", + ), + headers.link( text = "memory.fyi", url = "/p/{}/g/chromium.memory.fyi".format(settings.project), alt = "Chromium Memory FYI console", ), headers.link( - text = "packager", - url = "/p/{}/g/chromium.packager".format(settings.project), - alt = "Chromium Packager console", - ), - headers.link( text = "perf", url = "/p/chrome/g/chrome.perf/console", alt = "Chromium Perf console",
diff --git a/infra/config/dev/subprojects/chromium/ci.star b/infra/config/dev/subprojects/chromium/ci.star index c263b9d3..ee0fea08 100644 --- a/infra/config/dev/subprojects/chromium/ci.star +++ b/infra/config/dev/subprojects/chromium/ci.star
@@ -140,7 +140,7 @@ ) ci_builder( - name = "linux-ssd-rel-dev", + name = "linux-local-ssd-rel-dev", description_html = "Ensures builders are using available local SSDs", builder_spec = builder_config.builder_spec( gclient_config = builder_config.gclient_config(config = "chromium"), @@ -154,6 +154,21 @@ ) ci_builder( + name = "linux-remote-ssd-rel-dev", + description_html = "Ensures builders are using available remote SSDs. See b/279078023 for context.", + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config(config = "chromium"), + chromium_config = builder_config.chromium_config( + config = "chromium", + apply_configs = ["mb"], + build_config = builder_config.build_config.RELEASE, + ), + ), + builderless = False, + ssd = True, +) + +ci_builder( name = "mac-rel-dev", builder_spec = builder_config.builder_spec( gclient_config = builder_config.gclient_config(config = "chromium"),
diff --git a/infra/config/dev/subprojects/chromium/consoles/chromium.swarm.star b/infra/config/dev/subprojects/chromium/consoles/chromium.swarm.star index 041b2b74..ebf9a0e 100644 --- a/infra/config/dev/subprojects/chromium/consoles/chromium.swarm.star +++ b/infra/config/dev/subprojects/chromium/consoles/chromium.swarm.star
@@ -10,7 +10,8 @@ luci.console_view_entry(builder = "ci/android-pie-arm64-rel-dev"), luci.console_view_entry(builder = "ci/linux-rel-dev"), luci.console_view_entry(builder = "ci/linux-rel-jammy-dev"), - luci.console_view_entry(builder = "ci/linux-ssd-rel-dev"), + luci.console_view_entry(builder = "ci/linux-local-ssd-rel-dev"), + luci.console_view_entry(builder = "ci/linux-remote-ssd-rel-dev"), luci.console_view_entry(builder = "ci/mac-rel-dev"), luci.console_view_entry(builder = "ci/mac-arm-rel-dev"), luci.console_view_entry(builder = "ci/win-rel-dev"),
diff --git a/infra/config/generated/builders/ci/chromeos-amd64-generic-rel/properties.json b/infra/config/generated/builders/ci/chromeos-amd64-generic-rel/properties.json index e00afc7..3c74814 100644 --- a/infra/config/generated/builders/ci/chromeos-amd64-generic-rel/properties.json +++ b/infra/config/generated/builders/ci/chromeos-amd64-generic-rel/properties.json
@@ -51,6 +51,10 @@ { "builder": "chromeos-amd64-generic-rel", "group": "tryserver.chromium.chromiumos" + }, + { + "builder": "chromeos-amd64-generic-rel-rts", + "group": "tryserver.chromium.chromiumos" } ] }
diff --git a/infra/config/generated/builders/ci/linux-chromeos-rel/properties.json b/infra/config/generated/builders/ci/linux-chromeos-rel/properties.json index 6d01363..7fca0247 100644 --- a/infra/config/generated/builders/ci/linux-chromeos-rel/properties.json +++ b/infra/config/generated/builders/ci/linux-chromeos-rel/properties.json
@@ -48,6 +48,10 @@ { "builder": "linux-chromeos-rel", "group": "tryserver.chromium.chromiumos" + }, + { + "builder": "linux-chromeos-rel-rts", + "group": "tryserver.chromium.chromiumos" } ] }
diff --git a/infra/config/generated/builders/ci/linux-lacros-builder-rel/properties.json b/infra/config/generated/builders/ci/linux-lacros-builder-rel/properties.json index 5391c704..fe7d0e9 100644 --- a/infra/config/generated/builders/ci/linux-lacros-builder-rel/properties.json +++ b/infra/config/generated/builders/ci/linux-lacros-builder-rel/properties.json
@@ -83,6 +83,10 @@ { "builder": "linux-lacros-rel", "group": "tryserver.chromium.chromiumos" + }, + { + "builder": "linux-lacros-rel-rts", + "group": "tryserver.chromium.chromiumos" } ] }
diff --git a/infra/config/generated/builders/ci/linux-lacros-tester-rel/properties.json b/infra/config/generated/builders/ci/linux-lacros-tester-rel/properties.json index 7f25f7f..a06eb6c 100644 --- a/infra/config/generated/builders/ci/linux-lacros-tester-rel/properties.json +++ b/infra/config/generated/builders/ci/linux-lacros-tester-rel/properties.json
@@ -76,6 +76,10 @@ { "builder": "linux-lacros-rel", "group": "tryserver.chromium.chromiumos" + }, + { + "builder": "linux-lacros-rel-rts", + "group": "tryserver.chromium.chromiumos" } ] }
diff --git "a/infra/config/generated/builders/reclient/Linux Builder reclient test \050unified uploads\051 untrusted/properties.json" "b/infra/config/generated/builders/reclient/Linux Builder reclient test \050unified uploads\051 untrusted/properties.json" new file mode 100644 index 0000000..92671a3a --- /dev/null +++ "b/infra/config/generated/builders/reclient/Linux Builder reclient test \050unified uploads\051 untrusted/properties.json"
@@ -0,0 +1,62 @@ +{ + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "reclient", + "builder": "Linux Builder reclient test (unified uploads) untrusted", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-fyi-archive", + "builder_group": "chromium.reclient.fyi", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "chromium", + "target_bits": 64 + }, + "legacy_gclient_config": { + "apply_configs": [ + "use_clang_coverage", + "reclient_test" + ], + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "reclient", + "builder": "Linux Builder reclient test (unified uploads) untrusted", + "project": "chromium" + } + ] + } + }, + "$build/reclient": { + "bootstrap_env": { + "GLOG_use_unified_uploads": "true", + "GOMA_COMPILER_PROXY_ENABLE_CRASH_DUMP": "true" + }, + "instance": "rbe-chromium-untrusted-test", + "metrics_project": "chromium-reclient-metrics", + "scandeps_server": true + }, + "$recipe_engine/resultdb/test_presentation": { + "column_keys": [], + "grouping_keys": [ + "status", + "v.test_suite" + ] + }, + "builder_group": "chromium.reclient.fyi", + "recipe": "chromium" +} \ No newline at end of file
diff --git "a/infra/config/generated/builders/reclient/Linux Builder reclient test \050unified uploads\051/properties.json" "b/infra/config/generated/builders/reclient/Linux Builder reclient test \050unified uploads\051/properties.json" new file mode 100644 index 0000000..e83db50 --- /dev/null +++ "b/infra/config/generated/builders/reclient/Linux Builder reclient test \050unified uploads\051/properties.json"
@@ -0,0 +1,62 @@ +{ + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "reclient", + "builder": "Linux Builder reclient test (unified uploads)", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-fyi-archive", + "builder_group": "chromium.reclient.fyi", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "chromium", + "target_bits": 64 + }, + "legacy_gclient_config": { + "apply_configs": [ + "use_clang_coverage", + "reclient_test" + ], + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "reclient", + "builder": "Linux Builder reclient test (unified uploads)", + "project": "chromium" + } + ] + } + }, + "$build/reclient": { + "bootstrap_env": { + "GLOG_use_unified_uploads": "true", + "GOMA_COMPILER_PROXY_ENABLE_CRASH_DUMP": "true" + }, + "instance": "rbe-chromium-trusted-test", + "metrics_project": "chromium-reclient-metrics", + "scandeps_server": true + }, + "$recipe_engine/resultdb/test_presentation": { + "column_keys": [], + "grouping_keys": [ + "status", + "v.test_suite" + ] + }, + "builder_group": "chromium.reclient.fyi", + "recipe": "chromium" +} \ No newline at end of file
diff --git a/infra/config/generated/builders/try/chromeos-amd64-generic-rel-rts/properties.json b/infra/config/generated/builders/try/chromeos-amd64-generic-rel-rts/properties.json new file mode 100644 index 0000000..297ba60 --- /dev/null +++ b/infra/config/generated/builders/try/chromeos-amd64-generic-rel-rts/properties.json
@@ -0,0 +1,69 @@ +{ + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "chromeos-amd64-generic-rel", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-chromiumos-archive", + "builder_group": "chromium.chromiumos", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "chromium", + "cros_boards_with_qemu_images": [ + "amd64-generic-vm" + ], + "target_arch": "intel", + "target_bits": 64, + "target_cros_boards": [ + "amd64-generic" + ], + "target_platform": "chromeos" + }, + "legacy_gclient_config": { + "apply_configs": [ + "chromeos", + "checkout_lacros_sdk" + ], + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "chromeos-amd64-generic-rel", + "project": "chromium" + } + ], + "rts_config": { + "condition": "QUICK_RUN_ONLY" + } + } + }, + "$build/reclient": { + "instance": "rbe-chromium-untrusted", + "jobs": 150, + "metrics_project": "chromium-reclient-metrics" + }, + "$recipe_engine/resultdb/test_presentation": { + "column_keys": [], + "grouping_keys": [ + "status", + "v.test_suite" + ] + }, + "builder_group": "tryserver.chromium.chromiumos", + "recipe": "chromium_trybot" +} \ No newline at end of file
diff --git a/infra/config/generated/builders/try/linux-chromeos-rel-rts/properties.json b/infra/config/generated/builders/try/linux-chromeos-rel-rts/properties.json new file mode 100644 index 0000000..c70e234 --- /dev/null +++ b/infra/config/generated/builders/try/linux-chromeos-rel-rts/properties.json
@@ -0,0 +1,62 @@ +{ + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "linux-chromeos-rel", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-chromiumos-archive", + "builder_group": "chromium.chromiumos", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "chromium", + "target_arch": "intel", + "target_bits": 64 + }, + "legacy_gclient_config": { + "apply_configs": [ + "use_clang_coverage", + "chromeos" + ], + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "linux-chromeos-rel", + "project": "chromium" + } + ], + "rts_config": { + "condition": "QUICK_RUN_ONLY" + } + } + }, + "$build/reclient": { + "instance": "rbe-chromium-untrusted", + "jobs": 150, + "metrics_project": "chromium-reclient-metrics" + }, + "$recipe_engine/resultdb/test_presentation": { + "column_keys": [], + "grouping_keys": [ + "status", + "v.test_suite" + ] + }, + "builder_group": "tryserver.chromium.chromiumos", + "recipe": "chromium_trybot" +} \ No newline at end of file
diff --git a/infra/config/generated/builders/try/linux-lacros-rel-rts/properties.json b/infra/config/generated/builders/try/linux-lacros-rel-rts/properties.json new file mode 100644 index 0000000..05e90c5 --- /dev/null +++ b/infra/config/generated/builders/try/linux-lacros-rel-rts/properties.json
@@ -0,0 +1,101 @@ +{ + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "linux-lacros-builder-rel", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-chromiumos-archive", + "builder_group": "chromium.chromiumos", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "chromium", + "target_arch": "intel", + "target_bits": 64 + }, + "legacy_gclient_config": { + "apply_configs": [ + "chromeos" + ], + "config": "chromium_no_telemetry_dependencies" + } + } + }, + { + "builder_id": { + "bucket": "ci", + "builder": "linux-lacros-tester-rel", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-chromiumos-archive", + "builder_group": "chromium.chromiumos", + "execution_mode": "TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "chromium", + "target_arch": "intel", + "target_bits": 64 + }, + "legacy_gclient_config": { + "apply_configs": [ + "use_clang_coverage", + "chromeos" + ], + "config": "chromium_no_telemetry_dependencies" + }, + "parent": { + "bucket": "ci", + "builder": "linux-lacros-builder-rel", + "project": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "linux-lacros-builder-rel", + "project": "chromium" + } + ], + "builder_ids_in_scope_for_testing": [ + { + "bucket": "ci", + "builder": "linux-lacros-tester-rel", + "project": "chromium" + } + ], + "rts_config": { + "condition": "QUICK_RUN_ONLY" + } + } + }, + "$build/reclient": { + "instance": "rbe-chromium-untrusted", + "jobs": 150, + "metrics_project": "chromium-reclient-metrics" + }, + "$recipe_engine/resultdb/test_presentation": { + "column_keys": [], + "grouping_keys": [ + "status", + "v.test_suite" + ] + }, + "builder_group": "tryserver.chromium.chromiumos", + "recipe": "chromium_trybot" +} \ No newline at end of file
diff --git a/infra/config/generated/luci/commit-queue.cfg b/infra/config/generated/luci/commit-queue.cfg index eaf831a..a0f94c8 100644 --- a/infra/config/generated/luci/commit-queue.cfg +++ b/infra/config/generated/luci/commit-queue.cfg
@@ -1218,6 +1218,10 @@ includable_only: true } builders { + name: "chromium/try/chromeos-amd64-generic-rel-rts" + includable_only: true + } + builders { name: "chromium/try/chromeos-arm-generic-dbg" includable_only: true } @@ -2698,6 +2702,10 @@ includable_only: true } builders { + name: "chromium/try/linux-chromeos-rel-rts" + includable_only: true + } + builders { name: "chromium/try/linux-clang-tidy-rel" includable_only: true } @@ -2803,6 +2811,10 @@ includable_only: true } builders { + name: "chromium/try/linux-lacros-rel-rts" + includable_only: true + } + builders { name: "chromium/try/linux-lacros-version-skew-fyi" includable_only: true }
diff --git a/infra/config/generated/luci/cr-buildbucket-dev.cfg b/infra/config/generated/luci/cr-buildbucket-dev.cfg index ce3d7ac8..80f73ea9 100644 --- a/infra/config/generated/luci/cr-buildbucket-dev.cfg +++ b/infra/config/generated/luci/cr-buildbucket-dev.cfg
@@ -103,6 +103,97 @@ } } builders { + name: "linux-local-ssd-rel-dev" + swarming_host: "chromium-swarm-dev.appspot.com" + dimensions: "builder:linux-local-ssd-rel-dev" + dimensions: "cpu:x86-64" + dimensions: "os:Ubuntu-18.04" + exe { + cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" + cipd_version: "refs/heads/main" + cmd: "luciexe" + } + properties: + '{' + ' "$build/chromium_tests_builder_config": {' + ' "builder_config": {' + ' "builder_db": {' + ' "entries": [' + ' {' + ' "builder_id": {' + ' "bucket": "ci",' + ' "builder": "linux-local-ssd-rel-dev",' + ' "project": "chromium"' + ' },' + ' "builder_spec": {' + ' "builder_group": "chromium.dev",' + ' "execution_mode": "COMPILE_AND_TEST",' + ' "legacy_chromium_config": {' + ' "apply_configs": [' + ' "mb"' + ' ],' + ' "build_config": "Release",' + ' "config": "chromium"' + ' },' + ' "legacy_gclient_config": {' + ' "config": "chromium"' + ' }' + ' }' + ' }' + ' ]' + ' },' + ' "builder_ids": [' + ' {' + ' "bucket": "ci",' + ' "builder": "linux-local-ssd-rel-dev",' + ' "project": "chromium"' + ' }' + ' ]' + ' }' + ' },' + ' "$build/reclient": {' + ' "instance": "rbe-chromium-trusted",' + ' "jobs": 250,' + ' "metrics_project": "chromium-reclient-metrics"' + ' },' + ' "$recipe_engine/resultdb/test_presentation": {' + ' "column_keys": [],' + ' "grouping_keys": [' + ' "status",' + ' "v.test_suite"' + ' ]' + ' },' + ' "builder_group": "chromium.dev",' + ' "recipe": "swarming/staging"' + '}' + execution_timeout_secs: 10800 + build_numbers: YES + service_account: "chromium-ci-builder-dev@chops-service-accounts.iam.gserviceaccount.com" + experiments { + key: "luci.recipes.use_python3" + value: 100 + } + resultdb { + enable: true + bq_exports { + project: "chrome-luci-data" + dataset: "chromium_staging" + table: "ci_test_results" + test_results {} + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium_staging" + table: "ci_text_artifacts" + text_artifacts {} + } + history_options { + use_invocation_timestamp: true + } + } + description_html: "Ensures builders are using available local SSDs" + } + builders { name: "linux-rel-dev" swarming_host: "chromium-swarm-dev.appspot.com" dimensions: "cpu:x86-64" @@ -282,11 +373,12 @@ } } builders { - name: "linux-ssd-rel-dev" + name: "linux-remote-ssd-rel-dev" swarming_host: "chromium-swarm-dev.appspot.com" - dimensions: "builder:linux-ssd-rel-dev" + dimensions: "builder:linux-remote-ssd-rel-dev" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-22.04" + dimensions: "os:Ubuntu-18.04" + dimensions: "ssd:1" exe { cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/main" @@ -301,7 +393,7 @@ ' {' ' "builder_id": {' ' "bucket": "ci",' - ' "builder": "linux-ssd-rel-dev",' + ' "builder": "linux-remote-ssd-rel-dev",' ' "project": "chromium"' ' },' ' "builder_spec": {' @@ -324,7 +416,7 @@ ' "builder_ids": [' ' {' ' "bucket": "ci",' - ' "builder": "linux-ssd-rel-dev",' + ' "builder": "linux-remote-ssd-rel-dev",' ' "project": "chromium"' ' }' ' ]' @@ -370,7 +462,7 @@ use_invocation_timestamp: true } } - description_html: "Ensures builders are using available local SSDs" + description_html: "Ensures builders are using available remote SSDs. See b/279078023 for context." } builders { name: "mac-arm-rel-dev"
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg index cf3988fa..ad7fecf6 100644 --- a/infra/config/generated/luci/cr-buildbucket.cfg +++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -46,7 +46,7 @@ ' "v.test_suite"' ' ]' ' },' - ' "builder_group": "chromium.packager",' + ' "builder_group": "chromium.infra",' ' "recipe": "chromium_3pp"' '}' execution_timeout_secs: 10800 @@ -119,7 +119,7 @@ ' "v.test_suite"' ' ]' ' },' - ' "builder_group": "chromium.packager",' + ' "builder_group": "chromium.infra",' ' "recipe": "chromium_3pp"' '}' execution_timeout_secs: 10800 @@ -24135,7 +24135,7 @@ ' "v.test_suite"' ' ]' ' },' - ' "builder_group": "chromium.packager",' + ' "builder_group": "chromium.infra",' ' "recipe": "android/androidx_packager",' ' "sheriff_rotations": [' ' "android"' @@ -25075,7 +25075,7 @@ ' "v.test_suite"' ' ]' ' },' - ' "builder_group": "chromium.packager",' + ' "builder_group": "chromium.infra",' ' "recipe": "android/avd_packager"' '}' execution_timeout_secs: 10800 @@ -28092,7 +28092,7 @@ ' "v.test_suite"' ' ]' ' },' - ' "builder_group": "chromium.packager",' + ' "builder_group": "chromium.infra",' ' "packages": [' ' {' ' "cipd_yaml": "third_party/android_sdk/cipd/build-tools/25.0.2.yaml",' @@ -45166,7 +45166,7 @@ ' "v.test_suite"' ' ]' ' },' - ' "builder_group": "chromium.packager",' + ' "builder_group": "chromium.infra",' ' "recipe": "chromium_rts/create_model"' '}' execution_timeout_secs: 36000 @@ -53298,6 +53298,176 @@ description_html: "Builds chromium using the test version of reclient and the rbe-chromium-trusted-test rbe instance." } builders { + name: "Linux Builder reclient test (unified uploads)" + swarming_host: "chromium-swarm.appspot.com" + dimensions: "builderless:1" + dimensions: "cores:8" + dimensions: "cpu:x86-64" + dimensions: "free_space:standard" + dimensions: "os:Ubuntu-18.04" + dimensions: "pool:luci.chromium.ci" + dimensions: "ssd:0" + exe { + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" + } + properties: + '{' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' + ' },' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/reclient/Linux Builder reclient test (unified uploads)/properties.json",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' + ' },' + ' "builder_group": "chromium.reclient.fyi",' + ' "led_builder_is_bootstrapped": true,' + ' "recipe": "chromium"' + '}' + execution_timeout_secs: 10800 + build_numbers: YES + service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" + experiments { + key: "chromium_swarming.expose_merge_script_failures" + value: 100 + } + experiments { + key: "luci.recipes.use_python3" + value: 100 + } + resultdb { + enable: true + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "ci_test_results" + test_results {} + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "gpu_ci_test_results" + test_results { + predicate { + test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+" + } + } + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "blink_web_tests_ci_test_results" + test_results { + predicate { + test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*blink_wpt_tests/.+)" + } + } + } + history_options { + use_invocation_timestamp: true + } + } + description_html: "Builds chromium using the test version of reclient and the rbe-chromium-trusted-test rbe instance." + } + builders { + name: "Linux Builder reclient test (unified uploads) untrusted" + swarming_host: "chromium-swarm.appspot.com" + dimensions: "builderless:1" + dimensions: "cores:8" + dimensions: "cpu:x86-64" + dimensions: "free_space:standard" + dimensions: "os:Ubuntu-18.04" + dimensions: "pool:luci.chromium.ci" + dimensions: "ssd:0" + exe { + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" + } + properties: + '{' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' + ' },' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/reclient/Linux Builder reclient test (unified uploads) untrusted/properties.json",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' + ' },' + ' "builder_group": "chromium.reclient.fyi",' + ' "led_builder_is_bootstrapped": true,' + ' "recipe": "chromium"' + '}' + execution_timeout_secs: 10800 + build_numbers: YES + service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" + experiments { + key: "chromium_swarming.expose_merge_script_failures" + value: 100 + } + experiments { + key: "luci.recipes.use_python3" + value: 100 + } + resultdb { + enable: true + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "ci_test_results" + test_results {} + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "gpu_ci_test_results" + test_results { + predicate { + test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+" + } + } + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "blink_web_tests_ci_test_results" + test_results { + predicate { + test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*blink_wpt_tests/.+)" + } + } + } + history_options { + use_invocation_timestamp: true + } + } + description_html: "Builds chromium using the test version of reclient and the rbe-chromium-untrusted-test rbe instance." + } + builders { name: "Linux Builder reclient test untrusted" swarming_host: "chromium-swarm.appspot.com" dimensions: "builderless:1" @@ -55788,7 +55958,7 @@ ' "v.test_suite"' ' ]' ' },' - ' "builder_group": "tryserver.chromium.packager",' + ' "builder_group": "tryserver.chromium.infra",' ' "cq": "path-based",' ' "recipe": "chromium_3pp"' '}' @@ -55869,7 +56039,7 @@ ' "v.test_suite"' ' ]' ' },' - ' "builder_group": "tryserver.chromium.packager",' + ' "builder_group": "tryserver.chromium.infra",' ' "recipe": "chromium_3pp"' '}' execution_timeout_secs: 14400 @@ -62154,6 +62324,100 @@ description_html: "This is the compilator half of an orchestrator + compilator pair of builders. The orchestrator is <a href=\"https://ci.chromium.org/p/chromium/builders/try/chromeos-amd64-generic-rel\">chromeos-amd64-generic-rel</a>." } builders { + name: "chromeos-amd64-generic-rel-rts" + swarming_host: "chromium-swarm.appspot.com" + dimensions: "builderless:1" + dimensions: "cores:8" + dimensions: "cpu:x86-64" + dimensions: "os:Ubuntu-18.04" + dimensions: "pool:luci.chromium.try" + dimensions: "ssd:0" + exe { + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" + } + properties: + '{' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' + ' },' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/chromeos-amd64-generic-rel-rts/properties.json",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' + ' },' + ' "builder_group": "tryserver.chromium.chromiumos",' + ' "led_builder_is_bootstrapped": true,' + ' "recipe": "chromium_trybot"' + '}' + execution_timeout_secs: 14400 + expiration_secs: 7200 + grace_period { + seconds: 120 + } + build_numbers: YES + service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" + task_template_canary_percentage { + value: 5 + } + experiments { + key: "chromium_rts.inverted_rts" + value: 100 + } + experiments { + key: "chromium_swarming.expose_merge_script_failures" + value: 100 + } + experiments { + key: "luci.recipes.use_python3" + value: 100 + } + resultdb { + enable: true + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "try_test_results" + test_results {} + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "gpu_try_test_results" + test_results { + predicate { + test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+" + } + } + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "blink_web_tests_try_test_results" + test_results { + predicate { + test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*blink_wpt_tests/.+)" + } + } + } + history_options { + use_invocation_timestamp: true + } + } + } + builders { name: "chromeos-arm-generic-dbg" swarming_host: "chromium-swarm.appspot.com" dimensions: "builderless:1" @@ -73745,6 +74009,100 @@ description_html: "This is the compilator half of an orchestrator + compilator pair of builders. The orchestrator is <a href=\"https://ci.chromium.org/p/chromium/builders/try/linux-chromeos-rel\">linux-chromeos-rel</a>." } builders { + name: "linux-chromeos-rel-rts" + swarming_host: "chromium-swarm.appspot.com" + dimensions: "builderless:1" + dimensions: "cores:8" + dimensions: "cpu:x86-64" + dimensions: "os:Ubuntu-18.04" + dimensions: "pool:luci.chromium.try" + dimensions: "ssd:0" + exe { + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" + } + properties: + '{' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' + ' },' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-chromeos-rel-rts/properties.json",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' + ' },' + ' "builder_group": "tryserver.chromium.chromiumos",' + ' "led_builder_is_bootstrapped": true,' + ' "recipe": "chromium_trybot"' + '}' + execution_timeout_secs: 14400 + expiration_secs: 7200 + grace_period { + seconds: 120 + } + build_numbers: YES + service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" + task_template_canary_percentage { + value: 5 + } + experiments { + key: "chromium_rts.inverted_rts" + value: 100 + } + experiments { + key: "chromium_swarming.expose_merge_script_failures" + value: 100 + } + experiments { + key: "luci.recipes.use_python3" + value: 100 + } + resultdb { + enable: true + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "try_test_results" + test_results {} + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "gpu_try_test_results" + test_results { + predicate { + test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+" + } + } + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "blink_web_tests_try_test_results" + test_results { + predicate { + test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*blink_wpt_tests/.+)" + } + } + } + history_options { + use_invocation_timestamp: true + } + } + } + builders { name: "linux-clang-tidy-rel" swarming_host: "chromium-swarm.appspot.com" dimensions: "builderless:1" @@ -75260,6 +75618,100 @@ description_html: "This is the compilator half of an orchestrator + compilator pair of builders. The orchestrator is <a href=\"https://ci.chromium.org/p/chromium/builders/try/linux-lacros-rel\">linux-lacros-rel</a>." } builders { + name: "linux-lacros-rel-rts" + swarming_host: "chromium-swarm.appspot.com" + dimensions: "builderless:1" + dimensions: "cores:8" + dimensions: "cpu:x86-64" + dimensions: "os:Ubuntu-18.04" + dimensions: "pool:luci.chromium.try" + dimensions: "ssd:0" + exe { + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" + } + properties: + '{' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' + ' },' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-lacros-rel-rts/properties.json",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' + ' },' + ' "builder_group": "tryserver.chromium.chromiumos",' + ' "led_builder_is_bootstrapped": true,' + ' "recipe": "chromium_trybot"' + '}' + execution_timeout_secs: 14400 + expiration_secs: 7200 + grace_period { + seconds: 120 + } + build_numbers: YES + service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" + task_template_canary_percentage { + value: 5 + } + experiments { + key: "chromium_rts.inverted_rts" + value: 100 + } + experiments { + key: "chromium_swarming.expose_merge_script_failures" + value: 100 + } + experiments { + key: "luci.recipes.use_python3" + value: 100 + } + resultdb { + enable: true + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "try_test_results" + test_results {} + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "gpu_try_test_results" + test_results { + predicate { + test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+" + } + } + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "blink_web_tests_try_test_results" + test_results { + predicate { + test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*blink_wpt_tests/.+)" + } + } + } + history_options { + use_invocation_timestamp: true + } + } + } + builders { name: "linux-lacros-version-skew-fyi" swarming_host: "chromium-swarm.appspot.com" dimensions: "builderless:1"
diff --git a/infra/config/generated/luci/luci-milo-dev.cfg b/infra/config/generated/luci/luci-milo-dev.cfg index 716892c..0c19167 100644 --- a/infra/config/generated/luci/luci-milo-dev.cfg +++ b/infra/config/generated/luci/luci-milo-dev.cfg
@@ -20,7 +20,10 @@ name: "buildbucket/luci.chromium.ci/linux-rel-jammy-dev" } builders { - name: "buildbucket/luci.chromium.ci/linux-ssd-rel-dev" + name: "buildbucket/luci.chromium.ci/linux-local-ssd-rel-dev" + } + builders { + name: "buildbucket/luci.chromium.ci/linux-remote-ssd-rel-dev" } builders { name: "buildbucket/luci.chromium.ci/mac-rel-dev"
diff --git a/infra/config/generated/luci/luci-milo.cfg b/infra/config/generated/luci/luci-milo.cfg index 68b44bc..225f4e8 100644 --- a/infra/config/generated/luci/luci-milo.cfg +++ b/infra/config/generated/luci/luci-milo.cfg
@@ -214,16 +214,16 @@ alt: "Chromium GPU console" } links { + text: "infra" + url: "/p/chromium/g/chromium.infra" + alt: "Chromium Infra console" + } + links { text: "memory.fyi" url: "/p/chromium/g/chromium.memory.fyi" alt: "Chromium Memory FYI console" } links { - text: "packager" - url: "/p/chromium/g/chromium.packager" - alt: "Chromium Packager console" - } - links { text: "perf" url: "/p/chrome/g/chrome.perf/console" alt: "Chromium Perf console" @@ -1181,16 +1181,16 @@ alt: "Chromium GPU console" } links { + text: "infra" + url: "/p/chromium/g/chromium.infra" + alt: "Chromium Infra console" + } + links { text: "memory.fyi" url: "/p/chromium/g/chromium.memory.fyi" alt: "Chromium Memory FYI console" } links { - text: "packager" - url: "/p/chromium/g/chromium.packager" - alt: "Chromium Packager console" - } - links { text: "perf" url: "/p/chrome/g/chrome.perf/console" alt: "Chromium Perf console" @@ -1931,16 +1931,16 @@ alt: "Chromium GPU console" } links { + text: "infra" + url: "/p/chromium/g/chromium.infra" + alt: "Chromium Infra console" + } + links { text: "memory.fyi" url: "/p/chromium/g/chromium.memory.fyi" alt: "Chromium Memory FYI console" } links { - text: "packager" - url: "/p/chromium/g/chromium.packager" - alt: "Chromium Packager console" - } - links { text: "perf" url: "/p/chrome/g/chrome.perf/console" alt: "Chromium Perf console" @@ -2408,16 +2408,16 @@ alt: "Chromium GPU console" } links { + text: "infra" + url: "/p/chromium/g/chromium.infra" + alt: "Chromium Infra console" + } + links { text: "memory.fyi" url: "/p/chromium/g/chromium.memory.fyi" alt: "Chromium Memory FYI console" } links { - text: "packager" - url: "/p/chromium/g/chromium.packager" - alt: "Chromium Packager console" - } - links { text: "perf" url: "/p/chrome/g/chrome.perf/console" alt: "Chromium Perf console" @@ -2767,16 +2767,16 @@ alt: "Chromium GPU console" } links { + text: "infra" + url: "/p/chromium/g/chromium.infra" + alt: "Chromium Infra console" + } + links { text: "memory.fyi" url: "/p/chromium/g/chromium.memory.fyi" alt: "Chromium Memory FYI console" } links { - text: "packager" - url: "/p/chromium/g/chromium.packager" - alt: "Chromium Packager console" - } - links { text: "perf" url: "/p/chrome/g/chrome.perf/console" alt: "Chromium Perf console" @@ -3377,16 +3377,16 @@ alt: "Chromium GPU console" } links { + text: "infra" + url: "/p/chromium/g/chromium.infra" + alt: "Chromium Infra console" + } + links { text: "memory.fyi" url: "/p/chromium/g/chromium.memory.fyi" alt: "Chromium Memory FYI console" } links { - text: "packager" - url: "/p/chromium/g/chromium.packager" - alt: "Chromium Packager console" - } - links { text: "perf" url: "/p/chrome/g/chrome.perf/console" alt: "Chromium Perf console" @@ -3721,16 +3721,16 @@ alt: "Chromium GPU console" } links { + text: "infra" + url: "/p/chromium/g/chromium.infra" + alt: "Chromium Infra console" + } + links { text: "memory.fyi" url: "/p/chromium/g/chromium.memory.fyi" alt: "Chromium Memory FYI console" } links { - text: "packager" - url: "/p/chromium/g/chromium.packager" - alt: "Chromium Packager console" - } - links { text: "perf" url: "/p/chrome/g/chrome.perf/console" alt: "Chromium Perf console" @@ -4170,16 +4170,16 @@ alt: "Chromium GPU console" } links { + text: "infra" + url: "/p/chromium/g/chromium.infra" + alt: "Chromium Infra console" + } + links { text: "memory.fyi" url: "/p/chromium/g/chromium.memory.fyi" alt: "Chromium Memory FYI console" } links { - text: "packager" - url: "/p/chromium/g/chromium.packager" - alt: "Chromium Packager console" - } - links { text: "perf" url: "/p/chrome/g/chrome.perf/console" alt: "Chromium Perf console" @@ -4515,16 +4515,16 @@ alt: "Chromium GPU console" } links { + text: "infra" + url: "/p/chromium/g/chromium.infra" + alt: "Chromium Infra console" + } + links { text: "memory.fyi" url: "/p/chromium/g/chromium.memory.fyi" alt: "Chromium Memory FYI console" } links { - text: "packager" - url: "/p/chromium/g/chromium.packager" - alt: "Chromium Packager console" - } - links { text: "perf" url: "/p/chrome/g/chrome.perf/console" alt: "Chromium Perf console" @@ -5068,16 +5068,16 @@ alt: "Chromium GPU console" } links { + text: "infra" + url: "/p/chromium/g/chromium.infra" + alt: "Chromium Infra console" + } + links { text: "memory.fyi" url: "/p/chromium/g/chromium.memory.fyi" alt: "Chromium Memory FYI console" } links { - text: "packager" - url: "/p/chromium/g/chromium.packager" - alt: "Chromium Packager console" - } - links { text: "perf" url: "/p/chrome/g/chrome.perf/console" alt: "Chromium Perf console" @@ -5461,16 +5461,16 @@ alt: "Chromium GPU console" } links { + text: "infra" + url: "/p/chromium/g/chromium.infra" + alt: "Chromium Infra console" + } + links { text: "memory.fyi" url: "/p/chromium/g/chromium.memory.fyi" alt: "Chromium Memory FYI console" } links { - text: "packager" - url: "/p/chromium/g/chromium.packager" - alt: "Chromium Packager console" - } - links { text: "perf" url: "/p/chrome/g/chrome.perf/console" alt: "Chromium Perf console" @@ -5870,16 +5870,16 @@ alt: "Chromium GPU console" } links { + text: "infra" + url: "/p/chromium/g/chromium.infra" + alt: "Chromium Infra console" + } + links { text: "memory.fyi" url: "/p/chromium/g/chromium.memory.fyi" alt: "Chromium Memory FYI console" } links { - text: "packager" - url: "/p/chromium/g/chromium.packager" - alt: "Chromium Packager console" - } - links { text: "perf" url: "/p/chrome/g/chrome.perf/console" alt: "Chromium Perf console" @@ -6216,16 +6216,16 @@ alt: "Chromium GPU console" } links { + text: "infra" + url: "/p/chromium/g/chromium.infra" + alt: "Chromium Infra console" + } + links { text: "memory.fyi" url: "/p/chromium/g/chromium.memory.fyi" alt: "Chromium Memory FYI console" } links { - text: "packager" - url: "/p/chromium/g/chromium.packager" - alt: "Chromium Packager console" - } - links { text: "perf" url: "/p/chrome/g/chrome.perf/console" alt: "Chromium Perf console" @@ -6673,16 +6673,16 @@ alt: "Chromium GPU console" } links { + text: "infra" + url: "/p/chromium/g/chromium.infra" + alt: "Chromium Infra console" + } + links { text: "memory.fyi" url: "/p/chromium/g/chromium.memory.fyi" alt: "Chromium Memory FYI console" } links { - text: "packager" - url: "/p/chromium/g/chromium.packager" - alt: "Chromium Packager console" - } - links { text: "perf" url: "/p/chrome/g/chrome.perf/console" alt: "Chromium Perf console" @@ -7237,16 +7237,16 @@ alt: "Chromium GPU console" } links { + text: "infra" + url: "/p/chromium/g/chromium.infra" + alt: "Chromium Infra console" + } + links { text: "memory.fyi" url: "/p/chromium/g/chromium.memory.fyi" alt: "Chromium Memory FYI console" } links { - text: "packager" - url: "/p/chromium/g/chromium.packager" - alt: "Chromium Packager console" - } - links { text: "perf" url: "/p/chrome/g/chrome.perf/console" alt: "Chromium Perf console" @@ -7711,16 +7711,16 @@ alt: "Chromium GPU console" } links { + text: "infra" + url: "/p/chromium/g/chromium.infra" + alt: "Chromium Infra console" + } + links { text: "memory.fyi" url: "/p/chromium/g/chromium.memory.fyi" alt: "Chromium Memory FYI console" } links { - text: "packager" - url: "/p/chromium/g/chromium.packager" - alt: "Chromium Packager console" - } - links { text: "perf" url: "/p/chrome/g/chrome.perf/console" alt: "Chromium Perf console" @@ -8092,16 +8092,16 @@ alt: "Chromium GPU console" } links { + text: "infra" + url: "/p/chromium/g/chromium.infra" + alt: "Chromium Infra console" + } + links { text: "memory.fyi" url: "/p/chromium/g/chromium.memory.fyi" alt: "Chromium Memory FYI console" } links { - text: "packager" - url: "/p/chromium/g/chromium.packager" - alt: "Chromium Packager console" - } - links { text: "perf" url: "/p/chrome/g/chrome.perf/console" alt: "Chromium Perf console" @@ -8461,16 +8461,16 @@ alt: "Chromium GPU console" } links { + text: "infra" + url: "/p/chromium/g/chromium.infra" + alt: "Chromium Infra console" + } + links { text: "memory.fyi" url: "/p/chromium/g/chromium.memory.fyi" alt: "Chromium Memory FYI console" } links { - text: "packager" - url: "/p/chromium/g/chromium.packager" - alt: "Chromium Packager console" - } - links { text: "perf" url: "/p/chrome/g/chrome.perf/console" alt: "Chromium Perf console" @@ -8954,16 +8954,16 @@ alt: "Chromium GPU console" } links { + text: "infra" + url: "/p/chromium/g/chromium.infra" + alt: "Chromium Infra console" + } + links { text: "memory.fyi" url: "/p/chromium/g/chromium.memory.fyi" alt: "Chromium Memory FYI console" } links { - text: "packager" - url: "/p/chromium/g/chromium.packager" - alt: "Chromium Packager console" - } - links { text: "perf" url: "/p/chrome/g/chrome.perf/console" alt: "Chromium Perf console" @@ -9788,16 +9788,16 @@ alt: "Chromium GPU console" } links { + text: "infra" + url: "/p/chromium/g/chromium.infra" + alt: "Chromium Infra console" + } + links { text: "memory.fyi" url: "/p/chromium/g/chromium.memory.fyi" alt: "Chromium Memory FYI console" } links { - text: "packager" - url: "/p/chromium/g/chromium.packager" - alt: "Chromium Packager console" - } - links { text: "perf" url: "/p/chrome/g/chrome.perf/console" alt: "Chromium Perf console" @@ -10219,16 +10219,16 @@ alt: "Chromium GPU console" } links { + text: "infra" + url: "/p/chromium/g/chromium.infra" + alt: "Chromium Infra console" + } + links { text: "memory.fyi" url: "/p/chromium/g/chromium.memory.fyi" alt: "Chromium Memory FYI console" } links { - text: "packager" - url: "/p/chromium/g/chromium.packager" - alt: "Chromium Packager console" - } - links { text: "perf" url: "/p/chrome/g/chrome.perf/console" alt: "Chromium Perf console" @@ -10624,16 +10624,16 @@ alt: "Chromium GPU console" } links { + text: "infra" + url: "/p/chromium/g/chromium.infra" + alt: "Chromium Infra console" + } + links { text: "memory.fyi" url: "/p/chromium/g/chromium.memory.fyi" alt: "Chromium Memory FYI console" } links { - text: "packager" - url: "/p/chromium/g/chromium.packager" - alt: "Chromium Packager console" - } - links { text: "perf" url: "/p/chrome/g/chrome.perf/console" alt: "Chromium Perf console" @@ -11019,16 +11019,16 @@ alt: "Chromium GPU console" } links { + text: "infra" + url: "/p/chromium/g/chromium.infra" + alt: "Chromium Infra console" + } + links { text: "memory.fyi" url: "/p/chromium/g/chromium.memory.fyi" alt: "Chromium Memory FYI console" } links { - text: "packager" - url: "/p/chromium/g/chromium.packager" - alt: "Chromium Packager console" - } - links { text: "perf" url: "/p/chrome/g/chrome.perf/console" alt: "Chromium Perf console" @@ -11643,14 +11643,378 @@ alt: "Chromium GPU console" } links { + text: "infra" + url: "/p/chromium/g/chromium.infra" + alt: "Chromium Infra console" + } + links { text: "memory.fyi" url: "/p/chromium/g/chromium.memory.fyi" alt: "Chromium Memory FYI console" } links { - text: "packager" - url: "/p/chromium/g/chromium.packager" - alt: "Chromium Packager console" + text: "perf" + url: "/p/chrome/g/chrome.perf/console" + alt: "Chromium Perf console" + } + links { + text: "perf.fyi" + url: "/p/chrome/g/chrome.perf.fyi/console" + alt: "Chromium Perf FYI console" + } + links { + text: "angle" + url: "/p/chromium/g/chromium.angle" + alt: "Chromium ANGLE console" + } + links { + text: "swangle" + url: "/p/chromium/g/chromium.swangle" + alt: "Chromium SWANGLE console" + } + links { + text: "updater" + url: "/p/chromium/g/chromium.updater" + alt: "Chromium Updater console" + } + links { + text: "webrtc" + url: "/p/chromium/g/chromium.webrtc" + alt: "Chromium WebRTC console" + } + links { + text: "chromiumos" + url: "/p/chromium/g/chromium.chromiumos" + alt: "ChromiumOS console" + } + links { + text: "flakiness" + url: "/p/chromium/g/chromium.flakiness" + alt: "Chromium Flakiness console" + } + } + links { + name: "Branch Consoles" + links { + text: "m102" + url: "/p/chromium-m102/g/main/console" + } + links { + text: "m108" + url: "/p/chromium-m108/g/main/console" + } + links { + text: "m109" + url: "/p/chromium-m109/g/main/console" + } + links { + text: "m110" + url: "/p/chromium-m110/g/main/console" + } + links { + text: "m111" + url: "/p/chromium-m111/g/main/console" + } + links { + text: "m112" + url: "/p/chromium-m112/g/main/console" + } + links { + text: "m113" + url: "/p/chromium-m113/g/main/console" + } + links { + text: "trunk" + url: "/p/chromium/g/main/console" + alt: "Trunk (ToT) console" + } + } + links { + name: "Tryservers" + links { + text: "android" + url: "/p/chromium/g/tryserver.chromium.android/builders" + alt: "Android" + } + links { + text: "angle" + url: "/p/chromium/g/tryserver.chromium.angle/builders" + alt: "Angle" + } + links { + text: "blink" + url: "/p/chromium/g/tryserver.blink/builders" + alt: "Blink" + } + links { + text: "chrome" + url: "/p/chrome/g/tryserver.chrome/builders" + alt: "Chrome" + } + links { + text: "chromiumos" + url: "/p/chromium/g/tryserver.chromium.chromiumos/builders" + alt: "ChromiumOS" + } + links { + text: "fuchsia" + url: "/p/chromium/g/tryserver.chromium.fuchsia/builders" + alt: "Fuchsia" + } + links { + text: "linux" + url: "/p/chromium/g/tryserver.chromium.linux/builders" + alt: "Linux" + } + links { + text: "mac" + url: "/p/chromium/g/tryserver.chromium.mac/builders" + alt: "Mac" + } + links { + text: "swangle" + url: "/p/chromium/g/tryserver.chromium.swangle/builders" + alt: "SWANGLE" + } + links { + text: "tricium" + url: "/p/chromium/g/tryserver.chromium.tricium/builders" + alt: "Tricium" + } + links { + text: "win" + url: "/p/chromium/g/tryserver.chromium.win/builders" + alt: "Win" + } + } + links { + name: "Navigate" + links { + text: "about" + url: "http://dev.chromium.org/developers/testing/chromium-build-infrastructure/tour-of-the-chromium-buildbot" + alt: "Tour of the console" + } + links { + text: "customize" + url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/main/infra/config/generated/luci/luci-milo.cfg" + alt: "Customize this console" + } + } + console_groups { + title { + text: "Tree Closers" + url: "https://chromium-status.appspot.com/" + } + console_ids: "chromium/chromium" + console_ids: "chromium/chromium.win" + console_ids: "chromium/chromium.mac" + console_ids: "chromium/chromium.linux" + console_ids: "chromium/chromium.chromiumos" + console_ids: "chromium/chromium.fuchsia" + console_ids: "chrome/chrome" + console_ids: "chromium/chromium.memory" + console_ids: "chromium/chromium.gpu" + } + console_groups { + console_ids: "chromium/chromium.android" + console_ids: "chrome/chrome.perf" + console_ids: "chromium/chromium.fuchsia.fyi" + console_ids: "chromium/chromium.gpu.fyi" + console_ids: "chromium/chromium.angle" + console_ids: "chromium/chromium.swangle" + console_ids: "chromium/chromium.fuzz" + } + tree_status_host: "chromium-status.appspot.com" + } +} +consoles { + id: "chromium.infra" + name: "chromium.infra" + repo_url: "https://chromium.googlesource.com/chromium/src" + refs: "regexp:refs/heads/main" + manifest_name: "REVISION" + builders { + name: "buildbucket/luci.chromium.ci/3pp-linux-amd64-packager" + category: "packager|3pp|linux" + short_name: "amd64" + } + builders { + name: "buildbucket/luci.chromium.ci/3pp-mac-amd64-packager" + category: "packager|3pp|mac" + short_name: "amd64" + } + builders { + name: "buildbucket/luci.chromium.ci/android-androidx-packager" + category: "packager|android" + short_name: "androidx" + } + builders { + name: "buildbucket/luci.chromium.ci/android-avd-packager" + category: "packager|android" + short_name: "avd" + } + builders { + name: "buildbucket/luci.chromium.ci/android-sdk-packager" + category: "packager|android" + short_name: "sdk" + } + builders { + name: "buildbucket/luci.chromium.ci/rts-model-packager" + category: "packager|rts" + short_name: "create-model" + } + header { + oncalls { + name: "Chromium" + url: "https://chrome-ops-rotation-proxy.appspot.com/current/oncallator:chrome-build-sheriff" + } + oncalls { + name: "Android" + url: "https://chrome-ops-rotation-proxy.appspot.com/current/oncallator:chrome-android-sheriff" + } + oncalls { + name: "iOS" + url: "https://chrome-ops-rotation-proxy.appspot.com/current/oncallator:chrome-ios" + } + oncalls { + name: "ChromeOS" + url: "https://chrome-ops-rotation-proxy.appspot.com/current/oncallator:chromeos-gardeners" + } + oncalls { + name: "Fuchsia" + url: "https://chrome-ops-rotation-proxy.appspot.com/current/grotation:chrome-fuchsia-gardener" + } + oncalls { + name: "GPU" + url: "https://chrome-ops-rotation-proxy.appspot.com/current/oncallator:chrome-gpu-pixel-wrangler-weekly" + } + oncalls { + name: "ANGLE" + url: "https://chrome-ops-rotation-proxy.appspot.com/current/grotation:angle-wrangler" + } + oncalls { + name: "Perf" + url: "https://chrome-ops-rotation-proxy.appspot.com/current/grotation:chromium-perf-regression-sheriff" + } + oncalls { + name: "Perfbot" + url: "https://chrome-ops-rotation-proxy.appspot.com/current/grotation:chromium-perf-bot-sheriff" + } + oncalls { + name: "Trooper" + url: "https://chrome-ops-rotation-proxy.appspot.com/current/oncallator:chrome-ops-client-infra" + show_primary_secondary_labels: true + } + links { + name: "Builds" + links { + text: "continuous" + url: "https://commondatastorage.googleapis.com/chromium-browser-snapshots/index.html" + alt: "Continuous browser snapshots" + } + links { + text: "symbols" + url: "https://www.chromium.org/developers/how-tos/debugging-on-windows" + alt: "Windows Symbols" + } + links { + text: "status" + url: "https://chromium-status.appspot.com/" + alt: "Current tree status" + } + } + links { + name: "Dashboards" + links { + text: "perf" + url: "https://chromeperf.appspot.com/" + alt: "Chrome perf dashboard" + } + links { + text: "LUCI Analysis" + url: "https://luci-analysis.appspot.com" + alt: "New flake portal" + } + } + links { + name: "Chromium" + links { + text: "source" + url: "https://chromium.googlesource.com/chromium/src" + alt: "Chromium source code repository" + } + links { + text: "reviews" + url: "https://chromium-review.googlesource.com" + alt: "Chromium code review tool" + } + links { + text: "bugs" + url: "https://crbug.com" + alt: "Chromium bug tracker" + } + links { + text: "coverage" + url: "https://analysis.chromium.org/coverage/p/chromium" + alt: "Chromium code coverage dashboard" + } + links { + text: "dev" + url: "https://dev.chromium.org/Home" + alt: "Chromium developer home page" + } + links { + text: "support" + url: "https://support.google.com/chrome/#topic=7438008" + alt: "Google Chrome help center" + } + } + links { + name: "Consoles" + links { + text: "android" + url: "/p/chromium/g/chromium.android" + alt: "Chromium Android console" + } + links { + text: "clang" + url: "/p/chromium/g/chromium.clang" + alt: "Chromium Clang console" + } + links { + text: "dawn" + url: "/p/chromium/g/chromium.dawn" + alt: "Chromium Dawn console" + } + links { + text: "fuzz" + url: "/p/chromium/g/chromium.fuzz" + alt: "Chromium Fuzz console" + } + links { + text: "fuchsia" + url: "/p/chromium/g/chromium.fuchsia" + alt: "Chromium Fuchsia console" + } + links { + text: "fyi" + url: "/p/chromium/g/chromium.fyi" + alt: "Chromium FYI console" + } + links { + text: "gpu" + url: "/p/chromium/g/chromium.gpu" + alt: "Chromium GPU console" + } + links { + text: "infra" + url: "/p/chromium/g/chromium.infra" + alt: "Chromium Infra console" + } + links { + text: "memory.fyi" + url: "/p/chromium/g/chromium.memory.fyi" + alt: "Chromium Memory FYI console" } links { text: "perf" @@ -12057,16 +12421,16 @@ alt: "Chromium GPU console" } links { + text: "infra" + url: "/p/chromium/g/chromium.infra" + alt: "Chromium Infra console" + } + links { text: "memory.fyi" url: "/p/chromium/g/chromium.memory.fyi" alt: "Chromium Memory FYI console" } links { - text: "packager" - url: "/p/chromium/g/chromium.packager" - alt: "Chromium Packager console" - } - links { text: "perf" url: "/p/chrome/g/chrome.perf/console" alt: "Chromium Perf console" @@ -12481,16 +12845,16 @@ alt: "Chromium GPU console" } links { + text: "infra" + url: "/p/chromium/g/chromium.infra" + alt: "Chromium Infra console" + } + links { text: "memory.fyi" url: "/p/chromium/g/chromium.memory.fyi" alt: "Chromium Memory FYI console" } links { - text: "packager" - url: "/p/chromium/g/chromium.packager" - alt: "Chromium Packager console" - } - links { text: "perf" url: "/p/chrome/g/chrome.perf/console" alt: "Chromium Perf console" @@ -12925,16 +13289,16 @@ alt: "Chromium GPU console" } links { + text: "infra" + url: "/p/chromium/g/chromium.infra" + alt: "Chromium Infra console" + } + links { text: "memory.fyi" url: "/p/chromium/g/chromium.memory.fyi" alt: "Chromium Memory FYI console" } links { - text: "packager" - url: "/p/chromium/g/chromium.packager" - alt: "Chromium Packager console" - } - links { text: "perf" url: "/p/chrome/g/chrome.perf/console" alt: "Chromium Perf console" @@ -13269,368 +13633,9 @@ alt: "Chromium GPU console" } links { - text: "memory.fyi" - url: "/p/chromium/g/chromium.memory.fyi" - alt: "Chromium Memory FYI console" - } - links { - text: "packager" - url: "/p/chromium/g/chromium.packager" - alt: "Chromium Packager console" - } - links { - text: "perf" - url: "/p/chrome/g/chrome.perf/console" - alt: "Chromium Perf console" - } - links { - text: "perf.fyi" - url: "/p/chrome/g/chrome.perf.fyi/console" - alt: "Chromium Perf FYI console" - } - links { - text: "angle" - url: "/p/chromium/g/chromium.angle" - alt: "Chromium ANGLE console" - } - links { - text: "swangle" - url: "/p/chromium/g/chromium.swangle" - alt: "Chromium SWANGLE console" - } - links { - text: "updater" - url: "/p/chromium/g/chromium.updater" - alt: "Chromium Updater console" - } - links { - text: "webrtc" - url: "/p/chromium/g/chromium.webrtc" - alt: "Chromium WebRTC console" - } - links { - text: "chromiumos" - url: "/p/chromium/g/chromium.chromiumos" - alt: "ChromiumOS console" - } - links { - text: "flakiness" - url: "/p/chromium/g/chromium.flakiness" - alt: "Chromium Flakiness console" - } - } - links { - name: "Branch Consoles" - links { - text: "m102" - url: "/p/chromium-m102/g/main/console" - } - links { - text: "m108" - url: "/p/chromium-m108/g/main/console" - } - links { - text: "m109" - url: "/p/chromium-m109/g/main/console" - } - links { - text: "m110" - url: "/p/chromium-m110/g/main/console" - } - links { - text: "m111" - url: "/p/chromium-m111/g/main/console" - } - links { - text: "m112" - url: "/p/chromium-m112/g/main/console" - } - links { - text: "m113" - url: "/p/chromium-m113/g/main/console" - } - links { - text: "trunk" - url: "/p/chromium/g/main/console" - alt: "Trunk (ToT) console" - } - } - links { - name: "Tryservers" - links { - text: "android" - url: "/p/chromium/g/tryserver.chromium.android/builders" - alt: "Android" - } - links { - text: "angle" - url: "/p/chromium/g/tryserver.chromium.angle/builders" - alt: "Angle" - } - links { - text: "blink" - url: "/p/chromium/g/tryserver.blink/builders" - alt: "Blink" - } - links { - text: "chrome" - url: "/p/chrome/g/tryserver.chrome/builders" - alt: "Chrome" - } - links { - text: "chromiumos" - url: "/p/chromium/g/tryserver.chromium.chromiumos/builders" - alt: "ChromiumOS" - } - links { - text: "fuchsia" - url: "/p/chromium/g/tryserver.chromium.fuchsia/builders" - alt: "Fuchsia" - } - links { - text: "linux" - url: "/p/chromium/g/tryserver.chromium.linux/builders" - alt: "Linux" - } - links { - text: "mac" - url: "/p/chromium/g/tryserver.chromium.mac/builders" - alt: "Mac" - } - links { - text: "swangle" - url: "/p/chromium/g/tryserver.chromium.swangle/builders" - alt: "SWANGLE" - } - links { - text: "tricium" - url: "/p/chromium/g/tryserver.chromium.tricium/builders" - alt: "Tricium" - } - links { - text: "win" - url: "/p/chromium/g/tryserver.chromium.win/builders" - alt: "Win" - } - } - links { - name: "Navigate" - links { - text: "about" - url: "http://dev.chromium.org/developers/testing/chromium-build-infrastructure/tour-of-the-chromium-buildbot" - alt: "Tour of the console" - } - links { - text: "customize" - url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/main/infra/config/generated/luci/luci-milo.cfg" - alt: "Customize this console" - } - } - console_groups { - title { - text: "Tree Closers" - url: "https://chromium-status.appspot.com/" - } - console_ids: "chromium/chromium" - console_ids: "chromium/chromium.win" - console_ids: "chromium/chromium.mac" - console_ids: "chromium/chromium.linux" - console_ids: "chromium/chromium.chromiumos" - console_ids: "chromium/chromium.fuchsia" - console_ids: "chrome/chrome" - console_ids: "chromium/chromium.memory" - console_ids: "chromium/chromium.gpu" - } - console_groups { - console_ids: "chromium/chromium.android" - console_ids: "chrome/chrome.perf" - console_ids: "chromium/chromium.fuchsia.fyi" - console_ids: "chromium/chromium.gpu.fyi" - console_ids: "chromium/chromium.angle" - console_ids: "chromium/chromium.swangle" - console_ids: "chromium/chromium.fuzz" - } - tree_status_host: "chromium-status.appspot.com" - } -} -consoles { - id: "chromium.packager" - name: "chromium.packager" - repo_url: "https://chromium.googlesource.com/chromium/src" - refs: "regexp:refs/heads/main" - manifest_name: "REVISION" - builders { - name: "buildbucket/luci.chromium.ci/3pp-linux-amd64-packager" - category: "3pp|linux" - short_name: "amd64" - } - builders { - name: "buildbucket/luci.chromium.ci/3pp-mac-amd64-packager" - category: "3pp|mac" - short_name: "amd64" - } - builders { - name: "buildbucket/luci.chromium.ci/android-androidx-packager" - category: "android" - short_name: "androidx" - } - builders { - name: "buildbucket/luci.chromium.ci/android-avd-packager" - category: "android" - short_name: "avd" - } - builders { - name: "buildbucket/luci.chromium.ci/android-sdk-packager" - category: "android" - short_name: "sdk" - } - builders { - name: "buildbucket/luci.chromium.ci/rts-model-packager" - category: "rts" - short_name: "create-model" - } - header { - oncalls { - name: "Chromium" - url: "https://chrome-ops-rotation-proxy.appspot.com/current/oncallator:chrome-build-sheriff" - } - oncalls { - name: "Android" - url: "https://chrome-ops-rotation-proxy.appspot.com/current/oncallator:chrome-android-sheriff" - } - oncalls { - name: "iOS" - url: "https://chrome-ops-rotation-proxy.appspot.com/current/oncallator:chrome-ios" - } - oncalls { - name: "ChromeOS" - url: "https://chrome-ops-rotation-proxy.appspot.com/current/oncallator:chromeos-gardeners" - } - oncalls { - name: "Fuchsia" - url: "https://chrome-ops-rotation-proxy.appspot.com/current/grotation:chrome-fuchsia-gardener" - } - oncalls { - name: "GPU" - url: "https://chrome-ops-rotation-proxy.appspot.com/current/oncallator:chrome-gpu-pixel-wrangler-weekly" - } - oncalls { - name: "ANGLE" - url: "https://chrome-ops-rotation-proxy.appspot.com/current/grotation:angle-wrangler" - } - oncalls { - name: "Perf" - url: "https://chrome-ops-rotation-proxy.appspot.com/current/grotation:chromium-perf-regression-sheriff" - } - oncalls { - name: "Perfbot" - url: "https://chrome-ops-rotation-proxy.appspot.com/current/grotation:chromium-perf-bot-sheriff" - } - oncalls { - name: "Trooper" - url: "https://chrome-ops-rotation-proxy.appspot.com/current/oncallator:chrome-ops-client-infra" - show_primary_secondary_labels: true - } - links { - name: "Builds" - links { - text: "continuous" - url: "https://commondatastorage.googleapis.com/chromium-browser-snapshots/index.html" - alt: "Continuous browser snapshots" - } - links { - text: "symbols" - url: "https://www.chromium.org/developers/how-tos/debugging-on-windows" - alt: "Windows Symbols" - } - links { - text: "status" - url: "https://chromium-status.appspot.com/" - alt: "Current tree status" - } - } - links { - name: "Dashboards" - links { - text: "perf" - url: "https://chromeperf.appspot.com/" - alt: "Chrome perf dashboard" - } - links { - text: "LUCI Analysis" - url: "https://luci-analysis.appspot.com" - alt: "New flake portal" - } - } - links { - name: "Chromium" - links { - text: "source" - url: "https://chromium.googlesource.com/chromium/src" - alt: "Chromium source code repository" - } - links { - text: "reviews" - url: "https://chromium-review.googlesource.com" - alt: "Chromium code review tool" - } - links { - text: "bugs" - url: "https://crbug.com" - alt: "Chromium bug tracker" - } - links { - text: "coverage" - url: "https://analysis.chromium.org/coverage/p/chromium" - alt: "Chromium code coverage dashboard" - } - links { - text: "dev" - url: "https://dev.chromium.org/Home" - alt: "Chromium developer home page" - } - links { - text: "support" - url: "https://support.google.com/chrome/#topic=7438008" - alt: "Google Chrome help center" - } - } - links { - name: "Consoles" - links { - text: "android" - url: "/p/chromium/g/chromium.android" - alt: "Chromium Android console" - } - links { - text: "clang" - url: "/p/chromium/g/chromium.clang" - alt: "Chromium Clang console" - } - links { - text: "dawn" - url: "/p/chromium/g/chromium.dawn" - alt: "Chromium Dawn console" - } - links { - text: "fuzz" - url: "/p/chromium/g/chromium.fuzz" - alt: "Chromium Fuzz console" - } - links { - text: "fuchsia" - url: "/p/chromium/g/chromium.fuchsia" - alt: "Chromium Fuchsia console" - } - links { - text: "fyi" - url: "/p/chromium/g/chromium.fyi" - alt: "Chromium FYI console" - } - links { - text: "gpu" - url: "/p/chromium/g/chromium.gpu" - alt: "Chromium GPU console" + text: "infra" + url: "/p/chromium/g/chromium.infra" + alt: "Chromium Infra console" } links { text: "memory.fyi" @@ -13638,11 +13643,6 @@ alt: "Chromium Memory FYI console" } links { - text: "packager" - url: "/p/chromium/g/chromium.packager" - alt: "Chromium Packager console" - } - links { text: "perf" url: "/p/chrome/g/chrome.perf/console" alt: "Chromium Perf console" @@ -13859,6 +13859,11 @@ short_name: "rcs" } builders { + name: "buildbucket/luci.chromium.reclient/Linux Builder reclient test (unified uploads)" + category: "rbe|linux" + short_name: "rcs" + } + builders { name: "buildbucket/luci.chromium.reclient/Simple Chrome Builder reclient staging" category: "rbe|linux" short_name: "rcs" @@ -13914,6 +13919,11 @@ short_name: "rcs" } builders { + name: "buildbucket/luci.chromium.reclient/Linux Builder reclient test (unified uploads) untrusted" + category: "rbecq|linux" + short_name: "rcs" + } + builders { name: "buildbucket/luci.chromium.reclient/Linux Builder reclient test untrusted" category: "rbecq|linux" short_name: "rcs" @@ -14112,16 +14122,16 @@ alt: "Chromium GPU console" } links { + text: "infra" + url: "/p/chromium/g/chromium.infra" + alt: "Chromium Infra console" + } + links { text: "memory.fyi" url: "/p/chromium/g/chromium.memory.fyi" alt: "Chromium Memory FYI console" } links { - text: "packager" - url: "/p/chromium/g/chromium.packager" - alt: "Chromium Packager console" - } - links { text: "perf" url: "/p/chrome/g/chrome.perf/console" alt: "Chromium Perf console" @@ -14487,16 +14497,16 @@ alt: "Chromium GPU console" } links { + text: "infra" + url: "/p/chromium/g/chromium.infra" + alt: "Chromium Infra console" + } + links { text: "memory.fyi" url: "/p/chromium/g/chromium.memory.fyi" alt: "Chromium Memory FYI console" } links { - text: "packager" - url: "/p/chromium/g/chromium.packager" - alt: "Chromium Packager console" - } - links { text: "perf" url: "/p/chrome/g/chrome.perf/console" alt: "Chromium Perf console" @@ -14866,16 +14876,16 @@ alt: "Chromium GPU console" } links { + text: "infra" + url: "/p/chromium/g/chromium.infra" + alt: "Chromium Infra console" + } + links { text: "memory.fyi" url: "/p/chromium/g/chromium.memory.fyi" alt: "Chromium Memory FYI console" } links { - text: "packager" - url: "/p/chromium/g/chromium.packager" - alt: "Chromium Packager console" - } - links { text: "perf" url: "/p/chrome/g/chrome.perf/console" alt: "Chromium Perf console" @@ -15400,16 +15410,16 @@ alt: "Chromium GPU console" } links { + text: "infra" + url: "/p/chromium/g/chromium.infra" + alt: "Chromium Infra console" + } + links { text: "memory.fyi" url: "/p/chromium/g/chromium.memory.fyi" alt: "Chromium Memory FYI console" } links { - text: "packager" - url: "/p/chromium/g/chromium.packager" - alt: "Chromium Packager console" - } - links { text: "perf" url: "/p/chrome/g/chrome.perf/console" alt: "Chromium Perf console" @@ -15774,16 +15784,16 @@ alt: "Chromium GPU console" } links { + text: "infra" + url: "/p/chromium/g/chromium.infra" + alt: "Chromium Infra console" + } + links { text: "memory.fyi" url: "/p/chromium/g/chromium.memory.fyi" alt: "Chromium Memory FYI console" } links { - text: "packager" - url: "/p/chromium/g/chromium.packager" - alt: "Chromium Packager console" - } - links { text: "perf" url: "/p/chrome/g/chrome.perf/console" alt: "Chromium Perf console" @@ -16189,16 +16199,16 @@ alt: "Chromium GPU console" } links { + text: "infra" + url: "/p/chromium/g/chromium.infra" + alt: "Chromium Infra console" + } + links { text: "memory.fyi" url: "/p/chromium/g/chromium.memory.fyi" alt: "Chromium Memory FYI console" } links { - text: "packager" - url: "/p/chromium/g/chromium.packager" - alt: "Chromium Packager console" - } - links { text: "perf" url: "/p/chrome/g/chrome.perf/console" alt: "Chromium Perf console" @@ -16568,16 +16578,16 @@ alt: "Chromium GPU console" } links { + text: "infra" + url: "/p/chromium/g/chromium.infra" + alt: "Chromium Infra console" + } + links { text: "memory.fyi" url: "/p/chromium/g/chromium.memory.fyi" alt: "Chromium Memory FYI console" } links { - text: "packager" - url: "/p/chromium/g/chromium.packager" - alt: "Chromium Packager console" - } - links { text: "perf" url: "/p/chrome/g/chrome.perf/console" alt: "Chromium Perf console" @@ -16978,16 +16988,16 @@ alt: "Chromium GPU console" } links { + text: "infra" + url: "/p/chromium/g/chromium.infra" + alt: "Chromium Infra console" + } + links { text: "memory.fyi" url: "/p/chromium/g/chromium.memory.fyi" alt: "Chromium Memory FYI console" } links { - text: "packager" - url: "/p/chromium/g/chromium.packager" - alt: "Chromium Packager console" - } - links { text: "perf" url: "/p/chrome/g/chrome.perf/console" alt: "Chromium Perf console" @@ -17330,16 +17340,16 @@ alt: "Chromium GPU console" } links { + text: "infra" + url: "/p/chromium/g/chromium.infra" + alt: "Chromium Infra console" + } + links { text: "memory.fyi" url: "/p/chromium/g/chromium.memory.fyi" alt: "Chromium Memory FYI console" } links { - text: "packager" - url: "/p/chromium/g/chromium.packager" - alt: "Chromium Packager console" - } - links { text: "perf" url: "/p/chrome/g/chrome.perf/console" alt: "Chromium Perf console" @@ -17729,6 +17739,9 @@ name: "buildbucket/luci.chromium.try/chromeos-amd64-generic-rel-compilator" } builders { + name: "buildbucket/luci.chromium.try/chromeos-amd64-generic-rel-rts" + } + builders { name: "buildbucket/luci.chromium.try/chromeos-arm-generic-dbg" } builders { @@ -18113,6 +18126,9 @@ name: "buildbucket/luci.chromium.try/linux-chromeos-rel-compilator" } builders { + name: "buildbucket/luci.chromium.try/linux-chromeos-rel-rts" + } + builders { name: "buildbucket/luci.chromium.try/linux-clang-tidy-rel" } builders { @@ -18164,6 +18180,9 @@ name: "buildbucket/luci.chromium.try/linux-lacros-rel-compilator" } builders { + name: "buildbucket/luci.chromium.try/linux-lacros-rel-rts" + } + builders { name: "buildbucket/luci.chromium.try/linux-lacros-version-skew-fyi" } builders { @@ -18985,6 +19004,9 @@ name: "buildbucket/luci.chromium.try/chromeos-amd64-generic-rel-compilator" } builders { + name: "buildbucket/luci.chromium.try/chromeos-amd64-generic-rel-rts" + } + builders { name: "buildbucket/luci.chromium.try/chromeos-arm-generic-dbg" } builders { @@ -19051,6 +19073,9 @@ name: "buildbucket/luci.chromium.try/linux-chromeos-rel-compilator" } builders { + name: "buildbucket/luci.chromium.try/linux-chromeos-rel-rts" + } + builders { name: "buildbucket/luci.chromium.try/linux-lacros-dbg" } builders { @@ -19059,6 +19084,9 @@ builders { name: "buildbucket/luci.chromium.try/linux-lacros-rel-compilator" } + builders { + name: "buildbucket/luci.chromium.try/linux-lacros-rel-rts" + } builder_view_only: true } consoles { @@ -19188,6 +19216,17 @@ builder_view_only: true } consoles { + id: "tryserver.chromium.infra" + name: "tryserver.chromium.infra" + builders { + name: "buildbucket/luci.chromium.try/3pp-linux-amd64-packager" + } + builders { + name: "buildbucket/luci.chromium.try/3pp-mac-amd64-packager" + } + builder_view_only: true +} +consoles { id: "tryserver.chromium.linux" name: "tryserver.chromium.linux" builders { @@ -19636,17 +19675,6 @@ builder_view_only: true } consoles { - id: "tryserver.chromium.packager" - name: "tryserver.chromium.packager" - builders { - name: "buildbucket/luci.chromium.try/3pp-linux-amd64-packager" - } - builders { - name: "buildbucket/luci.chromium.try/3pp-mac-amd64-packager" - } - builder_view_only: true -} -consoles { id: "tryserver.chromium.rust" name: "tryserver.chromium.rust" builders {
diff --git a/infra/config/generated/luci/luci-scheduler-dev.cfg b/infra/config/generated/luci/luci-scheduler-dev.cfg index 2e841043..8aedce02 100644 --- a/infra/config/generated/luci/luci-scheduler-dev.cfg +++ b/infra/config/generated/luci/luci-scheduler-dev.cfg
@@ -14,6 +14,15 @@ } } job { + id: "linux-local-ssd-rel-dev" + realm: "ci" + buildbucket { + server: "cr-buildbucket-dev.appspot.com" + bucket: "ci" + builder: "linux-local-ssd-rel-dev" + } +} +job { id: "linux-rel-dev" realm: "ci" buildbucket { @@ -32,12 +41,12 @@ } } job { - id: "linux-ssd-rel-dev" + id: "linux-remote-ssd-rel-dev" realm: "ci" buildbucket { server: "cr-buildbucket-dev.appspot.com" bucket: "ci" - builder: "linux-ssd-rel-dev" + builder: "linux-remote-ssd-rel-dev" } } job { @@ -80,9 +89,10 @@ id: "chromium-gitiles-trigger" realm: "ci" triggers: "android-pie-arm64-rel-dev" + triggers: "linux-local-ssd-rel-dev" triggers: "linux-rel-dev" triggers: "linux-rel-jammy-dev" - triggers: "linux-ssd-rel-dev" + triggers: "linux-remote-ssd-rel-dev" triggers: "mac-arm-rel-dev" triggers: "mac-rel-dev" triggers: "win-rel-dev"
diff --git a/infra/config/generated/luci/luci-scheduler.cfg b/infra/config/generated/luci/luci-scheduler.cfg index 0e77cd62..a1d3c83 100644 --- a/infra/config/generated/luci/luci-scheduler.cfg +++ b/infra/config/generated/luci/luci-scheduler.cfg
@@ -1622,6 +1622,24 @@ } } job { + id: "Linux Builder reclient test (unified uploads)" + realm: "reclient" + buildbucket { + server: "cr-buildbucket.appspot.com" + bucket: "reclient" + builder: "Linux Builder reclient test (unified uploads)" + } +} +job { + id: "Linux Builder reclient test (unified uploads) untrusted" + realm: "reclient" + buildbucket { + server: "cr-buildbucket.appspot.com" + bucket: "reclient" + builder: "Linux Builder reclient test (unified uploads) untrusted" + } +} +job { id: "Linux Builder reclient test untrusted" realm: "reclient" buildbucket { @@ -6703,6 +6721,8 @@ triggers: "Linux Builder reclient staging" triggers: "Linux Builder reclient staging untrusted" triggers: "Linux Builder reclient test" + triggers: "Linux Builder reclient test (unified uploads)" + triggers: "Linux Builder reclient test (unified uploads) untrusted" triggers: "Linux Builder reclient test untrusted" triggers: "Mac Builder reclient staging" triggers: "Mac Builder reclient staging untrusted"
diff --git a/infra/config/generated/testing/gn_isolate_map.pyl b/infra/config/generated/testing/gn_isolate_map.pyl index 93af1f48..578d74e 100644 --- a/infra/config/generated/testing/gn_isolate_map.pyl +++ b/infra/config/generated/testing/gn_isolate_map.pyl
@@ -753,6 +753,10 @@ "label": "//testing:empty_main", "type": "additional_compile_target", }, + "env_chromium_unittests": { + "label": "//third_party/leveldatabase:env_chromium_unittests", + "type": "console_test_launcher", + }, "events_unittests": { "label": "//ui/events:events_unittests", "type": "windowed_test_launcher", @@ -1063,6 +1067,10 @@ "label": "//ui/latency:latency_unittests", "type": "console_test_launcher", }, + "leveldb_unittests": { + "label": "//third_party/leveldatabase:leveldb_unittests", + "type": "console_test_launcher", + }, "libcups_unittests": { "label": "//chrome/services/cups_proxy:libcups_unittests", "type": "console_test_launcher",
diff --git a/infra/config/subprojects/chromium/ci.star b/infra/config/subprojects/chromium/ci.star index 233eb18..11389c56 100644 --- a/infra/config/subprojects/chromium/ci.star +++ b/infra/config/subprojects/chromium/ci.star
@@ -156,11 +156,11 @@ exec("./ci/chromium.gpu.star") exec("./ci/chromium.gpu.experimental.star") exec("./ci/chromium.gpu.fyi.star") +exec("./ci/chromium.infra.star") exec("./ci/chromium.linux.star") exec("./ci/chromium.mac.star") exec("./ci/chromium.memory.star") exec("./ci/chromium.memory.fyi.star") -exec("./ci/chromium.packager.star") exec("./ci/chromium.rust.star") exec("./ci/chromium.swangle.star") exec("./ci/chromium.updater.star")
diff --git a/infra/config/subprojects/chromium/ci/chromium.packager.star b/infra/config/subprojects/chromium/ci/chromium.infra.star similarity index 94% rename from infra/config/subprojects/chromium/ci/chromium.packager.star rename to infra/config/subprojects/chromium/ci/chromium.infra.star index 1893575f8..f6aac23f 100644 --- a/infra/config/subprojects/chromium/ci/chromium.packager.star +++ b/infra/config/subprojects/chromium/ci/chromium.infra.star
@@ -1,26 +1,32 @@ # Copyright 2021 The Chromium Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""Definitions of builders in the chromium.packager builder group.""" +"""Definitions of builders in the chromium.infra builder group.""" load("//lib/builders.star", "os", "sheriff_rotations") load("//lib/ci.star", "ci") load("//lib/consoles.star", "consoles") ci.defaults.set( - builder_group = "chromium.packager", + builder_group = "chromium.infra", pool = ci.DEFAULT_POOL, cores = 8, os = os.LINUX_DEFAULT, execution_timeout = ci.DEFAULT_EXECUTION_TIMEOUT, - service_account = "chromium-cipd-builder@chops-service-accounts.iam.gserviceaccount.com", + service_account = ci.DEFAULT_SERVICE_ACCOUNT, ) consoles.console_view( - name = "chromium.packager", + name = "chromium.infra", ) -ci.builder( +def packager_builder(**kwargs): + return ci.builder( + service_account = "chromium-cipd-builder@chops-service-accounts.iam.gserviceaccount.com", + **kwargs + ) + +packager_builder( name = "3pp-linux-amd64-packager", executable = "recipe:chromium_3pp", # Every 6 hours starting at 5am UTC. @@ -28,7 +34,7 @@ triggered_by = [], builderless = False, console_view_entry = consoles.console_view_entry( - category = "3pp|linux", + category = "packager|3pp|linux", short_name = "amd64", ), notifies = ["chromium-3pp-packager"], @@ -49,7 +55,7 @@ }, ) -ci.builder( +packager_builder( name = "3pp-mac-amd64-packager", executable = "recipe:chromium_3pp", # TODO(crbug.com/1267449): Trigger builds routinely once works fine. @@ -59,7 +65,7 @@ cores = None, os = os.MAC_DEFAULT, console_view_entry = consoles.console_view_entry( - category = "3pp|mac", + category = "packager|3pp|mac", short_name = "amd64", ), notifies = ["chromium-3pp-packager"], @@ -71,20 +77,20 @@ }, ) -ci.builder( +packager_builder( name = "android-androidx-packager", executable = "recipe:android/androidx_packager", schedule = "0 7,14,22 * * * *", triggered_by = [], sheriff_rotations = sheriff_rotations.ANDROID, console_view_entry = consoles.console_view_entry( - category = "android", + category = "packager|android", short_name = "androidx", ), notifies = ["chromium-androidx-packager"], ) -ci.builder( +packager_builder( name = "android-avd-packager", executable = "recipe:android/avd_packager", # Triggered manually through the scheduler UI @@ -92,7 +98,7 @@ schedule = "triggered", triggered_by = [], console_view_entry = consoles.console_view_entry( - category = "android", + category = "packager|android", short_name = "avd", ), properties = { @@ -125,13 +131,13 @@ }, ) -ci.builder( +packager_builder( name = "android-sdk-packager", executable = "recipe:android/sdk_packager", schedule = "0 7 * * *", triggered_by = [], console_view_entry = consoles.console_view_entry( - category = "android", + category = "packager|android", short_name = "sdk", ), properties = { @@ -271,7 +277,7 @@ }, ) -ci.builder( +packager_builder( name = "rts-model-packager", executable = "recipe:chromium_rts/create_model", schedule = "0 9 * * *", # at 1AM or 2AM PT (depending on DST), once a day. @@ -279,7 +285,7 @@ builderless = False, cores = None, console_view_entry = consoles.console_view_entry( - category = "rts", + category = "packager|rts", short_name = "create-model", ), execution_timeout = 10 * time.hour,
diff --git a/infra/config/subprojects/chromium/try.star b/infra/config/subprojects/chromium/try.star index 4746adc..19c73ad 100644 --- a/infra/config/subprojects/chromium/try.star +++ b/infra/config/subprojects/chromium/try.star
@@ -169,9 +169,9 @@ exec("./try/tryserver.chromium.cft.star") exec("./try/tryserver.chromium.dawn.star") exec("./try/tryserver.chromium.fuchsia.star") +exec("./try/tryserver.chromium.infra.star") exec("./try/tryserver.chromium.linux.star") exec("./try/tryserver.chromium.mac.star") -exec("./try/tryserver.chromium.packager.star") exec("./try/tryserver.chromium.rust.star") exec("./try/tryserver.chromium.tricium.star") exec("./try/tryserver.chromium.updater.star")
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star b/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star index 9b5e483..fe595af 100644 --- a/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star +++ b/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star
@@ -353,3 +353,42 @@ ], ), ) + +try_.builder( + name = "chromeos-amd64-generic-rel-rts", + mirrors = builder_config.copy_from("try/chromeos-amd64-generic-rel"), + try_settings = builder_config.try_settings( + rts_config = builder_config.rts_config( + condition = builder_config.rts_condition.QUICK_RUN_ONLY, + ), + ), + experiments = { + "chromium_rts.inverted_rts": 100, + }, +) + +try_.builder( + name = "linux-chromeos-rel-rts", + mirrors = builder_config.copy_from("try/linux-chromeos-rel"), + try_settings = builder_config.try_settings( + rts_config = builder_config.rts_config( + condition = builder_config.rts_condition.QUICK_RUN_ONLY, + ), + ), + experiments = { + "chromium_rts.inverted_rts": 100, + }, +) + +try_.builder( + name = "linux-lacros-rel-rts", + mirrors = builder_config.copy_from("try/linux-lacros-rel"), + try_settings = builder_config.try_settings( + rts_config = builder_config.rts_config( + condition = builder_config.rts_condition.QUICK_RUN_ONLY, + ), + ), + experiments = { + "chromium_rts.inverted_rts": 100, + }, +)
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.packager.star b/infra/config/subprojects/chromium/try/tryserver.chromium.infra.star similarity index 90% rename from infra/config/subprojects/chromium/try/tryserver.chromium.packager.star rename to infra/config/subprojects/chromium/try/tryserver.chromium.infra.star index fd41beb..e216b736 100644 --- a/infra/config/subprojects/chromium/try/tryserver.chromium.packager.star +++ b/infra/config/subprojects/chromium/try/tryserver.chromium.infra.star
@@ -1,7 +1,7 @@ # Copyright 2021 The Chromium Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""Definitions of builders in the tryserver.chromium.packager builder group.""" +"""Definitions of builders in the tryserver.chromium.infra builder group.""" load("//lib/builders.star", "os") load("//lib/try.star", "try_") @@ -9,14 +9,14 @@ try_.defaults.set( executable = "recipe:chromium_3pp", - builder_group = "tryserver.chromium.packager", + builder_group = "tryserver.chromium.infra", pool = try_.DEFAULT_POOL, execution_timeout = try_.DEFAULT_EXECUTION_TIMEOUT, service_account = "chromium-cipd-try-builder@chops-service-accounts.iam.gserviceaccount.com", ) consoles.list_view( - name = "tryserver.chromium.packager", + name = "tryserver.chromium.infra", ) try_.builder(
diff --git a/infra/config/subprojects/reclient/reclient.star b/infra/config/subprojects/reclient/reclient.star index 40cdddf8..4d1bb5d 100644 --- a/infra/config/subprojects/reclient/reclient.star +++ b/infra/config/subprojects/reclient/reclient.star
@@ -152,6 +152,28 @@ console_view_category = "linux", ) +fyi_reclient_test_builder( + name = "Linux Builder reclient test (unified uploads)", + builder_spec = builder_config.copy_from( + "ci/Linux Builder", + lambda spec: structs.evolve( + spec, + gclient_config = structs.extend( + spec.gclient_config, + apply_configs = [ + "reclient_test", + ], + ), + build_gs_bucket = "chromium-fyi-archive", + ), + ), + os = os.LINUX_DEFAULT, + console_view_category = "linux", + reclient_bootstrap_env = { + "GLOG_use_unified_uploads": "true", + }, +) + fyi_reclient_staging_builder( name = "Mac Builder reclient staging", builder_spec = builder_config.copy_from(
diff --git a/infra/config/targets/targets.star b/infra/config/targets/targets.star index 094d485..9ac2a93 100644 --- a/infra/config/targets/targets.star +++ b/infra/config/targets/targets.star
@@ -936,6 +936,11 @@ label = "//testing:empty_main", ) +targets.console_test_launcher( + name = "env_chromium_unittests", + label = "//third_party/leveldatabase:env_chromium_unittests", +) + targets.windowed_test_launcher( name = "events_unittests", label = "//ui/events:events_unittests", @@ -1315,6 +1320,11 @@ ) targets.console_test_launcher( + name = "leveldb_unittests", + label = "//third_party/leveldatabase:leveldb_unittests", +) + +targets.console_test_launcher( name = "libcups_unittests", label = "//chrome/services/cups_proxy:libcups_unittests", )
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd index d025673..e610ebac 100644 --- a/ios/chrome/app/strings/ios_strings.grd +++ b/ios/chrome/app/strings/ios_strings.grd
@@ -2006,7 +2006,7 @@ <message name="IDS_IOS_PRICE_NOTIFICATIONS_SETTINGS_ALERT_TITLE" desc="Title for Price Notifications UI Alert Prompt displayed from the settings menu that redirects the user to the iOS push notifications permission page."> Turn on Price Alerts? </message> - <message name="IDS_IOS_PRICE_NOTIFICATIONS_TITLE" desc="Title for Price Notifications settings menu."> + <message name="IDS_IOS_NOTIFICATIONS_TITLE" desc="Title for Notifications settings menu."> Notifications </message> <message name="IDS_IOS_PRICE_NOTIFICATIONS_OVERFLOW_MENU_TITLE" desc="Title for Price Tracking Notifications overflow menu destination title."> @@ -2834,7 +2834,7 @@ You can use saved addresses across Google products. This address is saved in your Google Account, <ph name="USER_EMAIL">$1<ex>janedoe@google.com</ex></ph>. </message> <message name="IDS_IOS_AUTOFILL_ADDRESS_MIGRATE_IN_ACCOUNT_FOOTER" desc="Footer text shown in the address migration prompt to account. [iOS only]"> - This address is saved only to Chrome. To use it across Google products, save it in your Google Account, <ph name="USER_EMAIL">$1<ex>janedoe@google.com</ex></ph>. + This address is currently saved to Chrome. To use it across Google products, save it in your Google Account, <ph name="USER_EMAIL">$1<ex>janedoe@google.com</ex></ph>. </message> <message name="IDS_IOS_SETTINGS_EDIT_AUTOFILL_ADDRESS_REQUIREMENT_ERROR" desc="Error shown when the address is edited in settings and one of the required fields is empty. [iOS only]"> {count, plural, @@ -2998,8 +2998,11 @@ <message name="IDS_IOS_DISMISS_WARNING" desc="Button or dialog title which is shown on Password Details Screen to allow the user to dismiss a compromised password warning. [iOS only]" meaning="Title-cased"> Dismiss Warning </message> + <message name="IDS_IOS_DISMISS_WARNING_DIALOG_TITLE" desc="Title of the dialog presented to the user when they want to dismiss a compromised password warning. [iOS only]" meaning="Title-cased"> + Dismiss Warning? + </message> <message name="IDS_IOS_DISMISS_WARNING_DIALOG_MESSAGE" desc="Message of the dialog presented to the user when they want to dismiss a compromised password warning. [iOS only]"> - The warning can be found again later under Dismissed Warnings in Compromised Passwords section. + This password was exposed in a data breach on the internet. If you don't have time to change it right now, Google recommends keeping this warning to remind yourself later. </message> <message name="IDS_IOS_DISMISS_WARNING_DIALOG_DISMISS_BUTTON" desc="Button of the dialog presented to the user when they want to dismiss a compromised password warning. Button is used to confirm that they want to dismiss the warning. [iOS only]"> Dismiss
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_AUTOFILL_ADDRESS_MIGRATE_IN_ACCOUNT_FOOTER.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_AUTOFILL_ADDRESS_MIGRATE_IN_ACCOUNT_FOOTER.png.sha1 index ce725475..54cbff0 100644 --- a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_AUTOFILL_ADDRESS_MIGRATE_IN_ACCOUNT_FOOTER.png.sha1 +++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_AUTOFILL_ADDRESS_MIGRATE_IN_ACCOUNT_FOOTER.png.sha1
@@ -1 +1 @@ -8f55472821234829f3cb2888fe6fa1a1c2b1ca9c \ No newline at end of file +ebba9d0a8593f4bb246eaac6768246755db94241 \ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_DISMISS_WARNING_DIALOG_MESSAGE.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_DISMISS_WARNING_DIALOG_MESSAGE.png.sha1 index bc2044d..25ebca9 100644 --- a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_DISMISS_WARNING_DIALOG_MESSAGE.png.sha1 +++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_DISMISS_WARNING_DIALOG_MESSAGE.png.sha1
@@ -1 +1 @@ -64c36a88e6f5e689ce5154410db744c6c95696a4 \ No newline at end of file +9b7d3bd047e2c648e7e2c3f1e48d173793e354ae \ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_DISMISS_WARNING_DIALOG_TITLE.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_DISMISS_WARNING_DIALOG_TITLE.png.sha1 new file mode 100644 index 0000000..25ebca9 --- /dev/null +++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_DISMISS_WARNING_DIALOG_TITLE.png.sha1
@@ -0,0 +1 @@ +9b7d3bd047e2c648e7e2c3f1e48d173793e354ae \ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_PRICE_NOTIFICATIONS_TITLE.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_NOTIFICATIONS_TITLE.png.sha1 similarity index 100% rename from ios/chrome/app/strings/ios_strings_grd/IDS_IOS_PRICE_NOTIFICATIONS_TITLE.png.sha1 rename to ios/chrome/app/strings/ios_strings_grd/IDS_IOS_NOTIFICATIONS_TITLE.png.sha1
diff --git a/ios/chrome/browser/bring_android_tabs/BUILD.gn b/ios/chrome/browser/bring_android_tabs/BUILD.gn index a3ffdae6..7e2dbd7 100644 --- a/ios/chrome/browser/bring_android_tabs/BUILD.gn +++ b/ios/chrome/browser/bring_android_tabs/BUILD.gn
@@ -65,3 +65,32 @@ "//ios/chrome/browser/synced_sessions", ] } + +source_set("unit_tests") { + configs += [ "//build/config/compiler:enable_arc" ] + testonly = true + sources = [ "bring_android_tabs_to_ios_service_unittest.mm" ] + deps = [ + ":bring_android_tabs", + ":features", + ":metrics", + "//base/test:test_support", + "//components/prefs", + "//components/prefs:test_support", + "//components/segmentation_platform/embedder/default_model", + "//components/segmentation_platform/public", + "//components/segmentation_platform/public:test_support", + "//components/sessions:session_id", + "//components/sync:test_support", + "//components/sync/base", + "//components/sync/driver", + "//components/sync_device_info", + "//components/sync_sessions", + "//components/sync_sessions:test_support", + "//ios/chrome/browser/prefs:pref_names", + "//ios/chrome/browser/segmentation_platform", + "//ios/chrome/browser/sync", + "//ios/web/public/test", + "//testing/gtest", + ] +}
diff --git a/ios/chrome/browser/bring_android_tabs/bring_android_tabs_to_ios_service_unittest.mm b/ios/chrome/browser/bring_android_tabs/bring_android_tabs_to_ios_service_unittest.mm new file mode 100644 index 0000000..95bb5db --- /dev/null +++ b/ios/chrome/browser/bring_android_tabs/bring_android_tabs_to_ios_service_unittest.mm
@@ -0,0 +1,318 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/bring_android_tabs/bring_android_tabs_to_ios_service.h" + +#import "base/test/metrics/histogram_tester.h" +#import "base/test/scoped_feature_list.h" +#import "components/prefs/pref_registry_simple.h" +#import "components/prefs/pref_service.h" +#import "components/prefs/testing_pref_service.h" +#import "components/segmentation_platform/embedder/default_model/device_switcher_model.h" +#import "components/segmentation_platform/embedder/default_model/device_switcher_result_dispatcher.h" +#import "components/segmentation_platform/public/field_trial_register.h" +#import "components/segmentation_platform/public/result.h" +#import "components/segmentation_platform/public/segmentation_platform_service.h" +#import "components/segmentation_platform/public/testing/mock_segmentation_platform_service.h" +#import "components/sessions/core/session_id.h" +#import "components/sessions/core/session_types.h" +#import "components/sync/base/user_selectable_type.h" +#import "components/sync/driver/sync_service.h" +#import "components/sync/driver/sync_user_settings.h" +#import "components/sync/test/test_sync_service.h" +#import "components/sync_device_info/device_info.h" +#import "components/sync_sessions/open_tabs_ui_delegate.h" +#import "components/sync_sessions/session_sync_service.h" +#import "components/sync_sessions/session_sync_test_helper.h" +#import "components/sync_sessions/synced_session.h" +#import "ios/chrome/browser/bring_android_tabs/features.h" +#import "ios/chrome/browser/bring_android_tabs/metrics.h" +#import "ios/chrome/browser/prefs/pref_names.h" +#import "ios/chrome/browser/segmentation_platform/segmentation_platform_config.h" +#import "ios/chrome/browser/sync/session_sync_service_factory.h" +#import "ios/web/public/test/web_task_environment.h" +#import "testing/platform_test.h" +#import "ui/base/device_form_factor.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace bring_android_tabs { + +// Fake DeviceSwitcherResultDispatcher that takes a `classification_label` as +// input. DeviceSwitcherResultDispatcher is a dependency of +// BringAndroidTabsToIOSService. +class FakeDeviceSwitcherResultDispatcher + : public segmentation_platform::DeviceSwitcherResultDispatcher { + public: + FakeDeviceSwitcherResultDispatcher( + segmentation_platform::SegmentationPlatformService* segmentation_service, + syncer::SyncService* sync_service, + PrefService* prefs, + segmentation_platform::FieldTrialRegister* field_trial_register, + const char* classification_label) + : DeviceSwitcherResultDispatcher(segmentation_service, + sync_service, + prefs, + field_trial_register) { + classification_label_ = classification_label; + } + + // Returns a classification result with a successful PredictionStatus and + // label `classification_label`. + segmentation_platform::ClassificationResult GetCachedClassificationResult() + override { + segmentation_platform::ClassificationResult classification_result = + segmentation_platform::ClassificationResult( + segmentation_platform::PredictionStatus::kSucceeded); + classification_result.ordered_labels = {classification_label_}; + return classification_result; + } + + private: + const char* classification_label_; +}; + +// Mock SessionSyncService used to override the call to GetOpenTabsUIDelegate(). +// SessionSyncService is a dependency of BringAndroidTabsToIOSService. +class MockSessionSyncService : public sync_sessions::SessionSyncService { + public: + MOCK_METHOD(sync_sessions::OpenTabsUIDelegate*, + GetOpenTabsUIDelegate, + (), + (override)); + MOCK_METHOD(syncer::GlobalIdMapper*, GetGlobalIdMapper, (), (const)); + MOCK_METHOD(base::CallbackListSubscription, + SubscribeToForeignSessionsChanged, + (const base::RepeatingClosure&)); + MOCK_METHOD(base::WeakPtr<syncer::ModelTypeControllerDelegate>, + GetControllerDelegate, + ()); + MOCK_METHOD(void, ProxyTabsStateChanged, (syncer::DataTypeController::State)); +}; + +// Mock OpenTabsUIDelegate that takes the time the SyncedSession was last +// modified as input and creates a fake open tab. OpenTabsUIDelegate is a +// dependency of SessionSyncService. +class MockOpenTabsUIDelegate : public sync_sessions::OpenTabsUIDelegate { + public: + MockOpenTabsUIDelegate(base::Time modified_time) + : sync_sessions::OpenTabsUIDelegate() { + modified_time_ = modified_time; + } + + MOCK_METHOD(bool, + GetAllForeignSessions, + (std::vector<const sync_sessions::SyncedSession*>*), + (override)); + + MOCK_METHOD(bool, + GetForeignSessionTabs, + (const std::string&, std::vector<const sessions::SessionTab*>*), + (override)); + + MOCK_METHOD(bool, + GetForeignTab, + (const std::string&, SessionID, const sessions::SessionTab**)); + + MOCK_METHOD(void, DeleteForeignSession, (const std::string&)); + MOCK_METHOD(bool, + GetForeignSession, + (const std::string&, + std::vector<const sessions::SessionWindow*>*)); + MOCK_METHOD(bool, GetLocalSession, (const sync_sessions::SyncedSession**)); + + // Returns a fake tab with timestamp `modified_time_`. + sessions::SessionTab* Tab(SessionID session_id) { + sessions::SessionTab* tab = new sessions::SessionTab(); + tab->window_id = session_id; + tab->tab_id = session_id; + tab->tab_visual_index = 100; + tab->current_navigation_index = 1000; + tab->pinned = false; + tab->extension_app_id = "fake"; + tab->user_agent_override.ua_string_override = "fake"; + tab->timestamp = modified_time_; + tab->navigations.resize(100); + tab->session_storage_persistent_id = "fake"; + return tab; + } + + // Returns a fake session with modified time `modified_time_` and form factor + // type `device_form_factor`. + sync_sessions::SyncedSession* Session( + sync_pb::SyncEnums::DeviceType device_type, + syncer::DeviceInfo::FormFactor device_form_factor) { + sync_sessions::SyncedSession* session = new sync_sessions::SyncedSession(); + session->SetDeviceTypeAndFormFactor(device_type, device_form_factor); + session->SetModifiedTime(modified_time_); + return session; + } + + // Mocks the responses for GetAllForeignSessions() and + // GetForeignSessionTabs(). + void MockResponses() { + ON_CALL(*this, GetAllForeignSessions) + .WillByDefault([this](std::vector<const sync_sessions::SyncedSession*>* + sessions) { + sessions->push_back(Session(sync_pb::SyncEnums_DeviceType_TYPE_PHONE, + syncer::DeviceInfo::FormFactor::kPhone)); + sessions->push_back(Session(sync_pb::SyncEnums_DeviceType_TYPE_PHONE, + syncer::DeviceInfo::FormFactor::kPhone)); + sessions->push_back(Session(sync_pb::SyncEnums_DeviceType_TYPE_TABLET, + syncer::DeviceInfo::FormFactor::kTablet)); + return true; + }); + ON_CALL(*this, GetForeignSessionTabs) + .WillByDefault([this](const std::string& tag, + std::vector<const sessions::SessionTab*>* tabs) { + tabs->push_back(Tab(SessionID::FromSerializedValue(100))); + tabs->push_back(Tab(SessionID::FromSerializedValue(150))); + return true; + }); + } + + private: + base::Time modified_time_; +}; + +} // namespace bring_android_tabs + +// Test fixture for BringAndroidTabsToIOSService. +class BringAndroidTabsToIOSServiceTest : public PlatformTest { + protected: + BringAndroidTabsToIOSServiceTest() : PlatformTest() { + test_sync_service_ = std::make_unique<syncer::TestSyncService>(); + prefs_ = std::make_unique<TestingPrefServiceSimple>(); + segmentation_platform::DeviceSwitcherResultDispatcher::RegisterProfilePrefs( + prefs_->registry()); + prefs_->registry()->RegisterBooleanPref( + prefs::kIosBringAndroidTabsPromptDisplayed, false); + } + + // Helper method that creates an instance of BringAndroidTabsToIOSService, + // loads the user's tabs, and returns the number of tabs loaded (if any). + // Also records that the prompt is displayed if at least one tab is loaded. + int NumberOfTabsLoaded(bool is_android_switcher, bool tabs_recently_active) { + // Enable feature. + base::test::ScopedFeatureList feature_list; + feature_list.InitAndEnableFeature(kBringYourOwnTabsIOS); + + // Create the fake tab. + base::Time session_time = tabs_recently_active + ? base::Time::Now() + : base::Time::Now() - base::Days(14); + auto tabs_delegate = + std::make_unique<bring_android_tabs::MockOpenTabsUIDelegate>( + session_time); + tabs_delegate->MockResponses(); + + // Create BringAndroidTabsToIOSService dependencies. + auto session_sync_service = + std::make_unique<bring_android_tabs::MockSessionSyncService>(); + ON_CALL(*session_sync_service, GetOpenTabsUIDelegate) + .WillByDefault(testing::Return(tabs_delegate.get())); + const char* classification_label = + is_android_switcher + ? segmentation_platform::DeviceSwitcherModel::kAndroidPhoneLabel + : segmentation_platform::DeviceSwitcherModel::kIosPhoneChromeLabel; + segmentation_platform::IOSFieldTrialRegisterImpl field_trial_register_ = + segmentation_platform::IOSFieldTrialRegisterImpl(); + bring_android_tabs::FakeDeviceSwitcherResultDispatcher dispatcher( + &segmentation_platform_service_, test_sync_service_.get(), prefs_.get(), + &field_trial_register_, classification_label); + + // Create the BringAndroidTabsToIOSService and load tabs. + BringAndroidTabsToIOSService bring_android_tabs_service( + &dispatcher, test_sync_service_.get(), session_sync_service.get(), + prefs_.get()); + bring_android_tabs_service.LoadTabs(); + int number_of_tabs = bring_android_tabs_service.GetNumberOfAndroidTabs(); + // Record that the prompt has displayed. + if (number_of_tabs > 0) { + bring_android_tabs_service.OnBringAndroidTabsPromptDisplayed(); + } + return number_of_tabs; + } + + // Helper method that checks if `prompt_attempt_status` is recorded in the + // histogram with name `kPromptAttemptStatusHistogramName`. The metrics + // recording in BringAndroidTabsToIOSServiceTest is only done for iPhone + // users. + void ExpectHistogram( + bring_android_tabs::PromptAttemptStatus prompt_attempt_status) { + if (ui::GetDeviceFormFactor() == ui::DEVICE_FORM_FACTOR_PHONE) { + histogram_tester_.ExpectBucketCount( + bring_android_tabs::kPromptAttemptStatusHistogramName, + static_cast<base::HistogramBase::Sample>(prompt_attempt_status), 1); + } + } + + protected: + web::WebTaskEnvironment task_environment_; + testing::NiceMock<segmentation_platform::MockSegmentationPlatformService> + segmentation_platform_service_; + std::unique_ptr<syncer::TestSyncService> test_sync_service_; + std::unique_ptr<TestingPrefServiceSimple> prefs_; + base::HistogramTester histogram_tester_; +}; + +// Tests that no tabs are loaded when the user has not synced their tabs. +TEST_F(BringAndroidTabsToIOSServiceTest, UserNotSynced) { + // Set something other than `kTabs` as the selected type. + test_sync_service_->GetUserSettings()->SetSelectedTypes( + /*sync_everything=*/false, + /*types=*/syncer::UserSelectableTypeSet( + syncer::UserSelectableType::kPasswords)); + EXPECT_EQ(NumberOfTabsLoaded(/*is_android_switcher=*/true, + /*tabs_recently_active=*/true), + 0); + ExpectHistogram(bring_android_tabs::PromptAttemptStatus::kTabSyncDisabled); +} + +// Tests that no tabs are loaded when the user is not an android switcher. +TEST_F(BringAndroidTabsToIOSServiceTest, UserNotAndroidSwitcher) { + EXPECT_EQ(NumberOfTabsLoaded(/*is_android_switcher=*/false, + /*tabs_recently_active=*/true), + 0); + ExpectHistogram(bring_android_tabs::PromptAttemptStatus::kNotAndroidSwitcher); +} + +// Tests that no tabs are loaded when the user's open tabs were not recently +// opened. +TEST_F(BringAndroidTabsToIOSServiceTest, UserDoesNotHaveRecentlyOpenedTabs) { + EXPECT_EQ(NumberOfTabsLoaded(/*is_android_switcher=*/true, + /*tabs_recently_active=*/false), + 0); + ExpectHistogram(bring_android_tabs::PromptAttemptStatus::kNoActiveTabs); +} + +// Tests that no tabs are loaded when the user has already seen the prompt in a +// previous session. +TEST_F(BringAndroidTabsToIOSServiceTest, UserHasSeenPrompt) { + if (ui::GetDeviceFormFactor() == ui::DEVICE_FORM_FACTOR_PHONE) { + // Load tabs and record prompt is displayed. + EXPECT_EQ(NumberOfTabsLoaded(/*is_android_switcher=*/true, + /*tabs_recently_active=*/true), + 4); + // Reload tabs. + EXPECT_EQ(NumberOfTabsLoaded(/*is_android_switcher=*/true, + /*tabs_recently_active=*/true), + 0); + ExpectHistogram( + bring_android_tabs::PromptAttemptStatus::kPromptShownAndDismissed); + } +} + +// Tests that the user's tab is loaded when they meet all criteria to be shown +// the Bring Android Tabs prompt. The prompt should only be shown on iPhone. +TEST_F(BringAndroidTabsToIOSServiceTest, UserMeetsAllCriteria) { + int expected_number_of_tabs = + ui::GetDeviceFormFactor() == ui::DEVICE_FORM_FACTOR_PHONE ? 4 : 0; + EXPECT_EQ(NumberOfTabsLoaded(/*is_android_switcher=*/true, + /*tabs_recently_active=*/true), + expected_number_of_tabs); + ExpectHistogram(bring_android_tabs::PromptAttemptStatus::kSuccess); +}
diff --git a/ios/chrome/browser/ui/autofill/autofill_profile_edit_table_view_controller.mm b/ios/chrome/browser/ui/autofill/autofill_profile_edit_table_view_controller.mm index 7c420b8c..379ea67e 100644 --- a/ios/chrome/browser/ui/autofill/autofill_profile_edit_table_view_controller.mm +++ b/ios/chrome/browser/ui/autofill/autofill_profile_edit_table_view_controller.mm
@@ -198,6 +198,10 @@ NSInteger itemType = [self.controller.tableViewModel itemTypeForIndexPath:indexPath]; if (itemType == ItemTypeFooter || itemType == ItemTypeError) { + if (!self.settingsView) { + cell.separatorInset = UIEdgeInsetsMake( + 0, self.controller.tableView.bounds.size.width, 0, 0); + } return cell; } @@ -542,16 +546,10 @@ CHECK(!self.settingsView); TableViewTextItem* item = [[TableViewTextItem alloc] initWithType:ItemTypeFooter]; - if (self.migrationPrompt) { - item.text = l10n_util::GetNSStringF( - IDS_IOS_AUTOFILL_ADDRESS_MIGRATE_IN_ACCOUNT_FOOTER, - base::SysNSStringToUTF16(_userEmail)); - } else { - item.text = l10n_util::GetNSStringF( - update ? IDS_IOS_SETTINGS_AUTOFILL_ACCOUNT_ADDRESS_FOOTER_TEXT - : IDS_IOS_AUTOFILL_SAVE_ADDRESS_IN_ACCOUNT_FOOTER, - base::SysNSStringToUTF16(_userEmail)); - } + item.text = l10n_util::GetNSStringF( + update ? IDS_IOS_SETTINGS_AUTOFILL_ACCOUNT_ADDRESS_FOOTER_TEXT + : IDS_IOS_AUTOFILL_SAVE_ADDRESS_IN_ACCOUNT_FOOTER, + base::SysNSStringToUTF16(_userEmail)); item.textFont = [UIFont preferredFontForTextStyle:UIFontTextStyleFootnote]; item.textColor = [UIColor colorNamed:kTextSecondaryColor]; return item;
diff --git a/ios/chrome/browser/ui/content_suggestions/BUILD.gn b/ios/chrome/browser/ui/content_suggestions/BUILD.gn index d6a9159..adae344 100644 --- a/ios/chrome/browser/ui/content_suggestions/BUILD.gn +++ b/ios/chrome/browser/ui/content_suggestions/BUILD.gn
@@ -128,19 +128,15 @@ sources = [ "content_suggestions_metrics_recorder.h", "content_suggestions_metrics_recorder.mm", - "ntp_home_metrics.h", - "ntp_home_metrics.mm", ] configs += [ "//build/config/compiler:enable_arc" ] deps = [ + ":constants", ":content_suggestions_constant", "//base", "//components/favicon_base", "//components/ntp_tiles", - "//ios/chrome/browser/browser_state", "//ios/chrome/browser/metrics:metrics_internal", - "//ios/chrome/browser/ntp", - "//ios/chrome/browser/ui/content_suggestions:constants", "//ios/chrome/browser/ui/content_suggestions/cells", "//ios/chrome/browser/ui/content_suggestions/cells:constants", "//ios/chrome/browser/ui/favicon", @@ -247,16 +243,14 @@ ":content_suggestions", ":content_suggestions_ui", ":content_suggestions_ui_util", + ":feature_flags", + ":metrics", "//base", "//base/test:test_support", "//components/favicon/core", "//components/favicon/core/test:test_support", "//components/ntp_tiles", - "//components/omnibox/browser:test_support", "//components/reading_list/core", - "//components/search", - "//components/search_engines", - "//components/signin/public/identity_manager", "//components/sync_preferences:test_support", "//ios/chrome/browser/browser_state:test_support", "//ios/chrome/browser/favicon", @@ -266,36 +260,28 @@ "//ios/chrome/browser/promos_manager:test_support", "//ios/chrome/browser/reading_list", "//ios/chrome/browser/reading_list:test_support", - "//ios/chrome/browser/search_engines", + "//ios/chrome/browser/search_engines:template_url_service_factory", "//ios/chrome/browser/shared/public/commands", "//ios/chrome/browser/signin", - "//ios/chrome/browser/signin", "//ios/chrome/browser/signin:test_support", - "//ios/chrome/browser/signin:test_support", - "//ios/chrome/browser/ui/content_suggestions:constants", - "//ios/chrome/browser/ui/content_suggestions:content_suggestions_ui", - "//ios/chrome/browser/ui/content_suggestions:feature_flags", - "//ios/chrome/browser/ui/content_suggestions:metrics", "//ios/chrome/browser/ui/content_suggestions/cells", - "//ios/chrome/browser/ui/content_suggestions/identifier", "//ios/chrome/browser/ui/favicon", - "//ios/chrome/browser/ui/ntp:logo", + "//ios/chrome/browser/ui/ntp", + "//ios/chrome/browser/ui/ntp/metrics", "//ios/chrome/browser/ui/start_surface", "//ios/chrome/browser/ui/start_surface:feature_flags", - "//ios/chrome/browser/ui/toolbar/test", - "//ios/chrome/browser/url:constants", "//ios/chrome/browser/url_loading", "//ios/chrome/browser/url_loading:test_support", "//ios/chrome/browser/web_state_list", - "//ios/chrome/browser/web_state_list:test_support", "//ios/chrome/common/app_group", "//ios/chrome/common/ntp_tile", "//ios/chrome/common/ui/favicon", + "//ios/chrome/test:block_cleanup_test", "//ios/chrome/test:test_support", "//ios/testing:block_swizzler", "//ios/web/public/test", "//ios/web/public/test/fakes", - "//services/network:test_support", + "//net", "//testing/gtest", "//third_party/ocmock", "//ui/base:test_support",
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.h b/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.h index cf74fc67..79c4552 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.h +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.h
@@ -16,7 +16,7 @@ @protocol FeedDelegate; @protocol NewTabPageControllerDelegate; @protocol NewTabPageDelegate; -@class NTPHomeMetrics; +@protocol NewTabPageMetricsDelegate; @protocol ThumbStripSupporting; @class ViewRevealingVerticalPanHandler; @@ -46,13 +46,14 @@ thumbStripSupporting; // Delegate for NTP related actions. -@property(nonatomic, weak) id<NewTabPageDelegate> ntpDelegate; +@property(nonatomic, weak) id<NewTabPageDelegate> NTPDelegate; // Delegate used to communicate to communicate events to the feed. @property(nonatomic, weak) id<FeedDelegate> feedDelegate; -// Recorder for the metrics related to the NTP. -@property(nonatomic, assign) NTPHomeMetrics* NTPMetrics; +// Delegate for reporting content suggestions actions to the NTP metrics +// recorder. +@property(nonatomic, weak) id<NewTabPageMetricsDelegate> NTPMetricsDelegate; // Reloads the suggestions. - (void)reload;
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.mm index 85033ed..20141a9 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.mm
@@ -107,6 +107,8 @@ - (void)start { DCHECK(self.browser); + DCHECK(self.NTPMetricsDelegate); + if (self.started) { // Prevent this coordinator from being started twice in a row return; @@ -146,7 +148,7 @@ PromosManagerFactory::GetForBrowserState(self.browser->GetBrowserState()); BOOL isGoogleDefaultSearchProvider = - [self.ntpDelegate isGoogleDefaultSearchEngine]; + [self.NTPDelegate isGoogleDefaultSearchEngine]; self.contentSuggestionsMetricsRecorder = [[ContentSuggestionsMetricsRecorder alloc] init]; @@ -161,7 +163,6 @@ browser:self.browser]; self.contentSuggestionsMediator.feedDelegate = self.feedDelegate; self.contentSuggestionsMediator.promosManager = promosManager; - self.contentSuggestionsMediator.NTPMetrics = self.NTPMetrics; self.contentSuggestionsMediator.contentSuggestionsMetricsRecorder = self.contentSuggestionsMetricsRecorder; // TODO(crbug.com/1045047): Use HandlerForProtocol after commands protocol @@ -173,6 +174,7 @@ self.contentSuggestionsMediator.webStateList = self.browser->GetWebStateList(); self.contentSuggestionsMediator.webState = self.webState; + self.contentSuggestionsMediator.NTPMetricsDelegate = self.NTPMetricsDelegate; self.contentSuggestionsViewController = [[ContentSuggestionsViewController alloc] init]; @@ -228,12 +230,12 @@ } - (void)returnToRecentTabWasAdded { - [self.ntpDelegate updateFeedLayout]; - [self.ntpDelegate setContentOffsetToTop]; + [self.NTPDelegate updateFeedLayout]; + [self.NTPDelegate setContentOffsetToTop]; } - (void)moduleWasRemoved { - [self.ntpDelegate updateFeedLayout]; + [self.NTPDelegate updateFeedLayout]; } - (UIEdgeInsets)safeAreaInsetsForDiscoverFeed {
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.h b/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.h index 12fc429..454a4542 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.h +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.h
@@ -34,7 +34,7 @@ @protocol FeedDelegate; class GURL; class LargeIconCache; -@class NTPHomeMetrics; +@protocol NewTabPageMetricsDelegate; class PromosManager; class ReadingListModel; @protocol SnackbarCommands; @@ -87,8 +87,9 @@ // The promos manager to alert if the user uses What's New. @property(nonatomic, assign) PromosManager* promosManager; -// Recorder for the metrics related to the NTP. -@property(nonatomic, assign) NTPHomeMetrics* NTPMetrics; +// Delegate for reporting content suggestions actions to the NTP metrics +// recorder. +@property(nonatomic, weak) id<NewTabPageMetricsDelegate> NTPMetricsDelegate; // Recorder for content suggestions metrics. @property(nonatomic, assign)
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.mm index 19b2693..8999346 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.mm
@@ -58,10 +58,10 @@ #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_metrics_recorder.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_tile_saver.h" #import "ios/chrome/browser/ui/content_suggestions/identifier/content_suggestions_section_information.h" -#import "ios/chrome/browser/ui/content_suggestions/ntp_home_metrics.h" #import "ios/chrome/browser/ui/content_suggestions/start_suggest_service_factory.h" #import "ios/chrome/browser/ui/ntp/feed_delegate.h" #import "ios/chrome/browser/ui/ntp/new_tab_page_feature.h" +#import "ios/chrome/browser/ui/ntp/new_tab_page_metrics_delegate.h" #import "ios/chrome/browser/ui/start_surface/start_surface_util.h" #import "ios/chrome/browser/ui/whats_new/whats_new_util.h" #import "ios/chrome/browser/url/chrome_url_constants.h" @@ -291,9 +291,10 @@ - (void)openMostVisitedItem:(NSObject*)item atIndex:(NSInteger)mostVisitedIndex { + // Checks if the item is a shortcut tile. Does not include Most Visited URL + // tiles. if ([item isKindOfClass:[ContentSuggestionsMostVisitedActionItem class]]) { - [self.NTPMetrics recordContentSuggestionsActionForType: - IOSContentSuggestionsActionType::kShortcuts]; + [self.NTPMetricsDelegate shortcutTileOpened]; ContentSuggestionsMostVisitedActionItem* mostVisitedItem = base::mac::ObjCCastStrict<ContentSuggestionsMostVisitedActionItem>( item); @@ -335,8 +336,7 @@ } - (void)openMostRecentTab { - [self.NTPMetrics recordContentSuggestionsActionForType: - IOSContentSuggestionsActionType::kReturnToRecentTab]; + [self.NTPMetricsDelegate recentTabTileOpened]; [self.contentSuggestionsMetricsRecorder recordMostRecentTabOpened]; [self hideRecentTabTile]; WebStateList* web_state_list = self.browser->GetWebStateList(); @@ -499,13 +499,12 @@ // Logs a histogram due to a Most Visited item being opened. - (void)logMostVisitedOpening:(ContentSuggestionsMostVisitedItem*)item atIndex:(NSInteger)mostVisitedIndex { - [self.NTPMetrics - recordAction:new_tab_page_uma::ACTION_OPENED_MOST_VISITED_ENTRY]; - [self.NTPMetrics recordContentSuggestionsActionForType: - IOSContentSuggestionsActionType::kMostVisitedTile]; + [self.NTPMetricsDelegate mostVisitedTileOpened]; [self.contentSuggestionsMetricsRecorder recordMostVisitedTileOpened:item - atIndex:mostVisitedIndex]; + atIndex:mostVisitedIndex + webState:self.browser->GetWebStateList() + ->GetActiveWebState()]; } // Shows a snackbar with an action to undo the removal of the most visited item
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator_unittest.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator_unittest.mm index 081d25c6..db3087c 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator_unittest.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator_unittest.mm
@@ -35,7 +35,8 @@ #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_feature.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator_util.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_metrics_recorder.h" -#import "ios/chrome/browser/ui/content_suggestions/ntp_home_metrics.h" +#import "ios/chrome/browser/ui/ntp/metrics/new_tab_page_metrics_recorder.h" +#import "ios/chrome/browser/ui/ntp/new_tab_page_metrics_delegate.h" #import "ios/chrome/browser/ui/start_surface/start_surface_recent_tab_browser_agent.h" #import "ios/chrome/browser/url_loading/fake_url_loading_browser_agent.h" #import "ios/chrome/browser/url_loading/url_loading_notifier_browser_agent.h" @@ -119,10 +120,6 @@ mediator_.consumer = consumer_; mediator_.webStateList = browser_.get()->GetWebStateList(); mediator_.webState = fake_web_state_.get(); - NTPMetrics_ = [[NTPHomeMetrics alloc] - initWithBrowserState:browser_->GetBrowserState()]; - mediator_.NTPMetrics = NTPMetrics_; - mediator_.NTPMetrics.webState = fake_web_state_.get(); metrics_recorder_ = [[ContentSuggestionsMetricsRecorder alloc] init]; mediator_.contentSuggestionsMetricsRecorder = metrics_recorder_; @@ -163,7 +160,6 @@ std::unique_ptr<favicon::LargeIconServiceImpl> large_icon_service_; std::unique_ptr<MockPromosManager> promos_manager_; ContentSuggestionsMediator* mediator_; - NTPHomeMetrics* NTPMetrics_; FakeUrlLoadingBrowserAgent* url_loader_; std::unique_ptr<base::HistogramTester> histogram_tester_; ContentSuggestionsMetricsRecorder* metrics_recorder_; @@ -174,16 +170,12 @@ TEST_F(ContentSuggestionsMediatorTest, TestOpenReadingList) { OCMExpect([dispatcher_ showReadingList]); - histogram_tester_->ExpectUniqueSample( - "IOS.ContentSuggestions.ActionOnNTP", - IOSContentSuggestionsActionType::kShortcuts, 0); + OCMExpect([mediator_.NTPMetricsDelegate shortcutTileOpened]); + // Action. ContentSuggestionsMostVisitedActionItem* readingList = ReadingListActionItem(); [mediator_ openMostVisitedItem:readingList atIndex:1]; - histogram_tester_->ExpectUniqueSample( - "IOS.ContentSuggestions.ActionOnNTP", - IOSContentSuggestionsActionType::kShortcuts, 1); // Test. EXPECT_OCMOCK_VERIFY(dispatcher_); @@ -195,14 +187,10 @@ ContentSuggestionsMostVisitedItem* item = [[ContentSuggestionsMostVisitedItem alloc] init]; item.URL = url; - histogram_tester_->ExpectUniqueSample( - "IOS.ContentSuggestions.ActionOnNTP", - IOSContentSuggestionsActionType::kMostVisitedTile, 0); + OCMExpect([mediator_.NTPMetricsDelegate mostVisitedTileOpened]); + // Action. [mediator_ openMostVisitedItem:item atIndex:0]; - histogram_tester_->ExpectUniqueSample( - "IOS.ContentSuggestions.ActionOnNTP", - IOSContentSuggestionsActionType::kMostVisitedTile, 1); // Test. EXPECT_EQ(url, url_loader_->last_params.web_params.url); @@ -228,7 +216,6 @@ WebStateOpener()); web::WebState* ntp_web_state = web_state_list_->GetActiveWebState(); mediator_.webState = ntp_web_state; - mediator_.NTPMetrics.webState = ntp_web_state; NewTabPageTabHelper::FromWebState(ntp_web_state)->SetShowStartSurface(true); OCMExpect([consumer_ showReturnToRecentTabTileWithConfig:[OCMArg any]]); @@ -237,13 +224,9 @@ timeLabel:@"12 hours ago"]; OCMExpect([consumer_ hideReturnToRecentTabTile]); - histogram_tester_->ExpectUniqueSample( - "IOS.ContentSuggestions.ActionOnStartSurface", - IOSContentSuggestionsActionType::kReturnToRecentTab, 0); + OCMExpect([mediator_.NTPMetricsDelegate recentTabTileOpened]); + [mediator_ openMostRecentTab]; - histogram_tester_->ExpectUniqueSample( - "IOS.ContentSuggestions.ActionOnStartSurface", - IOSContentSuggestionsActionType::kReturnToRecentTab, 1); // Verify the most recent tab was opened. EXPECT_EQ(recent_tab_index, web_state_list_->active_index()); } @@ -278,16 +261,11 @@ TEST_F(ContentSuggestionsMediatorTest, TestOpenWhatsNew) { OCMExpect([dispatcher_ showWhatsNew]); - histogram_tester_->ExpectUniqueSample( - "IOS.ContentSuggestions.ActionOnNTP", - IOSContentSuggestionsActionType::kShortcuts, 0); + OCMExpect([mediator_.NTPMetricsDelegate shortcutTileOpened]); // Action. ContentSuggestionsMostVisitedActionItem* whatsNew = WhatsNewActionItem(); [mediator_ openMostVisitedItem:whatsNew atIndex:1]; - histogram_tester_->ExpectUniqueSample( - "IOS.ContentSuggestions.ActionOnNTP", - IOSContentSuggestionsActionType::kShortcuts, 1); // Test. EXPECT_OCMOCK_VERIFY(dispatcher_); }
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_metrics_recorder.h b/ios/chrome/browser/ui/content_suggestions/content_suggestions_metrics_recorder.h index 165a132..88b8b13 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_metrics_recorder.h +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_metrics_recorder.h
@@ -9,6 +9,10 @@ #import "ios/chrome/browser/metrics/new_tab_page_uma.h" +namespace web { +class WebState; +} + typedef NS_ENUM(NSInteger, NTPCollectionShortcutType); @class ContentSuggestionsMostVisitedItem; @@ -35,9 +39,10 @@ - (void)recordMostVisitedTileShown:(ContentSuggestionsMostVisitedItem*)item atIndex:(NSInteger)index; -// Logs a most visited tile `item` being opened at `index`. +// Logs a most visited tile `item` being opened at `index` in `webState`. - (void)recordMostVisitedTileOpened:(ContentSuggestionsMostVisitedItem*)item - atIndex:(NSInteger)index; + atIndex:(NSInteger)index + webState:(web::WebState*)webState; // Logs a most visited tile being removed. - (void)recordMostVisitedTileRemoved;
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_metrics_recorder.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_metrics_recorder.mm index a851fa9..408fa58 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_metrics_recorder.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_metrics_recorder.mm
@@ -75,13 +75,17 @@ } - (void)recordMostVisitedTileOpened:(ContentSuggestionsMostVisitedItem*)item - atIndex:(NSInteger)index { + atIndex:(NSInteger)index + webState:(web::WebState*)webState { base::RecordAction(base::UserMetricsAction("MobileNTPMostVisited")); ntp_tiles::metrics::RecordTileClick(ntp_tiles::NTPTileImpression( index, item.source, item.titleSource, [self getVisualTypeFromAttributes:item.attributes], [self getIconTypeFromAttributes:item.attributes], item.URL)); + + new_tab_page_uma::RecordAction( + false, webState, new_tab_page_uma::ACTION_OPENED_MOST_VISITED_ENTRY); } - (void)recordMostVisitedTileRemoved {
diff --git a/ios/chrome/browser/ui/content_suggestions/ntp_home_metrics.h b/ios/chrome/browser/ui/content_suggestions/ntp_home_metrics.h deleted file mode 100644 index 1a394727..0000000 --- a/ios/chrome/browser/ui/content_suggestions/ntp_home_metrics.h +++ /dev/null
@@ -1,47 +0,0 @@ -// Copyright 2017 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_NTP_HOME_METRICS_H_ -#define IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_NTP_HOME_METRICS_H_ - -#import "ios/chrome/browser/ui/content_suggestions/ntp_home_constant.h" - -#import "ios/chrome/browser/metrics/new_tab_page_uma.h" - -class ChromeBrowserState; - -namespace web { -class WebState; -} -// These values are persisted to IOS.ContentSuggestions.ActionOn* histograms. -// Entries should not be renumbered and numeric values should never be reused. -enum class IOSContentSuggestionsActionType { - kMostVisitedTile = 0, - kShortcuts = 1, - kReturnToRecentTab = 2, - kFeedCard = 3, - kFakebox = 4, - kTrendingQuery = 5, - kMaxValue = kTrendingQuery, -}; - -// Metrics recorder for the action used to potentially leave the NTP. -@interface NTPHomeMetrics : NSObject - -- (instancetype)initWithBrowserState:(ChromeBrowserState*)browserState - NS_DESIGNATED_INITIALIZER; -- (instancetype)init NS_UNAVAILABLE; - -// Currently active WebState with an active NTP. -@property(nonatomic, assign) web::WebState* webState; - -- (void)recordAction:(new_tab_page_uma::ActionType)action; - -// Records a user action on a ContentSuggestions module `type`. -- (void)recordContentSuggestionsActionForType: - (IOSContentSuggestionsActionType)type; - -@end - -#endif // IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_NTP_HOME_METRICS_H_
diff --git a/ios/chrome/browser/ui/content_suggestions/ntp_home_metrics.mm b/ios/chrome/browser/ui/content_suggestions/ntp_home_metrics.mm deleted file mode 100644 index f4236e2..0000000 --- a/ios/chrome/browser/ui/content_suggestions/ntp_home_metrics.mm +++ /dev/null
@@ -1,52 +0,0 @@ -// Copyright 2017 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "ios/chrome/browser/ui/content_suggestions/ntp_home_metrics.h" - -#import "base/mac/foundation_util.h" -#import "base/metrics/histogram_macros.h" -#import "base/metrics/user_metrics.h" -#import "base/metrics/user_metrics_action.h" -#import "ios/chrome/browser/browser_state/chrome_browser_state.h" -#import "ios/chrome/browser/ntp/new_tab_page_tab_helper.h" -#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_constants.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -@interface NTPHomeMetrics () -@property(nonatomic, assign) ChromeBrowserState* browserState; -@end - -@implementation NTPHomeMetrics - -@synthesize browserState = _browserState; - -- (instancetype)initWithBrowserState:(ChromeBrowserState*)browserState { - self = [super init]; - if (self) { - _browserState = browserState; - } - return self; -} - -- (void)recordAction:(new_tab_page_uma::ActionType)action { - DCHECK(self.webState); - new_tab_page_uma::RecordAction(self.browserState->IsOffTheRecord(), - self.webState, action); -} - -- (void)recordContentSuggestionsActionForType: - (IOSContentSuggestionsActionType)type { - if (NewTabPageTabHelper::FromWebState(self.webState) - ->ShouldShowStartSurface()) { - UMA_HISTOGRAM_ENUMERATION("IOS.ContentSuggestions.ActionOnStartSurface", - type); - } else { - UMA_HISTOGRAM_ENUMERATION("IOS.ContentSuggestions.ActionOnNTP", type); - } -} - -@end
diff --git a/ios/chrome/browser/ui/infobars/modals/autofill_address_profile/infobar_edit_address_profile_table_view_controller.mm b/ios/chrome/browser/ui/infobars/modals/autofill_address_profile/infobar_edit_address_profile_table_view_controller.mm index ca8e61d..93f56cc 100644 --- a/ios/chrome/browser/ui/infobars/modals/autofill_address_profile/infobar_edit_address_profile_table_view_controller.mm +++ b/ios/chrome/browser/ui/infobars/modals/autofill_address_profile/infobar_edit_address_profile_table_view_controller.mm
@@ -57,7 +57,8 @@ self.styler.cellBackgroundColor = [UIColor colorNamed:kBackgroundColor]; self.tableView.sectionHeaderHeight = 0; self.tableView.estimatedRowHeight = 56; - self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; + [self.tableView + setSeparatorInset:UIEdgeInsetsMake(0, kTableViewHorizontalSpacing, 0, 0)]; // Configure the NavigationBar. UIBarButtonItem* cancelButton = [[UIBarButtonItem alloc]
diff --git a/ios/chrome/browser/ui/infobars/modals/autofill_address_profile/infobar_edit_address_profile_table_view_controller_unittest.mm b/ios/chrome/browser/ui/infobars/modals/autofill_address_profile/infobar_edit_address_profile_table_view_controller_unittest.mm index 7a032cc..5a555c9 100644 --- a/ios/chrome/browser/ui/infobars/modals/autofill_address_profile/infobar_edit_address_profile_table_view_controller_unittest.mm +++ b/ios/chrome/browser/ui/infobars/modals/autofill_address_profile/infobar_edit_address_profile_table_view_controller_unittest.mm
@@ -310,7 +310,7 @@ TEST_F(InfobarEditAddressProfileTableViewControllerMigrationPromptTest, TestMigrationPrompt) { NSString* expected_footer_text = l10n_util::GetNSStringF( - IDS_IOS_AUTOFILL_ADDRESS_MIGRATE_IN_ACCOUNT_FOOTER, kTestSyncingEmail); + IDS_IOS_AUTOFILL_SAVE_ADDRESS_IN_ACCOUNT_FOOTER, kTestSyncingEmail); TestModelRowsAndButtons( [controller() tableViewModel], expected_footer_text, l10n_util::GetNSString(
diff --git a/ios/chrome/browser/ui/infobars/modals/autofill_address_profile/infobar_save_address_profile_table_view_controller.mm b/ios/chrome/browser/ui/infobars/modals/autofill_address_profile/infobar_save_address_profile_table_view_controller.mm index 212347d..3cf02b5 100644 --- a/ios/chrome/browser/ui/infobars/modals/autofill_address_profile/infobar_save_address_profile_table_view_controller.mm +++ b/ios/chrome/browser/ui/infobars/modals/autofill_address_profile/infobar_save_address_profile_table_view_controller.mm
@@ -61,6 +61,9 @@ const CGFloat kSymbolSize = 16; +// Defines the separator inset value for this table view. +const CGFloat kInfobarSaveAddressProfileSeparatorInset = 54; + } // namespace @interface InfobarSaveAddressProfileTableViewController () @@ -119,7 +122,13 @@ self.styler.cellBackgroundColor = [UIColor colorNamed:kBackgroundColor]; self.tableView.sectionHeaderHeight = 0; self.tableView.sectionFooterHeight = 0; - self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; + [self.tableView + setSeparatorInset:UIEdgeInsetsMake( + 0, + self.isUpdateModal + ? kTableViewHorizontalSpacing + : kInfobarSaveAddressProfileSeparatorInset, + 0, 0)]; if (!self.isMigrationToAccount || self.currentAddressProfileSaved) { // Do not show the cancel button when the migration prompt is presented and @@ -205,6 +214,9 @@ addTarget:self action:@selector(saveAddressProfileButtonWasPressed:) forControlEvents:UIControlEventTouchUpInside]; + // Hide the separator line. + cell.separatorInset = + UIEdgeInsetsMake(0, 0, 0, self.tableView.bounds.size.width); } else if (itemType == ItemTypeAddressProfileNoThanksButton) { TableViewTextButtonCell* tableViewTextButtonCell = base::mac::ObjCCastStrict<TableViewTextButtonCell>(cell); @@ -213,6 +225,13 @@ action:@selector(noThanksButtonWasPressed:) forControlEvents:UIControlEventTouchUpInside]; } else { + if (itemType == ItemTypeFooter || + itemType == ItemTypeUpdateModalDescription || + itemType == ItemTypeUpdateModalTitle) { + // Hide the separator line. + cell.separatorInset = + UIEdgeInsetsMake(0, 0, 0, self.tableView.bounds.size.width); + } cell.selectionStyle = UITableViewCellSelectionStyleNone; } return cell; @@ -338,9 +357,6 @@ toSectionWithIdentifier:SectionIdentifierFields]; } - // Store the last added field to the modal other than the update button. - SettingsImageDetailTextItem* lastAddedItem = nil; - for (NSNumber* type in self.profileDataDiff) { if ([self.profileDataDiff[type][0] length] > 0) { SettingsImageDetailTextItem* newItem = @@ -351,7 +367,6 @@ text:self.profileDataDiff[type][0] symbol:[self symbolForAutofillInputTypeNumber:type] imageTintColorIsGrey:NO]; - lastAddedItem = newItem; [model addItem:newItem toSectionWithIdentifier:SectionIdentifierFields]; } } @@ -373,7 +388,6 @@ text:self.profileDataDiff[type][1] symbol:[self symbolForAutofillInputTypeNumber:type] imageTintColorIsGrey:YES]; - lastAddedItem = oldItem; [model addItem:oldItem toSectionWithIdentifier:SectionIdentifierFields]; } } @@ -385,9 +399,6 @@ toSectionWithIdentifier:SectionIdentifierFields]; } - // Remove the separator after the last field. - lastAddedItem.useCustomSeparator = self.profileAnAccountProfile; - [model addItem:[self saveUpdateButton] toSectionWithIdentifier:SectionIdentifierFields]; } @@ -401,15 +412,11 @@ autofillUIType:AutofillUITypeProfileHomeAddressStreet]; [model addItem:addressItem toSectionWithIdentifier:SectionIdentifierFields]; - // Store the last added field to the modal other than the save button. - SettingsImageDetailTextItem* lastAddedItem = addressItem; - if ([self.emailAddress length]) { SettingsImageDetailTextItem* emailItem = [self detailItemForSaveModalWithText:self.emailAddress autofillUIType:AutofillUITypeProfileEmailAddress]; [model addItem:emailItem toSectionWithIdentifier:SectionIdentifierFields]; - lastAddedItem = emailItem; } if ([self.phoneNumber length]) { @@ -418,7 +425,6 @@ autofillUIType: AutofillUITypeProfileHomePhoneWholeNumber]; [model addItem:phoneItem toSectionWithIdentifier:SectionIdentifierFields]; - lastAddedItem = phoneItem; } if (self.isMigrationToAccount || self.profileAnAccountProfile) { @@ -427,10 +433,6 @@ toSectionWithIdentifier:SectionIdentifierFields]; } - // Remove the separator after the last field. - lastAddedItem.useCustomSeparator = - (self.isMigrationToAccount || self.profileAnAccountProfile); - [model addItem:[self saveUpdateButton] toSectionWithIdentifier:SectionIdentifierFields]; } @@ -608,7 +610,6 @@ detailItem.alignImageWithFirstLineOfText = YES; if (symbol) { detailItem.image = symbol; - detailItem.useCustomSeparator = YES; if (imageTintColorIsGrey) { detailItem.imageViewTintColor = [UIColor colorNamed:kGrey400Color]; } else {
diff --git a/ios/chrome/browser/ui/infobars/modals/autofill_address_profile/infobar_save_address_profile_table_view_controller_unittest.mm b/ios/chrome/browser/ui/infobars/modals/autofill_address_profile/infobar_save_address_profile_table_view_controller_unittest.mm index 487c76f..4c659309 100644 --- a/ios/chrome/browser/ui/infobars/modals/autofill_address_profile/infobar_save_address_profile_table_view_controller_unittest.mm +++ b/ios/chrome/browser/ui/infobars/modals/autofill_address_profile/infobar_save_address_profile_table_view_controller_unittest.mm
@@ -198,7 +198,7 @@ EXPECT_EQ(1, NumberOfSections()); EXPECT_EQ(4, NumberOfItemsInSection(0)); CheckTextCellText( - @"This address is saved only to Chrome. To use it across Google " + @"This address is currently saved to Chrome. To use it across Google " @"products, save it in your Google Account, test@gmail.com.", 0, 0); CheckTextCellText(@"Test", 0, 1);
diff --git a/ios/chrome/browser/ui/ntp/BUILD.gn b/ios/chrome/browser/ui/ntp/BUILD.gn index 36d15a71..e88af211 100644 --- a/ios/chrome/browser/ui/ntp/BUILD.gn +++ b/ios/chrome/browser/ui/ntp/BUILD.gn
@@ -13,6 +13,7 @@ "new_tab_page_controller_delegate.h", "new_tab_page_delegate.h", "new_tab_page_follow_delegate.h", + "new_tab_page_metrics_delegate.h", "new_tab_page_omnibox_positioning.h", "new_tab_page_url_loader_delegate.h", ] @@ -285,53 +286,38 @@ ":ntp_internal", "//base", "//base/test:test_support", - "//components/bookmarks/test", - "//components/metrics", "//components/ntp_tiles", - "//components/prefs:test_support", - "//components/search_engines", - "//components/sessions", + "//components/signin/public/identity_manager", "//components/variations", - "//ios/chrome/browser/bookmarks", "//ios/chrome/browser/browser_state:test_support", "//ios/chrome/browser/favicon", + "//ios/chrome/browser/main:public", "//ios/chrome/browser/main:test_support", "//ios/chrome/browser/ntp", - "//ios/chrome/browser/search_engines", - "//ios/chrome/browser/sessions", - "//ios/chrome/browser/sessions:test_support", + "//ios/chrome/browser/search_engines:template_url_service_factory", "//ios/chrome/browser/shared/coordinator/scene:scene_state_browser_agent", "//ios/chrome/browser/shared/coordinator/scene:scene_state_header", "//ios/chrome/browser/shared/public/commands", "//ios/chrome/browser/signin", "//ios/chrome/browser/signin:test_support", - "//ios/chrome/browser/tabs", "//ios/chrome/browser/ui/content_suggestions", - "//ios/chrome/browser/ui/content_suggestions:content_suggestions_constant", "//ios/chrome/browser/ui/content_suggestions:content_suggestions_ui", - "//ios/chrome/browser/ui/content_suggestions:metrics", "//ios/chrome/browser/ui/content_suggestions/cells", - "//ios/chrome/browser/ui/favicon", - "//ios/chrome/browser/ui/ntp", "//ios/chrome/browser/ui/ntp/incognito", + "//ios/chrome/browser/ui/ntp/metrics", "//ios/chrome/browser/ui/start_surface", "//ios/chrome/browser/ui/toolbar/public", "//ios/chrome/browser/ui/toolbar/test", "//ios/chrome/browser/url:constants", "//ios/chrome/browser/url_loading", "//ios/chrome/browser/url_loading:test_support", - "//ios/chrome/browser/web_state_list:test_support", - "//ios/chrome/browser/web_state_list:web_state_list", - "//ios/chrome/common/app_group", - "//ios/chrome/common/ui/favicon", + "//ios/chrome/browser/web_state_list", "//ios/chrome/test:test_support", "//ios/testing:block_swizzler", "//ios/web/public/test", + "//ios/web/public/test/fakes", "//testing/gtest", "//third_party/ocmock", - "//ui/base", - "//ui/base:test_support", - "//url", ] }
diff --git a/ios/chrome/browser/ui/ntp/metrics/feed_metrics_constants.h b/ios/chrome/browser/ui/ntp/metrics/feed_metrics_constants.h index 94e35a2..43d1b599 100644 --- a/ios/chrome/browser/ui/ntp/metrics/feed_metrics_constants.h +++ b/ios/chrome/browser/ui/ntp/metrics/feed_metrics_constants.h
@@ -298,11 +298,6 @@ // After engaging with the Following feed. extern const char kFollowCountWhenEngaged[]; -// Histogram for an action taken on the regular NTP (not start surface). -extern const char kActionOnNTP[]; -// Histogram for an action taken on the start surface. -extern const char kActionOnStartSurface[]; - // Histogram name for last visible card when switching from Discover to // Following feed. extern const char kDiscoverIndexWhenSwitchingFeed[];
diff --git a/ios/chrome/browser/ui/ntp/metrics/feed_metrics_constants.mm b/ios/chrome/browser/ui/ntp/metrics/feed_metrics_constants.mm index 9df73cd..2eb9d73 100644 --- a/ios/chrome/browser/ui/ntp/metrics/feed_metrics_constants.mm +++ b/ios/chrome/browser/ui/ntp/metrics/feed_metrics_constants.mm
@@ -89,9 +89,6 @@ "ContentSuggestions.Feed.WebFeed.FollowCount.AfterUnfollow"; const char kFollowCountWhenEngaged[] = "ContentSuggestions.Feed.WebFeed.FollowCount.Engaged"; -const char kActionOnNTP[] = "IOS.ContentSuggestions.ActionOnNTP"; -const char kActionOnStartSurface[] = - "IOS.ContentSuggestions.ActionOnStartSurface"; const char kDiscoverIndexWhenSwitchingFeed[] = "ContentSuggestions.Feed.CardIndexOnSwitch"; const char kFollowingIndexWhenSwitchingFeed[] =
diff --git a/ios/chrome/browser/ui/ntp/metrics/feed_metrics_recorder.h b/ios/chrome/browser/ui/ntp/metrics/feed_metrics_recorder.h index 389795c6..989ef19 100644 --- a/ios/chrome/browser/ui/ntp/metrics/feed_metrics_recorder.h +++ b/ios/chrome/browser/ui/ntp/metrics/feed_metrics_recorder.h
@@ -16,6 +16,7 @@ class DiscoverFeedRefresher; @protocol FeedControlDelegate; @protocol NewTabPageFollowDelegate; +@protocol NewTabPageMetricsDelegate; namespace base { class Time; @@ -36,6 +37,9 @@ // Object that can refresh the feed. @property(nonatomic, assign) DiscoverFeedRefresher* feedRefresher; +// Delegate for reporting feed actions to the NTP metrics recorder. +@property(nonatomic, weak) id<NewTabPageMetricsDelegate> NTPMetricsDelegate; + // Records the trigger where a feed refresh is requested. + (void)recordFeedRefreshTrigger:(FeedRefreshTrigger)trigger;
diff --git a/ios/chrome/browser/ui/ntp/metrics/feed_metrics_recorder.mm b/ios/chrome/browser/ui/ntp/metrics/feed_metrics_recorder.mm index e0ae8ac..2baf10d 100644 --- a/ios/chrome/browser/ui/ntp/metrics/feed_metrics_recorder.mm +++ b/ios/chrome/browser/ui/ntp/metrics/feed_metrics_recorder.mm
@@ -12,11 +12,11 @@ #import "base/time/time.h" #import "ios/chrome/browser/discover_feed/discover_feed_refresher.h" #import "ios/chrome/browser/ntp/features.h" -#import "ios/chrome/browser/ui/content_suggestions/ntp_home_metrics.h" #import "ios/chrome/browser/ui/ntp/feed_control_delegate.h" #import "ios/chrome/browser/ui/ntp/metrics/feed_metrics_constants.h" #import "ios/chrome/browser/ui/ntp/metrics/feed_session_recorder.h" #import "ios/chrome/browser/ui/ntp/new_tab_page_follow_delegate.h" +#import "ios/chrome/browser/ui/ntp/new_tab_page_metrics_delegate.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -1283,13 +1283,7 @@ [defaults setInteger:[self.feedControlDelegate selectedFeed] forKey:kLastUsedFeedForGoodVisitsKey]; - if (self.isShownOnStartSurface) { - UMA_HISTOGRAM_ENUMERATION(kActionOnStartSurface, - IOSContentSuggestionsActionType::kFeedCard); - } else { - UMA_HISTOGRAM_ENUMERATION(kActionOnNTP, - IOSContentSuggestionsActionType::kFeedCard); - } + [self.NTPMetricsDelegate feedArticleOpened]; switch ([self.feedControlDelegate selectedFeed]) { case FeedTypeDiscover:
diff --git a/ios/chrome/browser/ui/ntp/metrics/new_tab_page_metrics_recorder.h b/ios/chrome/browser/ui/ntp/metrics/new_tab_page_metrics_recorder.h index 07489a7..ff4fe41 100644 --- a/ios/chrome/browser/ui/ntp/metrics/new_tab_page_metrics_recorder.h +++ b/ios/chrome/browser/ui/ntp/metrics/new_tab_page_metrics_recorder.h
@@ -29,6 +29,17 @@ kMaxValue = kCloseTab, }; +// These values are persisted to IOS.Home.ActionOn* histograms. +// Entries should not be renumbered and numeric values should never be reused. +enum class IOSHomeActionType { + kMostVisitedTile = 0, + kShortcuts = 1, + kReturnToRecentTab = 2, + kFeedCard = 3, + kFakebox = 4, + kMaxValue = kFakebox, +}; + // Metrics recorder for the new tab page. @interface NewTabPageMetricsRecorder : NSObject @@ -57,6 +68,10 @@ // Logs a metric for the identity disc being tapped in the NTP. - (void)recordIdentityDiscTapped; +// Logs a Home action and attributes it to the NTP or Start surface. +- (void)recordHomeActionType:(IOSHomeActionType)type + onStartSurface:(BOOL)isStartSurface; + @end #endif // IOS_CHROME_BROWSER_UI_NTP_METRICS_NEW_TAB_PAGE_METRICS_RECORDER_H_
diff --git a/ios/chrome/browser/ui/ntp/metrics/new_tab_page_metrics_recorder.mm b/ios/chrome/browser/ui/ntp/metrics/new_tab_page_metrics_recorder.mm index e4c8b028..ff8abee9 100644 --- a/ios/chrome/browser/ui/ntp/metrics/new_tab_page_metrics_recorder.mm +++ b/ios/chrome/browser/ui/ntp/metrics/new_tab_page_metrics_recorder.mm
@@ -57,6 +57,15 @@ base::RecordAction(base::UserMetricsAction("MobileNTPIdentityDiscTapped")); } +- (void)recordHomeActionType:(IOSHomeActionType)type + onStartSurface:(BOOL)isStartSurface { + if (isStartSurface) { + UMA_HISTOGRAM_ENUMERATION("IOS.Home.ActionOnStartSurface", type); + } else { + UMA_HISTOGRAM_ENUMERATION("IOS.Home.ActionOnNTP", type); + } +} + #pragma mark - Private // Records an NTP impression for the tile ablation retention feature.
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator+private.h b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator+private.h index 467316ae..eba7af6 100644 --- a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator+private.h +++ b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator+private.h
@@ -14,6 +14,7 @@ @class ContentSuggestionsCoordinator; @class NewTabPageHeaderViewController; +@class NewTabPageMetricsRecorder; @class NewTabPageViewController; // This is a private category that is intended to only be imported in @@ -36,6 +37,8 @@ @property(nonatomic, strong) NewTabPageViewController* NTPViewController; +@property(nonatomic, strong) NewTabPageMetricsRecorder* NTPMetricsRecorder; + - (void)configureNTPViewController; @end
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm index 4e88376..36e02f6 100644 --- a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm +++ b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm
@@ -67,7 +67,6 @@ #import "ios/chrome/browser/ui/authentication/enterprise/enterprise_utils.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_feature.h" -#import "ios/chrome/browser/ui/content_suggestions/ntp_home_metrics.h" #import "ios/chrome/browser/ui/context_menu/link_preview/link_preview_coordinator.h" #import "ios/chrome/browser/ui/ntp/discover_feed_constants.h" #import "ios/chrome/browser/ui/ntp/discover_feed_preview_delegate.h" @@ -94,6 +93,7 @@ #import "ios/chrome/browser/ui/ntp/new_tab_page_header_commands.h" #import "ios/chrome/browser/ui/ntp/new_tab_page_header_view_controller.h" #import "ios/chrome/browser/ui/ntp/new_tab_page_mediator.h" +#import "ios/chrome/browser/ui/ntp/new_tab_page_metrics_delegate.h" #import "ios/chrome/browser/ui/ntp/new_tab_page_view_controller.h" #import "ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.h" #import "ios/chrome/browser/ui/settings/utils/pref_backed_boolean.h" @@ -138,6 +138,7 @@ NewTabPageDelegate, NewTabPageFollowDelegate, NewTabPageHeaderCommands, + NewTabPageMetricsDelegate, OverscrollActionsControllerDelegate, PrefObserverDelegate, SceneStateObserver> { @@ -260,11 +261,6 @@ @property(nonatomic, strong) id<NewTabPageComponentFactoryProtocol> componentFactory; -// Recorder for the metrics related to the NTP. -// TODO(crbug.com/1431193): Merge this with NewTabPageMetricsRecorder and -// ContentSuggestionsMetricsRecorder. -@property(nonatomic, strong) NTPHomeMetrics* NTPMetrics; - // Recorder for new tab page metrics. @property(nonatomic, strong) NewTabPageMetricsRecorder* NTPMetricsRecorder; @@ -406,7 +402,6 @@ [self.feedTopSectionCoordinator stop]; self.feedTopSectionCoordinator = nil; - self.NTPMetrics = nil; self.NTPMetricsRecorder = nil; if (self.feedSignInPromoCoordinator) { @@ -627,9 +622,6 @@ [componentFactory contentSuggestionsCoordinatorForBrowser:browser]; self.feedMetricsRecorder = [componentFactory feedMetricsRecorderForBrowser:browser]; - self.NTPMetrics = - [[NTPHomeMetrics alloc] initWithBrowserState:browser->GetBrowserState()]; - self.NTPMetrics.webState = self.webState; self.NTPMetricsRecorder = [[NewTabPageMetricsRecorder alloc] init]; } @@ -692,9 +684,9 @@ // Configures `self.contentSuggestionsCoordiantor`. - (void)configureContentSuggestionsCoordinator { self.contentSuggestionsCoordinator.webState = self.webState; - self.contentSuggestionsCoordinator.ntpDelegate = self; + self.contentSuggestionsCoordinator.NTPDelegate = self; self.contentSuggestionsCoordinator.feedDelegate = self; - self.contentSuggestionsCoordinator.NTPMetrics = self.NTPMetrics; + self.contentSuggestionsCoordinator.NTPMetricsDelegate = self; [self.contentSuggestionsCoordinator start]; } @@ -715,6 +707,7 @@ - (void)configureFeedMetricsRecorder { self.feedMetricsRecorder.feedControlDelegate = self; self.feedMetricsRecorder.followDelegate = self; + self.feedMetricsRecorder.NTPMetricsDelegate = self; } // Configures `self.NTPViewController` and sets it up as the main ViewController @@ -799,15 +792,8 @@ } - (void)fakeboxTapped { - // TODO(crbug.com/1431193): Move these logs to the `NTPMetricsRecorder`. - if (NewTabPageTabHelper::FromWebState(self.webState) - ->ShouldShowStartSurface()) { - UMA_HISTOGRAM_ENUMERATION("IOS.ContentSuggestions.ActionOnStartSurface", - IOSContentSuggestionsActionType::kFakebox); - } else { - UMA_HISTOGRAM_ENUMERATION("IOS.ContentSuggestions.ActionOnNTP", - IOSContentSuggestionsActionType::kFakebox); - } + [self.NTPMetricsRecorder recordHomeActionType:IOSHomeActionType::kFakebox + onStartSurface:[self isStartSurface]]; [self focusFakebox]; } @@ -1194,11 +1180,11 @@ } - (BOOL)isStartSurface { - // If the NTP is in another tab, it is never a start surface. - if (!self.visible) { + // The web state is nil if the NTP is in another tab. In this case, it is + // never a start surface. + if (!self.webState) { return NO; } - CHECK(self.webState); NewTabPageTabHelper* NTPHelper = NewTabPageTabHelper::FromWebState(self.webState); return NTPHelper && NTPHelper->ShouldShowStartSurface(); @@ -1236,6 +1222,30 @@ return followBrowserAgent->GetFollowedWebSites(); } +#pragma mark - NewTabPageMetricsDelegate + +- (void)recentTabTileOpened { + [self.NTPMetricsRecorder + recordHomeActionType:IOSHomeActionType::kReturnToRecentTab + onStartSurface:[self isStartSurface]]; +} + +- (void)feedArticleOpened { + [self.NTPMetricsRecorder recordHomeActionType:IOSHomeActionType::kFeedCard + onStartSurface:[self isStartSurface]]; +} + +- (void)mostVisitedTileOpened { + [self.NTPMetricsRecorder + recordHomeActionType:IOSHomeActionType::kMostVisitedTile + onStartSurface:[self isStartSurface]]; +} + +- (void)shortcutTileOpened { + [self.NTPMetricsRecorder recordHomeActionType:IOSHomeActionType::kShortcuts + onStartSurface:[self isStartSurface]]; +} + #pragma mark - LogoAnimationControllerOwnerOwner - (id<LogoAnimationControllerOwner>)logoAnimationControllerOwner { @@ -1687,7 +1697,6 @@ _webState = webState; self.NTPMediator.webState = _webState; self.contentSuggestionsCoordinator.webState = _webState; - self.NTPMetrics.webState = _webState; } // Called when the NTP changes visibility, either when the user navigates to
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator_unittest.mm b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator_unittest.mm index f3bffc1c..9fc62f7 100644 --- a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator_unittest.mm +++ b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator_unittest.mm
@@ -23,13 +23,14 @@ #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.h" -#import "ios/chrome/browser/ui/content_suggestions/ntp_home_metrics.h" #import "ios/chrome/browser/ui/ntp/incognito/incognito_view_controller.h" +#import "ios/chrome/browser/ui/ntp/metrics/new_tab_page_metrics_recorder.h" #import "ios/chrome/browser/ui/ntp/new_tab_page_component_factory.h" #import "ios/chrome/browser/ui/ntp/new_tab_page_controller_delegate.h" #import "ios/chrome/browser/ui/ntp/new_tab_page_coordinator+private.h" #import "ios/chrome/browser/ui/ntp/new_tab_page_feature.h" #import "ios/chrome/browser/ui/ntp/new_tab_page_header_view_controller.h" +#import "ios/chrome/browser/ui/ntp/new_tab_page_metrics_delegate.h" #import "ios/chrome/browser/ui/ntp/new_tab_page_view_controller.h" #import "ios/chrome/browser/ui/start_surface/start_surface_recent_tab_browser_agent.h" #import "ios/chrome/browser/ui/toolbar/public/fakebox_focuser.h" @@ -97,6 +98,9 @@ coordinator_.baseViewController = base_view_controller_; coordinator_.toolbarDelegate = toolbar_delegate_; + NTPMetricsRecorder_ = [[NewTabPageMetricsRecorder alloc] init]; + coordinator_.NTPMetricsRecorder = NTPMetricsRecorder_; + InsertWebState(CreateWebStateWithURL(GURL("chrome://newtab"))); } @@ -194,6 +198,7 @@ std::unique_ptr<Browser> browser_; id scene_state_; NewTabPageCoordinator* coordinator_; + NewTabPageMetricsRecorder* NTPMetricsRecorder_; UIViewController* base_view_controller_; id omnibox_commands_handler_mock; id snackbar_commands_handler_mock; @@ -312,13 +317,11 @@ // SetShowStartSurface. NewTabPageTabHelper::FromWebState(web_state_)->SetShowStartSurface(true); [coordinator_ start]; - histogram_tester_->ExpectUniqueSample( - "IOS.ContentSuggestions.ActionOnStartSurface", - IOSContentSuggestionsActionType::kFakebox, 0); + histogram_tester_->ExpectUniqueSample("IOS.Home.ActionOnStartSurface", + IOSHomeActionType::kFakebox, 0); [coordinator_ fakeboxTapped]; - histogram_tester_->ExpectUniqueSample( - "IOS.ContentSuggestions.ActionOnStartSurface", - IOSContentSuggestionsActionType::kFakebox, 1); + histogram_tester_->ExpectUniqueSample("IOS.Home.ActionOnStartSurface", + IOSHomeActionType::kFakebox, 1); // Simulate navigate away and then back to non-Start NTP. web::FakeNavigationContext navigation_context; @@ -329,19 +332,15 @@ ASSERT_FALSE(coordinator_.started); SetNTPAsCurrentURL(); [coordinator_ start]; - histogram_tester_->ExpectUniqueSample( - "IOS.ContentSuggestions.ActionOnStartSurface", - IOSContentSuggestionsActionType::kFakebox, 1); - histogram_tester_->ExpectUniqueSample( - "IOS.ContentSuggestions.ActionOnNTP", - IOSContentSuggestionsActionType::kFakebox, 0); + histogram_tester_->ExpectUniqueSample("IOS.Home.ActionOnStartSurface", + IOSHomeActionType::kFakebox, 1); + histogram_tester_->ExpectUniqueSample("IOS.Home.ActionOnNTP", + IOSHomeActionType::kFakebox, 0); [coordinator_ fakeboxTapped]; - histogram_tester_->ExpectUniqueSample( - "IOS.ContentSuggestions.ActionOnStartSurface", - IOSContentSuggestionsActionType::kFakebox, 1); - histogram_tester_->ExpectUniqueSample( - "IOS.ContentSuggestions.ActionOnNTP", - IOSContentSuggestionsActionType::kFakebox, 1); + histogram_tester_->ExpectUniqueSample("IOS.Home.ActionOnStartSurface", + IOSHomeActionType::kFakebox, 1); + histogram_tester_->ExpectUniqueSample("IOS.Home.ActionOnNTP", + IOSHomeActionType::kFakebox, 1); [coordinator_ stop]; } @@ -357,9 +356,8 @@ NewTabPageTabHelper::FromWebState(web_state_)->SetShowStartSurface(true); [coordinator_ start]; - histogram_tester_->ExpectUniqueSample( - "IOS.ContentSuggestions.ActionOnStartSurface", - IOSContentSuggestionsActionType::kMostVisitedTile, 0); + histogram_tester_->ExpectUniqueSample("IOS.Home.ActionOnStartSurface", + IOSHomeActionType::kMostVisitedTile, 0); ContentSuggestionsMostVisitedItem* item = [[ContentSuggestionsMostVisitedItem alloc] init]; @@ -379,12 +377,11 @@ [coordinator_ didNavigateAwayFromNTP]; // Verify that ActionOnStartSurface metric was logged, meaning that - // NTPHomeMetrics logged the metric before NewTabPageTabHelper received the - // DidStartNavigation() WebStateObserver callback to reset + // NewTabPageMetricsRecorder logged the metric before NewTabPageTabHelper + // received the DidStartNavigation() WebStateObserver callback to reset // ShouldShowStartSurface() to false. - histogram_tester_->ExpectUniqueSample( - "IOS.ContentSuggestions.ActionOnStartSurface", - IOSContentSuggestionsActionType::kMostVisitedTile, 1); + histogram_tester_->ExpectUniqueSample("IOS.Home.ActionOnStartSurface", + IOSHomeActionType::kMostVisitedTile, 1); EXPECT_FALSE( NewTabPageTabHelper::FromWebState(web_state_)->ShouldShowStartSurface()); [coordinator_ stop];
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_header_view_controller.mm b/ios/chrome/browser/ui/ntp/new_tab_page_header_view_controller.mm index 9c00c38..bdf3722 100644 --- a/ios/chrome/browser/ui/ntp/new_tab_page_header_view_controller.mm +++ b/ios/chrome/browser/ui/ntp/new_tab_page_header_view_controller.mm
@@ -28,7 +28,6 @@ #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_commands.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_feature.h" #import "ios/chrome/browser/ui/content_suggestions/ntp_home_constant.h" -#import "ios/chrome/browser/ui/content_suggestions/ntp_home_metrics.h" #import "ios/chrome/browser/ui/lens/lens_entrypoint.h" #import "ios/chrome/browser/ui/ntp/logo_vendor.h" #import "ios/chrome/browser/ui/ntp/metrics/new_tab_page_metrics_recorder.h"
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_mediator.h b/ios/chrome/browser/ui/ntp/new_tab_page_mediator.h index baffed30..2ca2e8e 100644 --- a/ios/chrome/browser/ui/ntp/new_tab_page_mediator.h +++ b/ios/chrome/browser/ui/ntp/new_tab_page_mediator.h
@@ -25,7 +25,6 @@ @protocol LogoVendor; @protocol NewTabPageConsumer; @protocol NewTabPageHeaderConsumer; -@class NTPHomeMetrics; class TemplateURLService; class UrlLoadingBrowserAgent; @protocol UserAccountImageUpdateDelegate; @@ -47,8 +46,6 @@ - (instancetype)init NS_UNAVAILABLE; -// Recorder for the metrics related to the NTP. -@property(nonatomic, strong) NTPHomeMetrics* NTPMetrics; // Recorder for the metrics related to the feed. @property(nonatomic, strong) FeedMetricsRecorder* feedMetricsRecorder; // Mediator for the ContentSuggestions.
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_mediator_unittest.mm b/ios/chrome/browser/ui/ntp/new_tab_page_mediator_unittest.mm index 5b7c0e9..00e7070 100644 --- a/ios/chrome/browser/ui/ntp/new_tab_page_mediator_unittest.mm +++ b/ios/chrome/browser/ui/ntp/new_tab_page_mediator_unittest.mm
@@ -19,7 +19,6 @@ #import "ios/chrome/browser/signin/identity_manager_factory.h" #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_item.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.h" -#import "ios/chrome/browser/ui/content_suggestions/ntp_home_metrics.h" #import "ios/chrome/browser/ui/content_suggestions/user_account_image_update_delegate.h" #import "ios/chrome/browser/ui/ntp/logo_vendor.h" #import "ios/chrome/browser/ui/ntp/new_tab_page_consumer.h"
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_metrics_delegate.h b/ios/chrome/browser/ui/ntp/new_tab_page_metrics_delegate.h new file mode 100644 index 0000000..d2f534d --- /dev/null +++ b/ios/chrome/browser/ui/ntp/new_tab_page_metrics_delegate.h
@@ -0,0 +1,25 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_NTP_NEW_TAB_PAGE_METRICS_DELEGATE_H_ +#define IOS_CHROME_BROWSER_UI_NTP_NEW_TAB_PAGE_METRICS_DELEGATE_H_ + +// Delegate for actions to be reported back to the NTP metrics recorder. +@protocol NewTabPageMetricsDelegate + +// The recent tab tile has been tapped. +- (void)recentTabTileOpened; + +// A feed article has been tapped. +- (void)feedArticleOpened; + +// A most visited tile has been tapped. +- (void)mostVisitedTileOpened; + +// A shortcut tile has been tapped. +- (void)shortcutTileOpened; + +@end + +#endif // IOS_CHROME_BROWSER_UI_NTP_NEW_TAB_PAGE_METRICS_DELEGATE_H_
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_constants.h b/ios/chrome/browser/ui/omnibox/omnibox_constants.h index f73c145..4873a3b5 100644 --- a/ios/chrome/browser/ui/omnibox/omnibox_constants.h +++ b/ios/chrome/browser/ui/omnibox/omnibox_constants.h
@@ -16,4 +16,6 @@ extern NSString* const kOmniboxLeadingImageSuggestionImageAccessibilityIdentifier; +extern NSString* const kOmniboxAutocompleteLabelAccessibilityIdentifier; + #endif // IOS_CHROME_BROWSER_UI_OMNIBOX_OMNIBOX_CONSTANTS_H_
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_constants.mm b/ios/chrome/browser/ui/omnibox/omnibox_constants.mm index 8ba7137..5c9d0dcd 100644 --- a/ios/chrome/browser/ui/omnibox/omnibox_constants.mm +++ b/ios/chrome/browser/ui/omnibox/omnibox_constants.mm
@@ -18,3 +18,6 @@ NSString* const kOmniboxLeadingImageSuggestionImageAccessibilityIdentifier = @"OmniboxLeadingImageSuggestionImageAccessibilityIdentifier"; + +NSString* const kOmniboxAutocompleteLabelAccessibilityIdentifier = + @"OmniboxAutocompleteLabelAccessibilityIdentifier";
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_text_field_legacy.mm b/ios/chrome/browser/ui/omnibox/omnibox_text_field_legacy.mm index 6fd2312..a00913a3 100644 --- a/ios/chrome/browser/ui/omnibox/omnibox_text_field_legacy.mm +++ b/ios/chrome/browser/ui/omnibox/omnibox_text_field_legacy.mm
@@ -23,6 +23,7 @@ #import "ios/chrome/browser/shared/ui/util/reversed_animation.h" #import "ios/chrome/browser/shared/ui/util/rtl_geometry.h" #import "ios/chrome/browser/shared/ui/util/uikit_ui_util.h" +#import "ios/chrome/browser/ui/omnibox/omnibox_constants.h" #import "ios/chrome/browser/ui/omnibox/omnibox_util.h" #import "ios/chrome/browser/ui/toolbar/public/toolbar_constants.h" #import "ios/chrome/common/material_timing.h" @@ -897,6 +898,8 @@ [_selection setFont:self.currentFont]; [_selection setTextColor:_displayedTextColor]; [_selection setOpaque:NO]; + [_selection setAccessibilityIdentifier: + kOmniboxAutocompleteLabelAccessibilityIdentifier]; [_selection setBackgroundColor:UIColor.clearColor]; _selection.lineBreakMode = NSLineBreakByClipping; [self addSubview:_selection];
diff --git a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_egtest.mm b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_egtest.mm index c3fe4d2b..6c854421 100644 --- a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_egtest.mm +++ b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_egtest.mm
@@ -147,6 +147,28 @@ [ChromeEarlGrey clearBrowsingHistory]; } +// Test inline autocomplete of legacy text field implementation. +- (void)testLegacyInlineAutocompleteSuggestion { + // Skip if new text field implementation is enabled. + if (base::FeatureList::IsEnabled(kIOSNewOmniboxImplementation)) { + return; + } + [ChromeEarlGrey loadURL:_URL1]; + [ChromeEarlGrey waitForWebStateContainingText:kPage1]; + + // Clears the url and replace it with local url host. + [ChromeEarlGreyUI focusOmniboxAndType:base::SysUTF8ToNSString(_URL1.host())]; + + // We expect to have an autocomplete for URL1. + [[EarlGrey + selectElementWithMatcher:chrome_test_util::OmniboxAutocompleteLabel()] + assertWithMatcher:grey_sufficientlyVisible()]; + + // We expect to have a suggestion autocomplete. + [[EarlGrey selectElementWithMatcher:PopupRowWithUrl(_URL1)] + assertWithMatcher:grey_sufficientlyVisible()]; +} + // Tests that tapping the switch to open tab button, switch to the open tab, // doesn't close the tab. - (void)testSwitchToOpenTab {
diff --git a/ios/chrome/browser/ui/overlays/infobar_modal/infobar_modal_overlay_coordinator.mm b/ios/chrome/browser/ui/overlays/infobar_modal/infobar_modal_overlay_coordinator.mm index 09df629..4c14afa 100644 --- a/ios/chrome/browser/ui/overlays/infobar_modal/infobar_modal_overlay_coordinator.mm +++ b/ios/chrome/browser/ui/overlays/infobar_modal/infobar_modal_overlay_coordinator.mm
@@ -138,6 +138,12 @@ initWithRootViewController:self.modalViewController]; self.modalNavController.modalPresentationStyle = UIModalPresentationCustom; self.modalNavController.transitioningDelegate = self.modalTransitionDriver; + UINavigationBarAppearance* opaqueAppearance = + [[UINavigationBarAppearance alloc] init]; + [opaqueAppearance configureWithOpaqueBackground]; + self.modalNavController.navigationBar.standardAppearance = opaqueAppearance; + self.modalNavController.navigationBar.compactAppearance = opaqueAppearance; + self.modalNavController.navigationBar.scrollEdgeAppearance = opaqueAppearance; } - (void)resetModal {
diff --git a/ios/chrome/browser/ui/settings/BUILD.gn b/ios/chrome/browser/ui/settings/BUILD.gn index 846bd02cd..f780b11 100644 --- a/ios/chrome/browser/ui/settings/BUILD.gn +++ b/ios/chrome/browser/ui/settings/BUILD.gn
@@ -179,12 +179,12 @@ "//ios/chrome/browser/ui/settings/google_services", "//ios/chrome/browser/ui/settings/language:language", "//ios/chrome/browser/ui/settings/language:language_ui", + "//ios/chrome/browser/ui/settings/notifications", + "//ios/chrome/browser/ui/settings/notifications:utils", "//ios/chrome/browser/ui/settings/password", "//ios/chrome/browser/ui/settings/password/password_checkup:password_checkup_utils", "//ios/chrome/browser/ui/settings/password/password_details", "//ios/chrome/browser/ui/settings/password/password_details:password_details_ui", - "//ios/chrome/browser/ui/settings/price_notifications", - "//ios/chrome/browser/ui/settings/price_notifications:utils", "//ios/chrome/browser/ui/settings/privacy", "//ios/chrome/browser/ui/settings/privacy:privacy_ui", "//ios/chrome/browser/ui/settings/safety_check",
diff --git a/ios/chrome/browser/ui/settings/price_notifications/BUILD.gn b/ios/chrome/browser/ui/settings/notifications/BUILD.gn similarity index 76% rename from ios/chrome/browser/ui/settings/price_notifications/BUILD.gn rename to ios/chrome/browser/ui/settings/notifications/BUILD.gn index cf8d55c..9a618eb 100644 --- a/ios/chrome/browser/ui/settings/price_notifications/BUILD.gn +++ b/ios/chrome/browser/ui/settings/notifications/BUILD.gn
@@ -2,17 +2,17 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -source_set("price_notifications") { +source_set("notifications") { configs += [ "//build/config/compiler:enable_arc" ] sources = [ - "price_notifications_coordinator.h", - "price_notifications_coordinator.mm", - "price_notifications_mediator.h", - "price_notifications_mediator.mm", + "notifications_coordinator.h", + "notifications_coordinator.mm", + "notifications_mediator.h", + "notifications_mediator.mm", ] deps = [ ":constants", - ":price_notifications_ui", + ":notifications_ui", ":utils", "//base", "//components/prefs", @@ -26,20 +26,20 @@ "//ios/chrome/browser/shared/ui/table_view:utils", "//ios/chrome/browser/shared/ui/table_view/cells", "//ios/chrome/browser/signin", - "//ios/chrome/browser/ui/settings/price_notifications/tracking_price", + "//ios/chrome/browser/ui/settings/notifications/tracking_price", "//ios/chrome/common/ui/colors", "//ui/base", ] } -source_set("price_notifications_ui") { +source_set("notifications_ui") { configs += [ "//build/config/compiler:enable_arc" ] sources = [ - "price_notifications_consumer.h", - "price_notifications_navigation_commands.h", - "price_notifications_view_controller.h", - "price_notifications_view_controller.mm", - "price_notifications_view_controller_delegate.h", + "notifications_consumer.h", + "notifications_navigation_commands.h", + "notifications_view_controller.h", + "notifications_view_controller.mm", + "notifications_view_controller_delegate.h", ] deps = [ ":constants", @@ -54,8 +54,8 @@ source_set("constants") { configs += [ "//build/config/compiler:enable_arc" ] sources = [ - "price_notifications_constants.h", - "price_notifications_constants.mm", + "notifications_constants.h", + "notifications_constants.mm", ] } @@ -85,7 +85,7 @@ "//build/config/ios:xctest_config", ] testonly = true - sources = [ "price_notifications_egtest.mm" ] + sources = [ "notifications_egtest.mm" ] deps = [ ":constants", "//base",
diff --git a/ios/chrome/browser/ui/settings/notifications/notifications_constants.h b/ios/chrome/browser/ui/settings/notifications/notifications_constants.h new file mode 100644 index 0000000..faab1a5 --- /dev/null +++ b/ios/chrome/browser/ui/settings/notifications/notifications_constants.h
@@ -0,0 +1,16 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_NOTIFICATIONS_NOTIFICATIONS_CONSTANTS_H_ +#define IOS_CHROME_BROWSER_UI_SETTINGS_NOTIFICATIONS_NOTIFICATIONS_CONSTANTS_H_ + +#import <Foundation/Foundation.h> + +// The accessibility identifier of the Notifications setting table view. +extern NSString* const kNotificationsTableViewId; + +// The accessibility identifier of the Notifications price tracking cell. +extern NSString* const kSettingsNotificationsPriceTrackingCellId; + +#endif // IOS_CHROME_BROWSER_UI_SETTINGS_NOTIFICATIONS_NOTIFICATIONS_CONSTANTS_H_
diff --git a/ios/chrome/browser/ui/settings/notifications/notifications_constants.mm b/ios/chrome/browser/ui/settings/notifications/notifications_constants.mm new file mode 100644 index 0000000..9b1f08a9 --- /dev/null +++ b/ios/chrome/browser/ui/settings/notifications/notifications_constants.mm
@@ -0,0 +1,14 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/ui/settings/notifications/notifications_constants.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +NSString* const kNotificationsTableViewId = @"kNotificationsTableViewId"; + +NSString* const kSettingsNotificationsPriceTrackingCellId = + @"kSettingsNotificationsPriceTrackingCellId";
diff --git a/ios/chrome/browser/ui/settings/price_notifications/price_notifications_consumer.h b/ios/chrome/browser/ui/settings/notifications/notifications_consumer.h similarity index 61% rename from ios/chrome/browser/ui/settings/price_notifications/price_notifications_consumer.h rename to ios/chrome/browser/ui/settings/notifications/notifications_consumer.h index ecebacdf..ac67a51d 100644 --- a/ios/chrome/browser/ui/settings/price_notifications/price_notifications_consumer.h +++ b/ios/chrome/browser/ui/settings/notifications/notifications_consumer.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_PRICE_NOTIFICATIONS_PRICE_NOTIFICATIONS_CONSUMER_H_ -#define IOS_CHROME_BROWSER_UI_SETTINGS_PRICE_NOTIFICATIONS_PRICE_NOTIFICATIONS_CONSUMER_H_ +#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_NOTIFICATIONS_NOTIFICATIONS_CONSUMER_H_ +#define IOS_CHROME_BROWSER_UI_SETTINGS_NOTIFICATIONS_NOTIFICATIONS_CONSUMER_H_ #import <UIKit/UIKit.h> @@ -11,8 +11,8 @@ @class TableViewItem; -// Consumer protocol for Price Notifications settings. -@protocol PriceNotificationsConsumer <ChromeTableViewConsumer> +// Consumer protocol for Notifications settings. +@protocol NotificationsConsumer <ChromeTableViewConsumer> // Initializes price tracking item. - (void)setPriceTrackingItem:(TableViewItem*)priceTrackingItem;
diff --git a/ios/chrome/browser/ui/settings/notifications/notifications_coordinator.h b/ios/chrome/browser/ui/settings/notifications/notifications_coordinator.h new file mode 100644 index 0000000..3cbb770 --- /dev/null +++ b/ios/chrome/browser/ui/settings/notifications/notifications_coordinator.h
@@ -0,0 +1,36 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_NOTIFICATIONS_NOTIFICATIONS_COORDINATOR_H_ +#define IOS_CHROME_BROWSER_UI_SETTINGS_NOTIFICATIONS_NOTIFICATIONS_COORDINATOR_H_ + +#import "ios/chrome/browser/shared/coordinator/chrome_coordinator/chrome_coordinator.h" + +@class NotificationsCoordinator; + +// Delegate that allows to dereference the NotificationsCoordinator. +@protocol NotificationsCoordinatorDelegate + +// Called when the view controller is removed from navigation controller. +- (void)notificationsCoordinatorDidRemove: + (NotificationsCoordinator*)coordinator; + +@end + +// The coordinator for the Notifications screen. +@interface NotificationsCoordinator : ChromeCoordinator + +@property(nonatomic, weak) id<NotificationsCoordinatorDelegate> delegate; + +- (instancetype)initWithBaseViewController:(UIViewController*)viewController + browser:(Browser*)browser NS_UNAVAILABLE; + +- (instancetype)initWithBaseNavigationController: + (UINavigationController*)navigationController + browser:(Browser*)browser + NS_DESIGNATED_INITIALIZER; + +@end + +#endif // IOS_CHROME_BROWSER_UI_SETTINGS_NOTIFICATIONS_NOTIFICATIONS_COORDINATOR_H_
diff --git a/ios/chrome/browser/ui/settings/price_notifications/price_notifications_coordinator.mm b/ios/chrome/browser/ui/settings/notifications/notifications_coordinator.mm similarity index 68% rename from ios/chrome/browser/ui/settings/price_notifications/price_notifications_coordinator.mm rename to ios/chrome/browser/ui/settings/notifications/notifications_coordinator.mm index cd6202f..11377d66 100644 --- a/ios/chrome/browser/ui/settings/price_notifications/price_notifications_coordinator.mm +++ b/ios/chrome/browser/ui/settings/notifications/notifications_coordinator.mm
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "ios/chrome/browser/ui/settings/price_notifications/price_notifications_coordinator.h" +#import "ios/chrome/browser/ui/settings/notifications/notifications_coordinator.h" #import "base/check.h" #import "base/check_op.h" @@ -13,25 +13,25 @@ #import "ios/chrome/browser/shared/ui/table_view/table_view_utils.h" #import "ios/chrome/browser/signin/authentication_service.h" #import "ios/chrome/browser/signin/authentication_service_factory.h" -#import "ios/chrome/browser/ui/settings/price_notifications/notifications_settings_observer.h" -#import "ios/chrome/browser/ui/settings/price_notifications/price_notifications_mediator.h" -#import "ios/chrome/browser/ui/settings/price_notifications/price_notifications_navigation_commands.h" -#import "ios/chrome/browser/ui/settings/price_notifications/price_notifications_view_controller.h" -#import "ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_coordinator.h" +#import "ios/chrome/browser/ui/settings/notifications/notifications_mediator.h" +#import "ios/chrome/browser/ui/settings/notifications/notifications_navigation_commands.h" +#import "ios/chrome/browser/ui/settings/notifications/notifications_settings_observer.h" +#import "ios/chrome/browser/ui/settings/notifications/notifications_view_controller.h" +#import "ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_coordinator.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." #endif -@interface PriceNotificationsCoordinator () < - PriceNotificationsNavigationCommands, - PriceNotificationsViewControllerPresentationDelegate, +@interface NotificationsCoordinator () < + NotificationsNavigationCommands, + NotificationsViewControllerPresentationDelegate, TrackingPriceCoordinatorDelegate> // View controller presented by coordinator. -@property(nonatomic, strong) PriceNotificationsViewController* viewController; -// Price notifications settings mediator. -@property(nonatomic, strong) PriceNotificationsMediator* mediator; +@property(nonatomic, strong) NotificationsViewController* viewController; +// Notifications settings mediator. +@property(nonatomic, strong) NotificationsMediator* mediator; // Coordinator for Tracking Price settings menu. @property(nonatomic, strong) TrackingPriceCoordinator* trackingPriceCoordinator; // An observer that tracks whether push notification permission settings have @@ -41,7 +41,7 @@ @end -@implementation PriceNotificationsCoordinator +@implementation NotificationsCoordinator @synthesize baseNavigationController = _baseNavigationController; @@ -67,12 +67,11 @@ _notificationsObserver = [[NotificationsSettingsObserver alloc] initWithPrefService:prefService]; - self.viewController = [[PriceNotificationsViewController alloc] + self.viewController = [[NotificationsViewController alloc] initWithStyle:ChromeTableViewStyle()]; self.viewController.presentationDelegate = self; - self.mediator = - [[PriceNotificationsMediator alloc] initWithPrefService:prefService - gaiaID:gaiaID]; + self.mediator = [[NotificationsMediator alloc] initWithPrefService:prefService + gaiaID:gaiaID]; self.mediator.consumer = self.viewController; self.mediator.handler = self; _notificationsObserver.delegate = self.mediator; @@ -81,7 +80,7 @@ animated:YES]; } -#pragma mark - PriceNotificationsNavigationCommands +#pragma mark - NotificationsNavigationCommands - (void)showTrackingPrice { DCHECK(!self.trackingPriceCoordinator); @@ -93,12 +92,12 @@ [self.trackingPriceCoordinator start]; } -#pragma mark - PriceNotificationsViewControllerPresentationDelegate +#pragma mark - NotificationsViewControllerPresentationDelegate -- (void)priceNotificationsViewControllerDidRemove: - (PriceNotificationsViewController*)controller { +- (void)notificationsViewControllerDidRemove: + (NotificationsViewController*)controller { DCHECK_EQ(self.viewController, controller); - [self.delegate priceNotificationsCoordinatorDidRemove:self]; + [self.delegate notificationsCoordinatorDidRemove:self]; } #pragma mark - TrackingPriceCoordinatorDelegate
diff --git a/ios/chrome/browser/ui/settings/price_notifications/price_notifications_egtest.mm b/ios/chrome/browser/ui/settings/notifications/notifications_egtest.mm similarity index 78% rename from ios/chrome/browser/ui/settings/price_notifications/price_notifications_egtest.mm rename to ios/chrome/browser/ui/settings/notifications/notifications_egtest.mm index c02f7f9..18fd6aa 100644 --- a/ios/chrome/browser/ui/settings/price_notifications/price_notifications_egtest.mm +++ b/ios/chrome/browser/ui/settings/notifications/notifications_egtest.mm
@@ -17,14 +17,14 @@ using chrome_test_util::ButtonWithAccessibilityLabelId; using chrome_test_util::SettingsDoneButton; -using chrome_test_util::SettingsMenuPriceNotificationsButton; -using chrome_test_util::SettingsPriceNotificationsTableView; +using chrome_test_util::SettingsMenuNotificationsButton; +using chrome_test_util::SettingsNotificationsTableView; // Integration tests using the Price Notifications settings screen. -@interface PriceNotificationsTestCase : ChromeTestCase +@interface NotificationsTestCase : ChromeTestCase @end -@implementation PriceNotificationsTestCase +@implementation NotificationsTestCase - (AppLaunchConfiguration)appConfigurationForTestCase { AppLaunchConfiguration config; @@ -48,19 +48,18 @@ - (void)testPriceNotificationsSwipeDown { // Opens price notifications setting. [ChromeEarlGreyUI openSettingsMenu]; - [ChromeEarlGreyUI - tapSettingsMenuButton:SettingsMenuPriceNotificationsButton()]; + [ChromeEarlGreyUI tapSettingsMenuButton:SettingsMenuNotificationsButton()]; // Check that Price Notifications TableView is presented. - [[EarlGrey selectElementWithMatcher:SettingsPriceNotificationsTableView()] + [[EarlGrey selectElementWithMatcher:SettingsNotificationsTableView()] assertWithMatcher:grey_notNil()]; // Swipe TableView down. - [[EarlGrey selectElementWithMatcher:SettingsPriceNotificationsTableView()] + [[EarlGrey selectElementWithMatcher:SettingsNotificationsTableView()] performAction:grey_swipeFastInDirection(kGREYDirectionDown)]; // Check that Settings has been dismissed. - [[EarlGrey selectElementWithMatcher:SettingsPriceNotificationsTableView()] + [[EarlGrey selectElementWithMatcher:SettingsNotificationsTableView()] assertWithMatcher:grey_nil()]; }
diff --git a/ios/chrome/browser/ui/settings/notifications/notifications_mediator.h b/ios/chrome/browser/ui/settings/notifications/notifications_mediator.h new file mode 100644 index 0000000..486985f --- /dev/null +++ b/ios/chrome/browser/ui/settings/notifications/notifications_mediator.h
@@ -0,0 +1,39 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_NOTIFICATIONS_NOTIFICATIONS_MEDIATOR_H_ +#define IOS_CHROME_BROWSER_UI_SETTINGS_NOTIFICATIONS_NOTIFICATIONS_MEDIATOR_H_ + +#import <UIKit/UIKit.h> +#import <string> + +#import "ios/chrome/browser/ui/settings/notifications/notifications_settings_observer.h" +#import "ios/chrome/browser/ui/settings/notifications/notifications_view_controller_delegate.h" + +class PrefService; +@protocol NotificationsConsumer; +@protocol NotificationsNavigationCommands; + +// Mediator for Notifications UI. +@interface NotificationsMediator + : NSObject <NotificationsSettingsObserverDelegate, + NotificationsViewControllerDelegate> + +// Initializes the mediator with the user's pref service and gaia ID to +// manipulate their push notification permissions. +- (instancetype)initWithPrefService:(PrefService*)prefs + gaiaID:(const std::string&)gaiaID + NS_DESIGNATED_INITIALIZER; + +- (instancetype)init NS_UNAVAILABLE; + +// View controller. +@property(nonatomic, weak) id<NotificationsConsumer> consumer; + +// Handler used to navigate inside the Price Notifications setting. +@property(nonatomic, weak) id<NotificationsNavigationCommands> handler; + +@end + +#endif // IOS_CHROME_BROWSER_UI_SETTINGS_NOTIFICATIONS_NOTIFICATIONS_MEDIATOR_H_
diff --git a/ios/chrome/browser/ui/settings/price_notifications/price_notifications_mediator.mm b/ios/chrome/browser/ui/settings/notifications/notifications_mediator.mm similarity index 77% rename from ios/chrome/browser/ui/settings/price_notifications/price_notifications_mediator.mm rename to ios/chrome/browser/ui/settings/notifications/notifications_mediator.mm index 1db60427..bca002f 100644 --- a/ios/chrome/browser/ui/settings/price_notifications/price_notifications_mediator.mm +++ b/ios/chrome/browser/ui/settings/notifications/notifications_mediator.mm
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "ios/chrome/browser/ui/settings/price_notifications/price_notifications_mediator.h" +#import "ios/chrome/browser/ui/settings/notifications/notifications_mediator.h" #import "base/mac/foundation_util.h" #import "base/notreached.h" @@ -11,11 +11,11 @@ #import "ios/chrome/browser/shared/ui/list_model/list_model.h" #import "ios/chrome/browser/shared/ui/symbols/symbols.h" #import "ios/chrome/browser/shared/ui/table_view/cells/table_view_detail_icon_item.h" -#import "ios/chrome/browser/ui/settings/price_notifications/notifications_settings_observer.h" -#import "ios/chrome/browser/ui/settings/price_notifications/notifications_settings_util.h" -#import "ios/chrome/browser/ui/settings/price_notifications/price_notifications_constants.h" -#import "ios/chrome/browser/ui/settings/price_notifications/price_notifications_consumer.h" -#import "ios/chrome/browser/ui/settings/price_notifications/price_notifications_navigation_commands.h" +#import "ios/chrome/browser/ui/settings/notifications/notifications_constants.h" +#import "ios/chrome/browser/ui/settings/notifications/notifications_consumer.h" +#import "ios/chrome/browser/ui/settings/notifications/notifications_navigation_commands.h" +#import "ios/chrome/browser/ui/settings/notifications/notifications_settings_observer.h" +#import "ios/chrome/browser/ui/settings/notifications/notifications_settings_util.h" #import "ios/chrome/common/ui/colors/semantic_color_names.h" #import "ios/chrome/grit/ios_strings.h" #import "ui/base/l10n/l10n_util.h" @@ -29,7 +29,7 @@ ItemTypeTrackingPrice = kItemTypeEnumZero, }; -@interface PriceNotificationsMediator () +@interface NotificationsMediator () // All the items for the price notifications section. @property(nonatomic, strong, readonly) TableViewItem* priceTrackingItem; @@ -39,7 +39,7 @@ @end -@implementation PriceNotificationsMediator { +@implementation NotificationsMediator { // Identity object that contains the user's account details. std::string _gaiaID; } @@ -70,15 +70,17 @@ detailText:nil symbol:kDownTrendSymbol symbolBackgroundColor:[UIColor colorNamed:kPink500Color] - accessibilityIdentifier:kSettingsPriceNotificationsPriceTrackingCellId]; - [self updatePriceTrackingDetailText]; + accessibilityIdentifier:kSettingsNotificationsPriceTrackingCellId]; + [self updateDetailTextForItem:_priceTrackingItem + withClientID:PushNotificationClientId::kCommerce]; } return _priceTrackingItem; } -- (void)setConsumer:(id<PriceNotificationsConsumer>)consumer { - if (_consumer == consumer) +- (void)setConsumer:(id<NotificationsConsumer>)consumer { + if (_consumer == consumer) { return; + } _consumer = consumer; [_consumer setPriceTrackingItem:self.priceTrackingItem]; } @@ -112,13 +114,14 @@ // PriceNotificationsTableViewController on the previous screen to read either // 'On/Off' to match the change to the client's push notification permission // state. -- (void)updatePriceTrackingDetailText { - DCHECK(_priceTrackingItem); +- (void)updateDetailTextForItem:(TableViewItem*)item + withClientID:(PushNotificationClientId)clientID { + DCHECK(item); TableViewDetailIconItem* iconItem = - base::mac::ObjCCastStrict<TableViewDetailIconItem>(_priceTrackingItem); + base::mac::ObjCCastStrict<TableViewDetailIconItem>(item); notifications_settings::ClientPermissionState permissionState = - notifications_settings::GetClientPermissionState( - PushNotificationClientId::kCommerce, _gaiaID, _prefService); + notifications_settings::GetClientPermissionState(clientID, _gaiaID, + _prefService); NSString* detailText = nil; if (permissionState == notifications_settings::ClientPermissionState::ENABLED) { @@ -152,7 +155,7 @@ (PushNotificationClientId)clientID { switch (clientID) { case PushNotificationClientId::kCommerce: { - [self updatePriceTrackingDetailText]; + [self updateDetailTextForItem:_priceTrackingItem withClientID:clientID]; break; } }
diff --git a/ios/chrome/browser/ui/settings/notifications/notifications_navigation_commands.h b/ios/chrome/browser/ui/settings/notifications/notifications_navigation_commands.h new file mode 100644 index 0000000..ca4ed64b9 --- /dev/null +++ b/ios/chrome/browser/ui/settings/notifications/notifications_navigation_commands.h
@@ -0,0 +1,17 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_NOTIFICATIONS_NOTIFICATIONS_NAVIGATION_COMMANDS_H_ +#define IOS_CHROME_BROWSER_UI_SETTINGS_NOTIFICATIONS_NOTIFICATIONS_NAVIGATION_COMMANDS_H_ + +// Protocol for navigating to different setting pages from Notifications +// setting. +@protocol NotificationsNavigationCommands <NSObject> + +// Shows tracking price screen. +- (void)showTrackingPrice; + +@end + +#endif // IOS_CHROME_BROWSER_UI_SETTINGS_NOTIFICATIONS_NOTIFICATIONS_NAVIGATION_COMMANDS_H_
diff --git a/ios/chrome/browser/ui/settings/price_notifications/notifications_settings_observer.h b/ios/chrome/browser/ui/settings/notifications/notifications_settings_observer.h similarity index 78% rename from ios/chrome/browser/ui/settings/price_notifications/notifications_settings_observer.h rename to ios/chrome/browser/ui/settings/notifications/notifications_settings_observer.h index a3aa06a..10e1cf6 100644 --- a/ios/chrome/browser/ui/settings/price_notifications/notifications_settings_observer.h +++ b/ios/chrome/browser/ui/settings/notifications/notifications_settings_observer.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_PRICE_NOTIFICATIONS_NOTIFICATIONS_SETTINGS_OBSERVER_H_ -#define IOS_CHROME_BROWSER_UI_SETTINGS_PRICE_NOTIFICATIONS_NOTIFICATIONS_SETTINGS_OBSERVER_H_ +#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_NOTIFICATIONS_NOTIFICATIONS_SETTINGS_OBSERVER_H_ +#define IOS_CHROME_BROWSER_UI_SETTINGS_NOTIFICATIONS_NOTIFICATIONS_SETTINGS_OBSERVER_H_ #import "components/prefs/ios/pref_observer_bridge.h" @@ -34,4 +34,4 @@ @end -#endif // IOS_CHROME_BROWSER_UI_SETTINGS_PRICE_NOTIFICATIONS_NOTIFICATIONS_SETTINGS_OBSERVER_H_ +#endif // IOS_CHROME_BROWSER_UI_SETTINGS_NOTIFICATIONS_NOTIFICATIONS_SETTINGS_OBSERVER_H_
diff --git a/ios/chrome/browser/ui/settings/price_notifications/notifications_settings_observer.mm b/ios/chrome/browser/ui/settings/notifications/notifications_settings_observer.mm similarity index 94% rename from ios/chrome/browser/ui/settings/price_notifications/notifications_settings_observer.mm rename to ios/chrome/browser/ui/settings/notifications/notifications_settings_observer.mm index 7c042f4..f2e3d25 100644 --- a/ios/chrome/browser/ui/settings/price_notifications/notifications_settings_observer.mm +++ b/ios/chrome/browser/ui/settings/notifications/notifications_settings_observer.mm
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "ios/chrome/browser/ui/settings/price_notifications/notifications_settings_observer.h" +#import "ios/chrome/browser/ui/settings/notifications/notifications_settings_observer.h" #import <memory>
diff --git a/ios/chrome/browser/ui/settings/price_notifications/notifications_settings_util.h b/ios/chrome/browser/ui/settings/notifications/notifications_settings_util.h similarity index 85% rename from ios/chrome/browser/ui/settings/price_notifications/notifications_settings_util.h rename to ios/chrome/browser/ui/settings/notifications/notifications_settings_util.h index 6dc22a71..d742742 100644 --- a/ios/chrome/browser/ui/settings/price_notifications/notifications_settings_util.h +++ b/ios/chrome/browser/ui/settings/notifications/notifications_settings_util.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_PRICE_NOTIFICATIONS_NOTIFICATIONS_SETTINGS_UTIL_H_ -#define IOS_CHROME_BROWSER_UI_SETTINGS_PRICE_NOTIFICATIONS_NOTIFICATIONS_SETTINGS_UTIL_H_ +#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_NOTIFICATIONS_NOTIFICATIONS_SETTINGS_UTIL_H_ +#define IOS_CHROME_BROWSER_UI_SETTINGS_NOTIFICATIONS_NOTIFICATIONS_SETTINGS_UTIL_H_ #import <Foundation/Foundation.h> #import <string> @@ -43,4 +43,4 @@ } // namespace notifications_settings -#endif // IOS_CHROME_BROWSER_UI_SETTINGS_PRICE_NOTIFICATIONS_NOTIFICATIONS_SETTINGS_UTIL_H_ +#endif // IOS_CHROME_BROWSER_UI_SETTINGS_NOTIFICATIONS_NOTIFICATIONS_SETTINGS_UTIL_H_
diff --git a/ios/chrome/browser/ui/settings/price_notifications/notifications_settings_util.mm b/ios/chrome/browser/ui/settings/notifications/notifications_settings_util.mm similarity index 96% rename from ios/chrome/browser/ui/settings/price_notifications/notifications_settings_util.mm rename to ios/chrome/browser/ui/settings/notifications/notifications_settings_util.mm index 8fe20aa..cfe890ad 100644 --- a/ios/chrome/browser/ui/settings/price_notifications/notifications_settings_util.mm +++ b/ios/chrome/browser/ui/settings/notifications/notifications_settings_util.mm
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "ios/chrome/browser/ui/settings/price_notifications/notifications_settings_util.h" +#import "ios/chrome/browser/ui/settings/notifications/notifications_settings_util.h" #import "components/commerce/core/pref_names.h" #import "components/prefs/pref_service.h"
diff --git a/ios/chrome/browser/ui/settings/notifications/notifications_view_controller.h b/ios/chrome/browser/ui/settings/notifications/notifications_view_controller.h new file mode 100644 index 0000000..10fda0e --- /dev/null +++ b/ios/chrome/browser/ui/settings/notifications/notifications_view_controller.h
@@ -0,0 +1,42 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_NOTIFICATIONS_NOTIFICATIONS_VIEW_CONTROLLER_H_ +#define IOS_CHROME_BROWSER_UI_SETTINGS_NOTIFICATIONS_NOTIFICATIONS_VIEW_CONTROLLER_H_ + +#import "ios/chrome/browser/ui/settings/settings_root_table_view_controller.h" + +#import "ios/chrome/browser/ui/settings/notifications/notifications_consumer.h" +#import "ios/chrome/browser/ui/settings/settings_controller_protocol.h" + +@class NotificationsViewController; +@protocol NotificationsNavigationCommands; +@protocol NotificationsViewControllerDelegate; + +// Delegate for presentation events related to +// NotificationsViewController. +@protocol NotificationsViewControllerPresentationDelegate + +// Called when the view controller is removed from its parent. +- (void)notificationsViewControllerDidRemove: + (NotificationsViewController*)controller; + +@end + +// View controller for Notifications setting. +@interface NotificationsViewController + : SettingsRootTableViewController <NotificationsConsumer, + SettingsControllerProtocol> + +// Presentation delegate. +@property(nonatomic, weak) id<NotificationsViewControllerPresentationDelegate> + presentationDelegate; + +// Delegate for view controller to send responses to model. +@property(nonatomic, weak) id<NotificationsViewControllerDelegate> + modelDelegate; + +@end + +#endif // IOS_CHROME_BROWSER_UI_SETTINGS_NOTIFICATIONS_NOTIFICATIONS_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/settings/price_notifications/price_notifications_view_controller.mm b/ios/chrome/browser/ui/settings/notifications/notifications_view_controller.mm similarity index 66% rename from ios/chrome/browser/ui/settings/price_notifications/price_notifications_view_controller.mm rename to ios/chrome/browser/ui/settings/notifications/notifications_view_controller.mm index ee9180e..c28a585 100644 --- a/ios/chrome/browser/ui/settings/price_notifications/price_notifications_view_controller.mm +++ b/ios/chrome/browser/ui/settings/notifications/notifications_view_controller.mm
@@ -2,13 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "ios/chrome/browser/ui/settings/price_notifications/price_notifications_view_controller.h" +#import "ios/chrome/browser/ui/settings/notifications/notifications_view_controller.h" #import "base/metrics/user_metrics.h" #import "base/metrics/user_metrics_action.h" #import "ios/chrome/browser/shared/ui/table_view/table_view_utils.h" -#import "ios/chrome/browser/ui/settings/price_notifications/price_notifications_constants.h" -#import "ios/chrome/browser/ui/settings/price_notifications/price_notifications_view_controller_delegate.h" +#import "ios/chrome/browser/ui/settings/notifications/notifications_constants.h" +#import "ios/chrome/browser/ui/settings/notifications/notifications_view_controller_delegate.h" #import "ios/chrome/grit/ios_strings.h" #import "ui/base/l10n/l10n_util.h" @@ -19,24 +19,24 @@ namespace { typedef NS_ENUM(NSInteger, SectionIdentifier) { - SectionIdentifierPriceNotificationsContent = kSectionIdentifierEnumZero, + SectionIdentifierNotificationsContent = kSectionIdentifierEnumZero, }; } // namespace -@interface PriceNotificationsViewController () +@interface NotificationsViewController () // All the items for the price notifications section received by mediator. @property(nonatomic, strong) TableViewItem* priceTrackingItem; @end -@implementation PriceNotificationsViewController +@implementation NotificationsViewController - (void)viewDidLoad { [super viewDidLoad]; - self.title = l10n_util::GetNSString(IDS_IOS_PRICE_NOTIFICATIONS_TITLE); - self.tableView.accessibilityIdentifier = kPriceNotificationsTableViewId; + self.title = l10n_util::GetNSString(IDS_IOS_NOTIFICATIONS_TITLE); + self.tableView.accessibilityIdentifier = kNotificationsTableViewId; [self loadModel]; } @@ -58,9 +58,9 @@ [super loadModel]; TableViewModel* model = self.tableViewModel; - [model addSectionWithIdentifier:SectionIdentifierPriceNotificationsContent]; + [model addSectionWithIdentifier:SectionIdentifierNotificationsContent]; [model addItem:self.priceTrackingItem - toSectionWithIdentifier:SectionIdentifierPriceNotificationsContent]; + toSectionWithIdentifier:SectionIdentifierNotificationsContent]; } #pragma mark - UIViewController @@ -68,7 +68,7 @@ - (void)didMoveToParentViewController:(UIViewController*)parent { [super didMoveToParentViewController:parent]; if (!parent) { - [self.presentationDelegate priceNotificationsViewControllerDidRemove:self]; + [self.presentationDelegate notificationsViewControllerDidRemove:self]; } }
diff --git a/ios/chrome/browser/ui/settings/notifications/notifications_view_controller_delegate.h b/ios/chrome/browser/ui/settings/notifications/notifications_view_controller_delegate.h new file mode 100644 index 0000000..9e7e441a --- /dev/null +++ b/ios/chrome/browser/ui/settings/notifications/notifications_view_controller_delegate.h
@@ -0,0 +1,19 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_NOTIFICATIONS_NOTIFICATIONS_VIEW_CONTROLLER_DELEGATE_H_ +#define IOS_CHROME_BROWSER_UI_SETTINGS_NOTIFICATIONS_NOTIFICATIONS_VIEW_CONTROLLER_DELEGATE_H_ + +@class TableViewItem; + +// Delegate for NotificationsViewController instance to manage the +// model. +@protocol NotificationsViewControllerDelegate <NSObject> + +// Sends `item` to the model to handle logic and navigation. +- (void)didSelectItem:(TableViewItem*)item; + +@end + +#endif // IOS_CHROME_BROWSER_UI_SETTINGS_NOTIFICATIONS_NOTIFICATIONS_VIEW_CONTROLLER_DELEGATE_H_
diff --git a/ios/chrome/browser/ui/settings/price_notifications/tracking_price/BUILD.gn b/ios/chrome/browser/ui/settings/notifications/tracking_price/BUILD.gn similarity index 97% rename from ios/chrome/browser/ui/settings/price_notifications/tracking_price/BUILD.gn rename to ios/chrome/browser/ui/settings/notifications/tracking_price/BUILD.gn index 8c79ef9..b2e7ddba 100644 --- a/ios/chrome/browser/ui/settings/price_notifications/tracking_price/BUILD.gn +++ b/ios/chrome/browser/ui/settings/notifications/tracking_price/BUILD.gn
@@ -31,7 +31,7 @@ "//ios/chrome/browser/shared/ui/table_view:utils", "//ios/chrome/browser/shared/ui/table_view/cells", "//ios/chrome/browser/signin", - "//ios/chrome/browser/ui/settings/price_notifications:utils", + "//ios/chrome/browser/ui/settings/notifications:utils", "//ui/base", ] }
diff --git a/ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_alert_presenter.h b/ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_alert_presenter.h similarity index 63% rename from ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_alert_presenter.h rename to ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_alert_presenter.h index 8ddf0748..496fec4c 100644 --- a/ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_alert_presenter.h +++ b/ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_alert_presenter.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_PRICE_NOTIFICATIONS_TRACKING_PRICE_TRACKING_PRICE_ALERT_PRESENTER_H_ -#define IOS_CHROME_BROWSER_UI_SETTINGS_PRICE_NOTIFICATIONS_TRACKING_PRICE_TRACKING_PRICE_ALERT_PRESENTER_H_ +#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_NOTIFICATIONS_TRACKING_PRICE_TRACKING_PRICE_ALERT_PRESENTER_H_ +#define IOS_CHROME_BROWSER_UI_SETTINGS_NOTIFICATIONS_TRACKING_PRICE_TRACKING_PRICE_ALERT_PRESENTER_H_ @class PriceNotificationsTableViewItem; @@ -17,4 +17,4 @@ @end -#endif // IOS_CHROME_BROWSER_UI_SETTINGS_PRICE_NOTIFICATIONS_TRACKING_PRICE_TRACKING_PRICE_ALERT_PRESENTER_H_ +#endif // IOS_CHROME_BROWSER_UI_SETTINGS_NOTIFICATIONS_TRACKING_PRICE_TRACKING_PRICE_ALERT_PRESENTER_H_
diff --git a/ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_constants.h b/ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_constants.h similarity index 66% rename from ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_constants.h rename to ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_constants.h index 0754ecf..c2e241e 100644 --- a/ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_constants.h +++ b/ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_constants.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_PRICE_NOTIFICATIONS_TRACKING_PRICE_TRACKING_PRICE_CONSTANTS_H_ -#define IOS_CHROME_BROWSER_UI_SETTINGS_PRICE_NOTIFICATIONS_TRACKING_PRICE_TRACKING_PRICE_CONSTANTS_H_ +#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_NOTIFICATIONS_TRACKING_PRICE_TRACKING_PRICE_CONSTANTS_H_ +#define IOS_CHROME_BROWSER_UI_SETTINGS_NOTIFICATIONS_TRACKING_PRICE_TRACKING_PRICE_CONSTANTS_H_ #import <Foundation/Foundation.h> @@ -16,4 +16,4 @@ // The accessibility identifier of the Tracking Price email notifications cell. extern NSString* const kSettingsTrackingPriceEmailNotificationsCellId; -#endif // IOS_CHROME_BROWSER_UI_SETTINGS_PRICE_NOTIFICATIONS_TRACKING_PRICE_TRACKING_PRICE_CONSTANTS_H_ +#endif // IOS_CHROME_BROWSER_UI_SETTINGS_NOTIFICATIONS_TRACKING_PRICE_TRACKING_PRICE_CONSTANTS_H_
diff --git a/ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_constants.mm b/ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_constants.mm similarity index 84% rename from ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_constants.mm rename to ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_constants.mm index d496fc639..8a9a51e 100644 --- a/ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_constants.mm +++ b/ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_constants.mm
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_constants.h" +#import "ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_constants.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support."
diff --git a/ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_consumer.h b/ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_consumer.h similarity index 71% rename from ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_consumer.h rename to ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_consumer.h index 7578f48..9b6b3a867 100644 --- a/ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_consumer.h +++ b/ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_consumer.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_PRICE_NOTIFICATIONS_TRACKING_PRICE_TRACKING_PRICE_CONSUMER_H_ -#define IOS_CHROME_BROWSER_UI_SETTINGS_PRICE_NOTIFICATIONS_TRACKING_PRICE_TRACKING_PRICE_CONSUMER_H_ +#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_NOTIFICATIONS_TRACKING_PRICE_TRACKING_PRICE_CONSUMER_H_ +#define IOS_CHROME_BROWSER_UI_SETTINGS_NOTIFICATIONS_TRACKING_PRICE_TRACKING_PRICE_CONSUMER_H_ #import <UIKit/UIKit.h> @@ -27,4 +27,4 @@ @end -#endif // IOS_CHROME_BROWSER_UI_SETTINGS_PRICE_NOTIFICATIONS_TRACKING_PRICE_TRACKING_PRICE_CONSUMER_H_ +#endif // IOS_CHROME_BROWSER_UI_SETTINGS_NOTIFICATIONS_TRACKING_PRICE_TRACKING_PRICE_CONSUMER_H_
diff --git a/ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_coordinator.h b/ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_coordinator.h similarity index 72% rename from ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_coordinator.h rename to ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_coordinator.h index 1292c8f..7458fab 100644 --- a/ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_coordinator.h +++ b/ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_coordinator.h
@@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_PRICE_NOTIFICATIONS_TRACKING_PRICE_TRACKING_PRICE_COORDINATOR_H_ -#define IOS_CHROME_BROWSER_UI_SETTINGS_PRICE_NOTIFICATIONS_TRACKING_PRICE_TRACKING_PRICE_COORDINATOR_H_ +#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_NOTIFICATIONS_TRACKING_PRICE_TRACKING_PRICE_COORDINATOR_H_ +#define IOS_CHROME_BROWSER_UI_SETTINGS_NOTIFICATIONS_TRACKING_PRICE_TRACKING_PRICE_COORDINATOR_H_ #import "ios/chrome/browser/shared/coordinator/chrome_coordinator/chrome_coordinator.h" -#import "ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_alert_presenter.h" +#import "ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_alert_presenter.h" @class TrackingPriceCoordinator; @@ -35,4 +35,4 @@ @end -#endif // IOS_CHROME_BROWSER_UI_SETTINGS_PRICE_NOTIFICATIONS_TRACKING_PRICE_TRACKING_PRICE_COORDINATOR_H_ +#endif // IOS_CHROME_BROWSER_UI_SETTINGS_NOTIFICATIONS_TRACKING_PRICE_TRACKING_PRICE_COORDINATOR_H_
diff --git a/ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_coordinator.mm b/ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_coordinator.mm similarity index 93% rename from ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_coordinator.mm rename to ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_coordinator.mm index bcede49..3530778 100644 --- a/ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_coordinator.mm +++ b/ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_coordinator.mm
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_coordinator.h" +#import "ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_coordinator.h" #import "base/check.h" #import "base/check_op.h" @@ -15,8 +15,8 @@ #import "ios/chrome/browser/shared/ui/table_view/table_view_utils.h" #import "ios/chrome/browser/signin/authentication_service.h" #import "ios/chrome/browser/signin/authentication_service_factory.h" -#import "ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_mediator.h" -#import "ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_view_controller.h" +#import "ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_mediator.h" +#import "ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_view_controller.h" #import "ios/chrome/grit/ios_strings.h" #import "ui/base/l10n/l10n_util_mac.h"
diff --git a/ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_egtest.mm b/ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_egtest.mm similarity index 94% rename from ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_egtest.mm rename to ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_egtest.mm index 053a2acc..158c730 100644 --- a/ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_egtest.mm +++ b/ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_egtest.mm
@@ -17,7 +17,7 @@ using chrome_test_util::ButtonWithAccessibilityLabelId; using chrome_test_util::SettingsDoneButton; -using chrome_test_util::SettingsMenuPriceNotificationsButton; +using chrome_test_util::SettingsMenuNotificationsButton; using chrome_test_util::SettingsTrackingPriceTableView; // Integration tests using the Tracking Price settings screen. @@ -66,8 +66,7 @@ // Opens tracking price settings from price notifications setting page. - (void)openTrackingPriceSettings { [ChromeEarlGreyUI openSettingsMenu]; - [ChromeEarlGreyUI - tapSettingsMenuButton:SettingsMenuPriceNotificationsButton()]; + [ChromeEarlGreyUI tapSettingsMenuButton:SettingsMenuNotificationsButton()]; [ChromeEarlGreyUI tapPriceNotificationsMenuButton: ButtonWithAccessibilityLabelId( IDS_IOS_PRICE_NOTIFICATIONS_PRICE_TRACKING_TITLE)];
diff --git a/ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_mediator.h b/ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_mediator.h similarity index 74% rename from ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_mediator.h rename to ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_mediator.h index 6e77b0ba..fbefe93b 100644 --- a/ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_mediator.h +++ b/ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_mediator.h
@@ -2,13 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_PRICE_NOTIFICATIONS_TRACKING_PRICE_TRACKING_PRICE_MEDIATOR_H_ -#define IOS_CHROME_BROWSER_UI_SETTINGS_PRICE_NOTIFICATIONS_TRACKING_PRICE_TRACKING_PRICE_MEDIATOR_H_ +#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_NOTIFICATIONS_TRACKING_PRICE_TRACKING_PRICE_MEDIATOR_H_ +#define IOS_CHROME_BROWSER_UI_SETTINGS_NOTIFICATIONS_TRACKING_PRICE_TRACKING_PRICE_MEDIATOR_H_ #import <UIKit/UIKit.h> #import "base/memory/weak_ptr.h" -#import "ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_view_controller_delegate.h" +#import "ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_view_controller_delegate.h" class AuthenticationService; class PrefService; @@ -45,4 +45,4 @@ @end -#endif // IOS_CHROME_BROWSER_UI_SETTINGS_PRICE_NOTIFICATIONS_TRACKING_PRICE_TRACKING_PRICE_MEDIATOR_H_ +#endif // IOS_CHROME_BROWSER_UI_SETTINGS_NOTIFICATIONS_TRACKING_PRICE_TRACKING_PRICE_MEDIATOR_H_
diff --git a/ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_mediator.mm b/ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_mediator.mm similarity index 92% rename from ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_mediator.mm rename to ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_mediator.mm index 86bd0940..a745dbf9 100644 --- a/ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_mediator.mm +++ b/ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_mediator.mm
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_mediator.h" +#import "ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_mediator.h" #import "base/mac/foundation_util.h" #import "base/notreached.h" @@ -23,10 +23,10 @@ #import "ios/chrome/browser/shared/ui/table_view/cells/table_view_link_header_footer_item.h" #import "ios/chrome/browser/shared/ui/table_view/cells/table_view_switch_item.h" #import "ios/chrome/browser/signin/authentication_service.h" -#import "ios/chrome/browser/ui/settings/price_notifications/notifications_settings_util.h" -#import "ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_alert_presenter.h" -#import "ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_constants.h" -#import "ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_consumer.h" +#import "ios/chrome/browser/ui/settings/notifications/notifications_settings_util.h" +#import "ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_alert_presenter.h" +#import "ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_constants.h" +#import "ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_consumer.h" #import "ios/chrome/grit/ios_strings.h" #import "ui/base/l10n/l10n_util.h" @@ -133,8 +133,9 @@ } - (void)setConsumer:(id<TrackingPriceConsumer>)consumer { - if (_consumer == consumer) + if (_consumer == consumer) { return; + } _consumer = consumer; [_consumer setMobileNotificationItem:self.mobileNotificationItem]; [_consumer setEmailNotificationItem:self.emailNotificationItem];
diff --git a/ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_view_controller.h b/ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_view_controller.h similarity index 73% rename from ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_view_controller.h rename to ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_view_controller.h index 45524e8..dca8cc99 100644 --- a/ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_view_controller.h +++ b/ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_view_controller.h
@@ -2,12 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_PRICE_NOTIFICATIONS_TRACKING_PRICE_TRACKING_PRICE_VIEW_CONTROLLER_H_ -#define IOS_CHROME_BROWSER_UI_SETTINGS_PRICE_NOTIFICATIONS_TRACKING_PRICE_TRACKING_PRICE_VIEW_CONTROLLER_H_ +#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_NOTIFICATIONS_TRACKING_PRICE_TRACKING_PRICE_VIEW_CONTROLLER_H_ +#define IOS_CHROME_BROWSER_UI_SETTINGS_NOTIFICATIONS_TRACKING_PRICE_TRACKING_PRICE_VIEW_CONTROLLER_H_ #import "ios/chrome/browser/ui/settings/settings_root_table_view_controller.h" -#import "ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_consumer.h" +#import "ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_consumer.h" #import "ios/chrome/browser/ui/settings/settings_controller_protocol.h" @class TrackingPriceViewController; @@ -38,4 +38,4 @@ @end -#endif // IOS_CHROME_BROWSER_UI_SETTINGS_PRICE_NOTIFICATIONS_TRACKING_PRICE_TRACKING_PRICE_VIEW_CONTROLLER_H_ +#endif // IOS_CHROME_BROWSER_UI_SETTINGS_NOTIFICATIONS_TRACKING_PRICE_TRACKING_PRICE_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_view_controller.mm b/ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_view_controller.mm similarity index 92% rename from ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_view_controller.mm rename to ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_view_controller.mm index e7072c9a..f9a21f5 100644 --- a/ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_view_controller.mm +++ b/ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_view_controller.mm
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_view_controller.h" +#import "ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_view_controller.h" #import "base/check.h" #import "base/mac/foundation_util.h" @@ -11,8 +11,8 @@ #import "ios/chrome/browser/shared/ui/table_view/cells/table_view_switch_cell.h" #import "ios/chrome/browser/shared/ui/table_view/cells/table_view_text_header_footer_item.h" #import "ios/chrome/browser/shared/ui/table_view/table_view_utils.h" -#import "ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_constants.h" -#import "ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_view_controller_delegate.h" +#import "ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_constants.h" +#import "ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_view_controller_delegate.h" #import "ios/chrome/grit/ios_strings.h" #import "ui/base/l10n/l10n_util.h"
diff --git a/ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_view_controller_delegate.h b/ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_view_controller_delegate.h similarity index 70% rename from ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_view_controller_delegate.h rename to ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_view_controller_delegate.h index 55b7206..5114909 100644 --- a/ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_view_controller_delegate.h +++ b/ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_view_controller_delegate.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_PRICE_NOTIFICATIONS_TRACKING_PRICE_TRACKING_PRICE_VIEW_CONTROLLER_DELEGATE_H_ -#define IOS_CHROME_BROWSER_UI_SETTINGS_PRICE_NOTIFICATIONS_TRACKING_PRICE_TRACKING_PRICE_VIEW_CONTROLLER_DELEGATE_H_ +#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_NOTIFICATIONS_TRACKING_PRICE_TRACKING_PRICE_VIEW_CONTROLLER_DELEGATE_H_ +#define IOS_CHROME_BROWSER_UI_SETTINGS_NOTIFICATIONS_TRACKING_PRICE_TRACKING_PRICE_VIEW_CONTROLLER_DELEGATE_H_ @class TableViewItem;
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator.mm b/ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator.mm index d2bb125..6d706bd4b 100644 --- a/ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator.mm +++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator.mm
@@ -360,7 +360,8 @@ #pragma mark - PasswordDetailsMediatorDelegate - (void)showDismissWarningDialogWithPasswordDetails:(PasswordDetails*)password { - NSString* title = l10n_util::GetNSString(IDS_IOS_DISMISS_WARNING); + NSString* title = + l10n_util::GetNSString(IDS_IOS_DISMISS_WARNING_DIALOG_TITLE); NSString* message = l10n_util::GetNSString(IDS_IOS_DISMISS_WARNING_DIALOG_MESSAGE); self.alertCoordinator =
diff --git a/ios/chrome/browser/ui/settings/price_notifications/price_notifications_constants.h b/ios/chrome/browser/ui/settings/price_notifications/price_notifications_constants.h deleted file mode 100644 index 3e1c592..0000000 --- a/ios/chrome/browser/ui/settings/price_notifications/price_notifications_constants.h +++ /dev/null
@@ -1,16 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_PRICE_NOTIFICATIONS_PRICE_NOTIFICATIONS_CONSTANTS_H_ -#define IOS_CHROME_BROWSER_UI_SETTINGS_PRICE_NOTIFICATIONS_PRICE_NOTIFICATIONS_CONSTANTS_H_ - -#import <Foundation/Foundation.h> - -// The accessibility identifier of the Price Notifications setting table view. -extern NSString* const kPriceNotificationsTableViewId; - -// The accessibility identifier of the Price Notifications price tracking cell. -extern NSString* const kSettingsPriceNotificationsPriceTrackingCellId; - -#endif // IOS_CHROME_BROWSER_UI_SETTINGS_PRICE_NOTIFICATIONS_PRICE_NOTIFICATIONS_CONSTANTS_H_
diff --git a/ios/chrome/browser/ui/settings/price_notifications/price_notifications_constants.mm b/ios/chrome/browser/ui/settings/price_notifications/price_notifications_constants.mm deleted file mode 100644 index d6d6786..0000000 --- a/ios/chrome/browser/ui/settings/price_notifications/price_notifications_constants.mm +++ /dev/null
@@ -1,15 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "ios/chrome/browser/ui/settings/price_notifications/price_notifications_constants.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -NSString* const kPriceNotificationsTableViewId = - @"kPriceNotificationsTableViewId"; - -NSString* const kSettingsPriceNotificationsPriceTrackingCellId = - @"kSettingsPriceNotificationsPriceTrackingCellId";
diff --git a/ios/chrome/browser/ui/settings/price_notifications/price_notifications_coordinator.h b/ios/chrome/browser/ui/settings/price_notifications/price_notifications_coordinator.h deleted file mode 100644 index c656d3e5..0000000 --- a/ios/chrome/browser/ui/settings/price_notifications/price_notifications_coordinator.h +++ /dev/null
@@ -1,36 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_PRICE_NOTIFICATIONS_PRICE_NOTIFICATIONS_COORDINATOR_H_ -#define IOS_CHROME_BROWSER_UI_SETTINGS_PRICE_NOTIFICATIONS_PRICE_NOTIFICATIONS_COORDINATOR_H_ - -#import "ios/chrome/browser/shared/coordinator/chrome_coordinator/chrome_coordinator.h" - -@class PriceNotificationsCoordinator; - -// Delegate that allows to dereference the PriceNotificationsCoordinator. -@protocol PriceNotificationsCoordinatorDelegate - -// Called when the view controller is removed from navigation controller. -- (void)priceNotificationsCoordinatorDidRemove: - (PriceNotificationsCoordinator*)coordinator; - -@end - -// The coordinator for the Price Notifications screen. -@interface PriceNotificationsCoordinator : ChromeCoordinator - -@property(nonatomic, weak) id<PriceNotificationsCoordinatorDelegate> delegate; - -- (instancetype)initWithBaseViewController:(UIViewController*)viewController - browser:(Browser*)browser NS_UNAVAILABLE; - -- (instancetype)initWithBaseNavigationController: - (UINavigationController*)navigationController - browser:(Browser*)browser - NS_DESIGNATED_INITIALIZER; - -@end - -#endif // IOS_CHROME_BROWSER_UI_SETTINGS_PRICE_NOTIFICATIONS_PRICE_NOTIFICATIONS_COORDINATOR_H_
diff --git a/ios/chrome/browser/ui/settings/price_notifications/price_notifications_mediator.h b/ios/chrome/browser/ui/settings/price_notifications/price_notifications_mediator.h deleted file mode 100644 index c5a16fa..0000000 --- a/ios/chrome/browser/ui/settings/price_notifications/price_notifications_mediator.h +++ /dev/null
@@ -1,39 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_PRICE_NOTIFICATIONS_PRICE_NOTIFICATIONS_MEDIATOR_H_ -#define IOS_CHROME_BROWSER_UI_SETTINGS_PRICE_NOTIFICATIONS_PRICE_NOTIFICATIONS_MEDIATOR_H_ - -#import <UIKit/UIKit.h> -#import <string> - -#import "ios/chrome/browser/ui/settings/price_notifications/notifications_settings_observer.h" -#import "ios/chrome/browser/ui/settings/price_notifications/price_notifications_view_controller_delegate.h" - -class PrefService; -@protocol PriceNotificationsConsumer; -@protocol PriceNotificationsNavigationCommands; - -// Mediator for Price Notifications. -@interface PriceNotificationsMediator - : NSObject <NotificationsSettingsObserverDelegate, - PriceNotificationsViewControllerDelegate> - -// Initializes the mediator with the user's pref service and gaia ID to -// manipulate their push notification permissions. -- (instancetype)initWithPrefService:(PrefService*)prefs - gaiaID:(const std::string&)gaiaID - NS_DESIGNATED_INITIALIZER; - -- (instancetype)init NS_UNAVAILABLE; - -// View controller. -@property(nonatomic, weak) id<PriceNotificationsConsumer> consumer; - -// Handler used to navigate inside the Price Notifications setting. -@property(nonatomic, weak) id<PriceNotificationsNavigationCommands> handler; - -@end - -#endif // IOS_CHROME_BROWSER_UI_SETTINGS_PRICE_NOTIFICATIONS_PRICE_NOTIFICATIONS_MEDIATOR_H_
diff --git a/ios/chrome/browser/ui/settings/price_notifications/price_notifications_navigation_commands.h b/ios/chrome/browser/ui/settings/price_notifications/price_notifications_navigation_commands.h deleted file mode 100644 index 1399c08e..0000000 --- a/ios/chrome/browser/ui/settings/price_notifications/price_notifications_navigation_commands.h +++ /dev/null
@@ -1,17 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_PRICE_NOTIFICATIONS_PRICE_NOTIFICATIONS_NAVIGATION_COMMANDS_H_ -#define IOS_CHROME_BROWSER_UI_SETTINGS_PRICE_NOTIFICATIONS_PRICE_NOTIFICATIONS_NAVIGATION_COMMANDS_H_ - -// Protocol for navigating to different setting pages from Price Notifications -// setting. -@protocol PriceNotificationsNavigationCommands <NSObject> - -// Shows tracking price screen. -- (void)showTrackingPrice; - -@end - -#endif // IOS_CHROME_BROWSER_UI_SETTINGS_PRICE_NOTIFICATIONS_PRICE_NOTIFICATIONS_NAVIGATION_COMMANDS_H_
diff --git a/ios/chrome/browser/ui/settings/price_notifications/price_notifications_view_controller.h b/ios/chrome/browser/ui/settings/price_notifications/price_notifications_view_controller.h deleted file mode 100644 index ac4f1ad4..0000000 --- a/ios/chrome/browser/ui/settings/price_notifications/price_notifications_view_controller.h +++ /dev/null
@@ -1,43 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_PRICE_NOTIFICATIONS_PRICE_NOTIFICATIONS_VIEW_CONTROLLER_H_ -#define IOS_CHROME_BROWSER_UI_SETTINGS_PRICE_NOTIFICATIONS_PRICE_NOTIFICATIONS_VIEW_CONTROLLER_H_ - -#import "ios/chrome/browser/ui/settings/settings_root_table_view_controller.h" - -#import "ios/chrome/browser/ui/settings/price_notifications/price_notifications_consumer.h" -#import "ios/chrome/browser/ui/settings/settings_controller_protocol.h" - -@class PriceNotificationsViewController; -@protocol PriceNotificationsNavigationCommands; -@protocol PriceNotificationsViewControllerDelegate; - -// Delegate for presentation events related to -// PriceNotificationsViewController. -@protocol PriceNotificationsViewControllerPresentationDelegate - -// Called when the view controller is removed from its parent. -- (void)priceNotificationsViewControllerDidRemove: - (PriceNotificationsViewController*)controller; - -@end - -// View controller for Price Notifications setting. -@interface PriceNotificationsViewController - : SettingsRootTableViewController <PriceNotificationsConsumer, - SettingsControllerProtocol> - -// Presentation delegate. -@property(nonatomic, weak) - id<PriceNotificationsViewControllerPresentationDelegate> - presentationDelegate; - -// Delegate for view controller to send responses to model. -@property(nonatomic, weak) id<PriceNotificationsViewControllerDelegate> - modelDelegate; - -@end - -#endif // IOS_CHROME_BROWSER_UI_SETTINGS_PRICE_NOTIFICATIONS_PRICE_NOTIFICATIONS_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/settings/price_notifications/price_notifications_view_controller_delegate.h b/ios/chrome/browser/ui/settings/price_notifications/price_notifications_view_controller_delegate.h deleted file mode 100644 index aa5508a..0000000 --- a/ios/chrome/browser/ui/settings/price_notifications/price_notifications_view_controller_delegate.h +++ /dev/null
@@ -1,19 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_PRICE_NOTIFICATIONS_PRICE_NOTIFICATIONS_VIEW_CONTROLLER_DELEGATE_H_ -#define IOS_CHROME_BROWSER_UI_SETTINGS_PRICE_NOTIFICATIONS_PRICE_NOTIFICATIONS_VIEW_CONTROLLER_DELEGATE_H_ - -@class TableViewItem; - -// Delegate for PriceNotificationsViewController instance to manage the -// model. -@protocol PriceNotificationsViewControllerDelegate <NSObject> - -// Sends `item` to the model to handle logic and navigation. -- (void)didSelectItem:(TableViewItem*)item; - -@end - -#endif // IOS_CHROME_BROWSER_UI_SETTINGS_PRICE_NOTIFICATIONS_PRICE_NOTIFICATIONS_VIEW_CONTROLLER_DELEGATE_H_
diff --git a/ios/chrome/browser/ui/settings/settings_table_view_controller.mm b/ios/chrome/browser/ui/settings/settings_table_view_controller.mm index 8b799fc..c70cd88c 100644 --- a/ios/chrome/browser/ui/settings/settings_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/settings_table_view_controller.mm
@@ -100,11 +100,11 @@ #import "ios/chrome/browser/ui/settings/google_services/manage_sync_settings_coordinator.h" #import "ios/chrome/browser/ui/settings/language/language_settings_mediator.h" #import "ios/chrome/browser/ui/settings/language/language_settings_table_view_controller.h" +#import "ios/chrome/browser/ui/settings/notifications/notifications_coordinator.h" +#import "ios/chrome/browser/ui/settings/notifications/notifications_settings_observer.h" +#import "ios/chrome/browser/ui/settings/notifications/notifications_settings_util.h" #import "ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_utils.h" #import "ios/chrome/browser/ui/settings/password/passwords_coordinator.h" -#import "ios/chrome/browser/ui/settings/price_notifications/notifications_settings_observer.h" -#import "ios/chrome/browser/ui/settings/price_notifications/notifications_settings_util.h" -#import "ios/chrome/browser/ui/settings/price_notifications/price_notifications_coordinator.h" #import "ios/chrome/browser/ui/settings/privacy/privacy_coordinator.h" #import "ios/chrome/browser/ui/settings/safety_check/safety_check_constants.h" #import "ios/chrome/browser/ui/settings/safety_check/safety_check_coordinator.h" @@ -166,7 +166,7 @@ PasswordsCoordinatorDelegate, PopoverLabelViewControllerDelegate, PrefObserverDelegate, - PriceNotificationsCoordinatorDelegate, + NotificationsCoordinatorDelegate, PrivacyCoordinatorDelegate, SafetyCheckCoordinatorDelegate, SettingsControllerProtocol, @@ -214,8 +214,8 @@ GoogleServicesSettingsCoordinator* _googleServicesSettingsCoordinator; ManageSyncSettingsCoordinator* _manageSyncSettingsCoordinator; - // Price notifications coordinator. - PriceNotificationsCoordinator* _priceNotificationsCoordinator; + // notifications coordinator. + NotificationsCoordinator* _notificationsCoordinator; // Privacy coordinator. PrivacyCoordinator* _privacyCoordinator; @@ -247,7 +247,7 @@ TableViewDetailIconItem* _passwordsDetailItem; TableViewDetailIconItem* _autoFillProfileDetailItem; TableViewDetailIconItem* _autoFillCreditCardDetailItem; - TableViewDetailIconItem* _priceNotificationsItem; + TableViewDetailIconItem* _notificationsItem; TableViewItem* _syncItem; // Whether Settings have been dismissed. @@ -464,9 +464,9 @@ [model addSectionWithIdentifier:SettingsSectionIdentifierAdvanced]; if (base::FeatureList::IsEnabled(kNotificationSettingsMenuItem) && IsPriceNotificationsEnabled()) { - _priceNotificationsItem = [self priceNotificationsItem]; + _notificationsItem = [self notificationsItem]; [self updateNotificationsDetailText]; - [model addItem:_priceNotificationsItem + [model addItem:_notificationsItem toSectionWithIdentifier:SettingsSectionIdentifierAdvanced]; } [model addItem:[self voiceSearchDetailItem] @@ -955,14 +955,14 @@ return _safetyCheckItem; } -- (TableViewDetailIconItem*)priceNotificationsItem { - NSString* title = l10n_util::GetNSString(IDS_IOS_PRICE_NOTIFICATIONS_TITLE); - return [self detailItemWithType:SettingsItemTypePriceNotifications +- (TableViewDetailIconItem*)notificationsItem { + NSString* title = l10n_util::GetNSString(IDS_IOS_NOTIFICATIONS_TITLE); + return [self detailItemWithType:SettingsItemTypeNotifications text:title detailText:nil symbol:DefaultSettingsRootSymbol(kBellSymbol) symbolBackgroundColor:[UIColor colorNamed:kPink500Color] - accessibilityIdentifier:kSettingsPriceNotificationsId]; + accessibilityIdentifier:kSettingsNotificationsId]; } - (TableViewItem*)privacyDetailItem { @@ -1377,9 +1377,9 @@ controller = [[AutofillProfileTableViewController alloc] initWithBrowser:_browser]; break; - case SettingsItemTypePriceNotifications: + case SettingsItemTypeNotifications: DCHECK(IsPriceNotificationsEnabled()); - [self showPriceNotifications]; + [self showNotifications]; break; case SettingsItemTypeVoiceSearch: base::RecordAction(base::UserMetricsAction("Settings.VoiceSearch")); @@ -1661,15 +1661,15 @@ [self reconfigureCellsForItems:@[ _safetyCheckItem ]]; } -// Shows Price Notifications screen. -- (void)showPriceNotifications { - DCHECK(!_priceNotificationsCoordinator); +// Shows Notifications screen. +- (void)showNotifications { + DCHECK(!_notificationsCoordinator); DCHECK(self.navigationController); - _priceNotificationsCoordinator = [[PriceNotificationsCoordinator alloc] + _notificationsCoordinator = [[NotificationsCoordinator alloc] initWithBaseNavigationController:self.navigationController browser:_browser]; - _priceNotificationsCoordinator.delegate = self; - [_priceNotificationsCoordinator start]; + _notificationsCoordinator.delegate = self; + [_notificationsCoordinator start]; } // Shows Privacy screen. @@ -1879,7 +1879,7 @@ // Updates the string indicating the push notification state. - (void)updateNotificationsDetailText { - if (!_priceNotificationsItem) { + if (!_notificationsItem) { return; } @@ -1901,8 +1901,8 @@ detailText = l10n_util::GetNSString(IDS_IOS_SETTING_OFF); } - _priceNotificationsItem.detailText = detailText; - [self reconfigureCellsForItems:@[ _priceNotificationsItem ]]; + _notificationsItem.detailText = detailText; + [self reconfigureCellsForItems:@[ _notificationsItem ]]; } #pragma mark - SigninPresenter @@ -1974,8 +1974,8 @@ _passwordsCoordinator.delegate = nil; _passwordsCoordinator = nil; - [_priceNotificationsCoordinator stop]; - _priceNotificationsCoordinator = nil; + [_notificationsCoordinator stop]; + _notificationsCoordinator = nil; [_privacyCoordinator stop]; _privacyCoordinator = nil; @@ -2275,13 +2275,13 @@ _passwordsCoordinator = nil; } -#pragma mark - PriceNotificationsDelegate +#pragma mark - NotificationsDelegate -- (void)priceNotificationsCoordinatorDidRemove: - (PriceNotificationsCoordinator*)coordinator { - DCHECK_EQ(_priceNotificationsCoordinator, coordinator); - [_priceNotificationsCoordinator stop]; - _priceNotificationsCoordinator = nil; +- (void)notificationsCoordinatorDidRemove: + (NotificationsCoordinator*)coordinator { + DCHECK_EQ(_notificationsCoordinator, coordinator); + [_notificationsCoordinator stop]; + _notificationsCoordinator = nil; } #pragma mark - PrivacyCoordinatorDelegate
diff --git a/ios/chrome/browser/ui/settings/settings_table_view_controller_constants.h b/ios/chrome/browser/ui/settings/settings_table_view_controller_constants.h index aca23b1d..1ddbc673 100644 --- a/ios/chrome/browser/ui/settings/settings_table_view_controller_constants.h +++ b/ios/chrome/browser/ui/settings/settings_table_view_controller_constants.h
@@ -35,7 +35,7 @@ SettingsItemTypeAutofillProfile, SettingsItemTypeVoiceSearch, SettingsItemTypeBottomOmnibox, - SettingsItemTypePriceNotifications, + SettingsItemTypeNotifications, SettingsItemTypePrivacy, SettingsItemTypeLanguageSettings, SettingsItemTypeContentSettings, @@ -161,8 +161,8 @@ // when the setting is disabled because of Enterprise policy. extern NSString* const kSettingsIncognitoInterstitialDisabledId; -// The accessibility identifier of the Price Notifications setting. -extern NSString* const kSettingsPriceNotificationsId; +// The accessibility identifier of the Notifications setting. +extern NSString* const kSettingsNotificationsId; // The accessibility identifier of the tabs cell. extern NSString* const kSettingsTabsCellId;
diff --git a/ios/chrome/browser/ui/settings/settings_table_view_controller_constants.mm b/ios/chrome/browser/ui/settings/settings_table_view_controller_constants.mm index ee6c5125..9dea04d 100644 --- a/ios/chrome/browser/ui/settings/settings_table_view_controller_constants.mm +++ b/ios/chrome/browser/ui/settings/settings_table_view_controller_constants.mm
@@ -60,8 +60,7 @@ @"kSettingsIncognitoInterstitialId"; NSString* const kSettingsIncognitoInterstitialDisabledId = @"kSettingsIncognitoInterstitialDisabledId"; -NSString* const kSettingsPriceNotificationsId = - @"kSettingsPriceNotificationsId"; +NSString* const kSettingsNotificationsId = @"kSettingsNotificationsId"; NSString* const kSettingsTabsCellId = @"kSettingsTabsCellId"; NSString* const kSettingsMoveInactiveTabsCellId = @"kSettingsMoveInactiveTabsCellId";
diff --git a/ios/chrome/test/BUILD.gn b/ios/chrome/test/BUILD.gn index 0186edc..baba7c4 100644 --- a/ios/chrome/test/BUILD.gn +++ b/ios/chrome/test/BUILD.gn
@@ -193,6 +193,7 @@ "//ios/chrome/browser/autofill:unit_tests", "//ios/chrome/browser/autofill/manual_fill:unit_tests", "//ios/chrome/browser/bookmarks:unit_tests", + "//ios/chrome/browser/bring_android_tabs:unit_tests", "//ios/chrome/browser/browser_state:unit_tests", "//ios/chrome/browser/browsing_data:unit_tests", "//ios/chrome/browser/commerce:unit_tests",
diff --git a/ios/chrome/test/earl_grey/BUILD.gn b/ios/chrome/test/earl_grey/BUILD.gn index 5940533..ba993833 100644 --- a/ios/chrome/test/earl_grey/BUILD.gn +++ b/ios/chrome/test/earl_grey/BUILD.gn
@@ -138,6 +138,7 @@ "//ios/chrome/browser/ui/ntp", "//ios/chrome/browser/ui/omnibox:eg_app_support+eg2", "//ios/chrome/browser/ui/omnibox:omnibox_internal", + "//ios/chrome/browser/ui/omnibox:omnibox_popup_shared", "//ios/chrome/browser/ui/omnibox/keyboard_assist", "//ios/chrome/browser/ui/omnibox/popup:popup_accessibility_identifier_constants", "//ios/chrome/browser/ui/partial_translate:eg_app_support+eg2", @@ -164,12 +165,12 @@ "//ios/chrome/browser/ui/settings/google_services:constants", "//ios/chrome/browser/ui/settings/google_services:eg_app_support+eg2", "//ios/chrome/browser/ui/settings/language:eg_app_support+eg2", + "//ios/chrome/browser/ui/settings/notifications:constants", + "//ios/chrome/browser/ui/settings/notifications/tracking_price:constants", "//ios/chrome/browser/ui/settings/password:eg_app_support+eg2", "//ios/chrome/browser/ui/settings/password:password_constants", "//ios/chrome/browser/ui/settings/password/password_settings:password_settings_constants", "//ios/chrome/browser/ui/settings/password/passwords_in_other_apps:eg_app_support+eg2", - "//ios/chrome/browser/ui/settings/price_notifications:constants", - "//ios/chrome/browser/ui/settings/price_notifications/tracking_price:constants", "//ios/chrome/browser/ui/settings/privacy:privacy_constants", "//ios/chrome/browser/ui/settings/privacy:privacy_ui", "//ios/chrome/browser/ui/settings/sync",
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey_ui.mm b/ios/chrome/test/earl_grey/chrome_earl_grey_ui.mm index a991faa..2728655 100644 --- a/ios/chrome/test/earl_grey/chrome_earl_grey_ui.mm +++ b/ios/chrome/test/earl_grey/chrome_earl_grey_ui.mm
@@ -342,8 +342,7 @@ grey_allOf(buttonMatcher, grey_interactable(), nil); [[[EarlGrey selectElementWithMatcher:interactableButtonMatcher] usingSearchAction:ScrollDown() - onElementWithMatcher:chrome_test_util:: - SettingsPriceNotificationsTableView()] + onElementWithMatcher:chrome_test_util::SettingsNotificationsTableView()] performAction:grey_tap()]; }
diff --git a/ios/chrome/test/earl_grey/chrome_matchers.h b/ios/chrome/test/earl_grey/chrome_matchers.h index 065cd2a2..690ef73 100644 --- a/ios/chrome/test/earl_grey/chrome_matchers.h +++ b/ios/chrome/test/earl_grey/chrome_matchers.h
@@ -132,6 +132,9 @@ // Returns a matcher for `text` being a substring of the text in the omnibox. id<GREYMatcher> OmniboxContainingText(const std::string& text); +// Returns a matcher for omnibox autocomplete. +id<GREYMatcher> OmniboxAutocompleteLabel(); + // Returns a matcher for `text` being a substring of the text in the location // view. id<GREYMatcher> LocationViewContainingText(const std::string& text); @@ -287,7 +290,7 @@ id<GREYMatcher> SettingsPrivacySafeBrowsingTableView(); // Returns a matcher for the notifications settings table view. -id<GREYMatcher> SettingsPriceNotificationsTableView(); +id<GREYMatcher> SettingsNotificationsTableView(); // Returns a matcher for the tracking price settings table view. id<GREYMatcher> SettingsTrackingPriceTableView(); @@ -320,9 +323,9 @@ // Returns a matcher for the Save passwords cell on the main Settings screen. id<GREYMatcher> SettingsMenuPasswordsButton(); -// Returns a matcher for the Price Notifications cell on the main Settings +// Returns a matcher for the Notifications cell on the main Settings // screen. -id<GREYMatcher> SettingsMenuPriceNotificationsButton(); +id<GREYMatcher> SettingsMenuNotificationsButton(); // Returns a matcher for the payment request collection view. id<GREYMatcher> PaymentRequestView();
diff --git a/ios/chrome/test/earl_grey/chrome_matchers.mm b/ios/chrome/test/earl_grey/chrome_matchers.mm index 027c935..f977c30 100644 --- a/ios/chrome/test/earl_grey/chrome_matchers.mm +++ b/ios/chrome/test/earl_grey/chrome_matchers.mm
@@ -170,6 +170,10 @@ omniboxContainingText:base::SysUTF8ToNSString(text)]; } +id<GREYMatcher> OmniboxAutocompleteLabel() { + return [ChromeMatchersAppInterface omniboxAutocompleteLabel]; +} + id<GREYMatcher> LocationViewContainingText(const std::string& text) { return [ChromeMatchersAppInterface locationViewContainingText:base::SysUTF8ToNSString(text)]; @@ -361,8 +365,8 @@ return [ChromeMatchersAppInterface settingsPrivacySafeBrowsingTableView]; } -id<GREYMatcher> SettingsPriceNotificationsTableView() { - return [ChromeMatchersAppInterface settingsPriceNotificationsTableView]; +id<GREYMatcher> SettingsNotificationsTableView() { + return [ChromeMatchersAppInterface settingsNotificationsTableView]; } id<GREYMatcher> SettingsTrackingPriceTableView() { @@ -398,8 +402,8 @@ return [ChromeMatchersAppInterface settingsMenuPrivacyButton]; } -id<GREYMatcher> SettingsMenuPriceNotificationsButton() { - return [ChromeMatchersAppInterface settingsMenuPriceNotificationsButton]; +id<GREYMatcher> SettingsMenuNotificationsButton() { + return [ChromeMatchersAppInterface settingsMenuNotificationsButton]; } id<GREYMatcher> SettingsMenuPasswordsButton() {
diff --git a/ios/chrome/test/earl_grey/chrome_matchers_app_interface.h b/ios/chrome/test/earl_grey/chrome_matchers_app_interface.h index 0c37615..4e2575d 100644 --- a/ios/chrome/test/earl_grey/chrome_matchers_app_interface.h +++ b/ios/chrome/test/earl_grey/chrome_matchers_app_interface.h
@@ -118,6 +118,9 @@ // Returns matcher for `text` being a substring of the text in the omnibox. + (id<GREYMatcher>)omniboxContainingText:(NSString*)text; +// Returns matcher for omniboxAutocomplete label in the omnibox. ++ (id<GREYMatcher>)omniboxAutocompleteLabel; + // Returns matcher for `text` being a substring of the text in the location // view. + (id<GREYMatcher>)locationViewContainingText:(NSString*)text; @@ -275,8 +278,8 @@ // Returns matcher for the privacy safe browsing table view. + (id<GREYMatcher>)settingsPrivacySafeBrowsingTableView; -// Returns matcher for the price notifications table view. -+ (id<GREYMatcher>)settingsPriceNotificationsTableView; +// Returns matcher for the notifications table view. ++ (id<GREYMatcher>)settingsNotificationsTableView; // Returns matcher for the tracking price table view. + (id<GREYMatcher>)settingsTrackingPriceTableView; @@ -305,8 +308,8 @@ // Returns matcher for the Privacy cell on the main Settings screen. + (id<GREYMatcher>)settingsMenuPrivacyButton; -// Returns matcher for the Price Notifications cell on the main Settings screen. -+ (id<GREYMatcher>)settingsMenuPriceNotificationsButton; +// Returns matcher for the Notifications cell on the main Settings screen. ++ (id<GREYMatcher>)settingsMenuNotificationsButton; // Returns matcher for the Save passwords cell on the main Settings screen. + (id<GREYMatcher>)settingsMenuPasswordsButton;
diff --git a/ios/chrome/test/earl_grey/chrome_matchers_app_interface.mm b/ios/chrome/test/earl_grey/chrome_matchers_app_interface.mm index b78055c..cf4982d8 100644 --- a/ios/chrome/test/earl_grey/chrome_matchers_app_interface.mm +++ b/ios/chrome/test/earl_grey/chrome_matchers_app_interface.mm
@@ -33,6 +33,7 @@ #import "ios/chrome/browser/ui/location_bar/location_bar_steady_view.h" #import "ios/chrome/browser/ui/ntp/new_tab_page_constants.h" #import "ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_views_utils.h" +#import "ios/chrome/browser/ui/omnibox/omnibox_constants.h" #import "ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.h" #import "ios/chrome/browser/ui/omnibox/popup/omnibox_popup_accessibility_identifier_constants.h" #import "ios/chrome/browser/ui/popup_menu/popup_menu_constants.h" @@ -46,10 +47,10 @@ #import "ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller_constants.h" #import "ios/chrome/browser/ui/settings/google_services/google_services_settings_constants.h" #import "ios/chrome/browser/ui/settings/import_data_table_view_controller.h" +#import "ios/chrome/browser/ui/settings/notifications/notifications_constants.h" +#import "ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_constants.h" #import "ios/chrome/browser/ui/settings/password/password_settings/password_settings_constants.h" #import "ios/chrome/browser/ui/settings/password/passwords_table_view_constants.h" -#import "ios/chrome/browser/ui/settings/price_notifications/price_notifications_constants.h" -#import "ios/chrome/browser/ui/settings/price_notifications/tracking_price/tracking_price_constants.h" #import "ios/chrome/browser/ui/settings/privacy/privacy_constants.h" #import "ios/chrome/browser/ui/settings/privacy/privacy_table_view_controller.h" #import "ios/chrome/browser/ui/settings/safety_check/safety_check_ui_swift.h" @@ -364,6 +365,12 @@ return matcher; } ++ (id<GREYMatcher>)omniboxAutocompleteLabel { + return grey_allOf( + grey_accessibilityID(kOmniboxAutocompleteLabelAccessibilityIdentifier), + grey_sufficientlyVisible(), nil); +} + + (id<GREYMatcher>)locationViewContainingText:(NSString*)text { GREYElementMatcherBlock* matcher = [GREYElementMatcherBlock matcherWithMatchesBlock:^BOOL(LocationBarSteadyView* element) { @@ -611,8 +618,8 @@ return grey_accessibilityID(kPrivacySafeBrowsingTableViewId); } -+ (id<GREYMatcher>)settingsPriceNotificationsTableView { - return grey_accessibilityID(kPriceNotificationsTableViewId); ++ (id<GREYMatcher>)settingsNotificationsTableView { + return grey_accessibilityID(kNotificationsTableViewId); } + (id<GREYMatcher>)settingsTrackingPriceTableView { @@ -671,9 +678,9 @@ buttonWithAccessibilityLabelID:(IDS_IOS_SETTINGS_PRIVACY_TITLE)]; } -+ (id<GREYMatcher>)settingsMenuPriceNotificationsButton { ++ (id<GREYMatcher>)settingsMenuNotificationsButton { return [ChromeMatchersAppInterface - buttonWithAccessibilityLabelID:(IDS_IOS_PRICE_NOTIFICATIONS_TITLE)]; + buttonWithAccessibilityLabelID:(IDS_IOS_NOTIFICATIONS_TITLE)]; } + (id<GREYMatcher>)settingsMenuPasswordsButton {
diff --git a/ios/chrome/test/earl_grey2/BUILD.gn b/ios/chrome/test/earl_grey2/BUILD.gn index 2b1afc5..e11b9798 100644 --- a/ios/chrome/test/earl_grey2/BUILD.gn +++ b/ios/chrome/test/earl_grey2/BUILD.gn
@@ -136,10 +136,10 @@ "//ios/chrome/browser/ui/settings/content_settings:eg2_tests", "//ios/chrome/browser/ui/settings/google_services:eg2_tests", "//ios/chrome/browser/ui/settings/language:eg2_tests", + "//ios/chrome/browser/ui/settings/notifications:eg2_tests", + "//ios/chrome/browser/ui/settings/notifications/tracking_price:eg2_tests", "//ios/chrome/browser/ui/settings/password:eg2_tests", "//ios/chrome/browser/ui/settings/password/passwords_in_other_apps:eg2_tests", - "//ios/chrome/browser/ui/settings/price_notifications:eg2_tests", - "//ios/chrome/browser/ui/settings/price_notifications/tracking_price:eg2_tests", "//ios/chrome/browser/ui/settings/privacy:eg2_tests", "//ios/chrome/browser/ui/settings/sync:eg2_tests", ]
diff --git a/media/base/android/media_player_bridge.cc b/media/base/android/media_player_bridge.cc index 2814175c..b9e94f9 100644 --- a/media/base/android/media_player_bridge.cc +++ b/media/base/android/media_player_bridge.cc
@@ -11,7 +11,6 @@ #include "base/android/jni_string.h" #include "base/android/scoped_java_ref.h" #include "base/check_op.h" -#include "base/cxx17_backports.h" #include "base/functional/bind.h" #include "base/metrics/histogram_macros.h" #include "base/notreached.h" @@ -421,7 +420,7 @@ } void MediaPlayerBridge::SetVolume(double volume) { - volume_ = base::clamp(volume, 0.0, 1.0); + volume_ = std::clamp(volume, 0.0, 1.0); UpdateVolumeInternal(); }
diff --git a/media/base/audio_power_monitor.cc b/media/base/audio_power_monitor.cc index 8a1616f9..4a31e302 100644 --- a/media/base/audio_power_monitor.cc +++ b/media/base/audio_power_monitor.cc
@@ -8,7 +8,6 @@ #include <cmath> #include "base/check_op.h" -#include "base/cxx17_backports.h" #include "base/time/time.h" #include "media/base/audio_bus.h" #include "media/base/vector_math.h" @@ -61,7 +60,7 @@ } // Update accumulated results, with clamping for sanity. - average_power_ = base::clamp(sum_power / num_channels, 0.0f, 1.0f); + average_power_ = std::clamp(sum_power / num_channels, 0.0f, 1.0f); // Push results for reading by other threads, non-blocking. if (reading_lock_.Try()) {
diff --git a/media/base/audio_shifter.cc b/media/base/audio_shifter.cc index e25607a..5444ed3 100644 --- a/media/base/audio_shifter.cc +++ b/media/base/audio_shifter.cc
@@ -9,7 +9,6 @@ #include <utility> #include "base/containers/circular_deque.h" -#include "base/cxx17_backports.h" #include "base/functional/bind.h" #include "base/logging.h" #include "base/trace_event/trace_event.h" @@ -199,13 +198,13 @@ // This is the ratio we would need to get perfect sync after // |adjustment_time_| has passed. double slow_ratio = steady_ratio + time_difference / adjustment_time_; - slow_ratio = base::clamp(slow_ratio, 0.9, 1.1); + slow_ratio = std::clamp(slow_ratio, 0.9, 1.1); const base::TimeDelta adjustment_time = base::Seconds(output->frames() / rate_); // This is ratio we we'd need get perfect sync at the end of the // current output audiobus. double fast_ratio = steady_ratio + time_difference / adjustment_time; - fast_ratio = base::clamp(fast_ratio, 0.9, 1.1); + fast_ratio = std::clamp(fast_ratio, 0.9, 1.1); // If the current ratio is somewhere between the slow and the fast // ratio, then keep it. This means we don't have to recalculate the @@ -219,7 +218,7 @@ // perfect sync in the alloted time. Clamp. double max_ratio = std::max(fast_ratio, slow_ratio); double min_ratio = std::min(fast_ratio, slow_ratio); - current_ratio_ = base::clamp(current_ratio_, min_ratio, max_ratio); + current_ratio_ = std::clamp(current_ratio_, min_ratio, max_ratio); } else { // The "direction" has changed. (From speed up to slow down or // vice versa, so we just take the slow ratio.
diff --git a/media/base/tuneable.cc b/media/base/tuneable.cc index cc6b3d5..55cfa23d 100644 --- a/media/base/tuneable.cc +++ b/media/base/tuneable.cc
@@ -4,9 +4,9 @@ #include "media/base/tuneable.h" +#include <algorithm> #include <random> -#include "base/cxx17_backports.h" #include "base/hash/hash.h" #include "base/metrics/field_trial_params.h" #include "base/strings/string_number_conversions.h" @@ -32,7 +32,7 @@ int minimum_value, int default_value, int maximum_value) { - return base::clamp( + return std::clamp( base::FeatureParam<int>(&::media::kMediaOptimizer, name, default_value) .Get(), minimum_value, maximum_value);
diff --git a/media/base/video_decoder.cc b/media/base/video_decoder.cc index 2c5a67f..48787cf 100644 --- a/media/base/video_decoder.cc +++ b/media/base/video_decoder.cc
@@ -7,7 +7,6 @@ #include <algorithm> #include "base/command_line.h" -#include "base/cxx17_backports.h" #include "base/strings/string_number_conversions.h" #include "base/system/sys_info.h" #include "media/base/limits.h" @@ -59,7 +58,7 @@ // zero threads; I.e., decoding will execute on the calling thread. Therefore, // at least two threads are required to allow decoding to progress outside of // each Decode() call. - return base::clamp(desired_threads, + return std::clamp(desired_threads, static_cast<int>(limits::kMinVideoDecodeThreads), static_cast<int>(limits::kMaxVideoDecodeThreads)); }
diff --git a/media/base/video_encoder.cc b/media/base/video_encoder.cc index d27811d3..4ae5780 100644 --- a/media/base/video_encoder.cc +++ b/media/base/video_encoder.cc
@@ -4,7 +4,8 @@ #include "media/base/video_encoder.h" -#include "base/cxx17_backports.h" +#include <algorithm> + #include "base/numerics/checked_math.h" #include "base/numerics/clamped_math.h" #include "base/system/sys_info.h" @@ -23,10 +24,10 @@ // Scale default bitrate to the given frame size and fps base::ClampedNumeric<uint64_t> result = kDefaultBitrateForHD30fps; - result *= base::clamp(framerate, 1u, 300u); - result *= base::clamp(frame_size.GetArea(), 1, kMaxArea); + result *= std::clamp(framerate, 1u, 300u); + result *= std::clamp(frame_size.GetArea(), 1, kMaxArea); result /= kHDArea * 30u; // HD resolution, 30 fps - return base::clamp(result.RawValue(), kMinBitrate, kMaxBitrate); + return std::clamp(result.RawValue(), kMinBitrate, kMaxBitrate); } int GetNumberOfThreadsForSoftwareEncoding(gfx::Size frame_size) {
diff --git a/media/capture/video/chromeos/camera_3a_controller.cc b/media/capture/video/chromeos/camera_3a_controller.cc index 396c6fa..84717a0 100644 --- a/media/capture/video/chromeos/camera_3a_controller.cc +++ b/media/capture/video/chromeos/camera_3a_controller.cc
@@ -4,10 +4,10 @@ #include "media/capture/video/chromeos/camera_3a_controller.h" +#include <algorithm> #include <utility> #include "base/containers/contains.h" -#include "base/cxx17_backports.h" #include "base/functional/bind.h" #include "base/task/single_thread_task_runner.h" #include "base/trace_event/typed_macros.h" @@ -545,10 +545,10 @@ // (xmin, ymin, xmax, ymax, weight) std::vector<int32_t> region = { - base::clamp(point.x() - roi_radius, 0, active_array_size.width() - 1), - base::clamp(point.y() - roi_radius, 0, active_array_size.height() - 1), - base::clamp(point.x() + roi_radius, 0, active_array_size.width() - 1), - base::clamp(point.y() + roi_radius, 0, active_array_size.height() - 1), + std::clamp(point.x() - roi_radius, 0, active_array_size.width() - 1), + std::clamp(point.y() - roi_radius, 0, active_array_size.height() - 1), + std::clamp(point.x() + roi_radius, 0, active_array_size.width() - 1), + std::clamp(point.y() + roi_radius, 0, active_array_size.height() - 1), 1, };
diff --git a/media/capture/video/chromeos/camera_app_device_impl.cc b/media/capture/video/chromeos/camera_app_device_impl.cc index 5d906e2..c17136d 100644 --- a/media/capture/video/chromeos/camera_app_device_impl.cc +++ b/media/capture/video/chromeos/camera_app_device_impl.cc
@@ -4,9 +4,9 @@ #include "media/capture/video/chromeos/camera_app_device_impl.h" +#include <algorithm> #include <cmath> -#include "base/cxx17_backports.h" #include "base/task/bind_post_task.h" #include "base/task/single_thread_task_runner.h" #include "base/time/time.h" @@ -474,8 +474,8 @@ // Rotate a point in coordination space {x: [0.0, 1.0], y: [0.0, 1.0]} with // anchor point {x: 0.5, y: 0.5}. auto rotate_corner = [&](const gfx::PointF& corner) -> gfx::PointF { - float x = base::clamp(corner.x(), 0.0f, 1.0f); - float y = base::clamp(corner.y(), 0.0f, 1.0f); + float x = std::clamp(corner.x(), 0.0f, 1.0f); + float y = std::clamp(corner.y(), 0.0f, 1.0f); switch (rotation) { case VIDEO_ROTATION_0:
diff --git a/media/capture/video/chromeos/camera_device_delegate.cc b/media/capture/video/chromeos/camera_device_delegate.cc index 2f930d6..c173335 100644 --- a/media/capture/video/chromeos/camera_device_delegate.cc +++ b/media/capture/video/chromeos/camera_device_delegate.cc
@@ -13,7 +13,6 @@ #include "ash/constants/ash_features.h" #include "base/containers/contains.h" -#include "base/cxx17_backports.h" #include "base/functional/bind.h" #include "base/functional/callback_helpers.h" #include "base/no_destructor.h" @@ -1379,8 +1378,8 @@ // the closest allowed value. // ref: https://www.w3.org/TR/image-capture/#points-of-interest - double x = base::clamp(points_of_interest[0]->x, 0.0, 1.0); - double y = base::clamp(points_of_interest[0]->y, 0.0, 1.0); + double x = std::clamp(points_of_interest[0]->x, 0.0, 1.0); + double y = std::clamp(points_of_interest[0]->y, 0.0, 1.0); // Handle rotation, still in normalized square space. std::tie(x, y) = [&]() -> std::pair<double, double> {
diff --git a/media/capture/video/fake_video_capture_device.cc b/media/capture/video/fake_video_capture_device.cc index e066be4..2005176 100644 --- a/media/capture/video/fake_video_capture_device.cc +++ b/media/capture/video/fake_video_capture_device.cc
@@ -5,10 +5,10 @@ #include "media/capture/video/fake_video_capture_device.h" #include <stddef.h> + #include <algorithm> #include <utility> -#include "base/cxx17_backports.h" #include "base/functional/bind.h" #include "base/location.h" #include "base/memory/raw_ptr.h" @@ -698,23 +698,23 @@ if (settings->has_pan) { device_state_write_access->pan = - base::clamp(settings->pan, kMinPan, kMaxPan); + std::clamp(settings->pan, kMinPan, kMaxPan); } if (settings->has_tilt) { device_state_write_access->tilt = - base::clamp(settings->tilt, kMinTilt, kMaxTilt); + std::clamp(settings->tilt, kMinTilt, kMaxTilt); } if (settings->has_zoom) { device_state_write_access->zoom = - base::clamp(settings->zoom, kMinZoom, kMaxZoom); + std::clamp(settings->zoom, kMinZoom, kMaxZoom); } if (settings->has_exposure_time) { - device_state_write_access->exposure_time = base::clamp( - settings->exposure_time, kMinExposureTime, kMaxExposureTime); + device_state_write_access->exposure_time = + std::clamp(settings->exposure_time, kMinExposureTime, kMaxExposureTime); } if (settings->has_focus_distance) { - device_state_write_access->focus_distance = base::clamp( + device_state_write_access->focus_distance = std::clamp( settings->focus_distance, kMinFocusDistance, kMaxFocusDistance); }
diff --git a/media/capture/video/file_video_capture_device.cc b/media/capture/video/file_video_capture_device.cc index 6061afc..8ad3ba7 100644 --- a/media/capture/video/file_video_capture_device.cc +++ b/media/capture/video/file_video_capture_device.cc
@@ -6,10 +6,10 @@ #include <stddef.h> +#include <algorithm> #include <memory> #include <utility> -#include "base/cxx17_backports.h" #include "base/functional/bind.h" #include "base/location.h" #include "base/logging.h" @@ -570,14 +570,14 @@ } if (settings->has_pan) { - pan_ = base::clamp(int(settings->pan), 0, zoom_max_levels_); + pan_ = std::clamp(int(settings->pan), 0, zoom_max_levels_); } if (settings->has_tilt) { - tilt_ = base::clamp(int(settings->tilt), 0, zoom_max_levels_); + tilt_ = std::clamp(int(settings->tilt), 0, zoom_max_levels_); } if (settings->has_zoom) { - zoom_ = base::clamp(int(settings->zoom), 0, zoom_max_levels_); + zoom_ = std::clamp(int(settings->zoom), 0, zoom_max_levels_); } std::move(callback).Run(true);
diff --git a/media/cast/sender/congestion_control.cc b/media/cast/sender/congestion_control.cc index 4772dfe9e..3d280a00 100644 --- a/media/cast/sender/congestion_control.cc +++ b/media/cast/sender/congestion_control.cc
@@ -18,7 +18,6 @@ #include <algorithm> #include <deque> -#include "base/cxx17_backports.h" #include "base/logging.h" #include "base/memory/raw_ptr.h" #include "base/numerics/safe_conversions.h" @@ -428,8 +427,8 @@ TRACE_COUNTER_ID1("cast.stream", "Empty Buffer Fraction", this, empty_buffer_fraction); - return base::clamp(bits_per_second, min_bitrate_configured_, - max_bitrate_configured_); + return std::clamp(bits_per_second, min_bitrate_configured_, + max_bitrate_configured_); } } // namespace cast
diff --git a/media/cast/sender/openscreen_frame_sender.cc b/media/cast/sender/openscreen_frame_sender.cc index 88e1330b..60d2b0c 100644 --- a/media/cast/sender/openscreen_frame_sender.cc +++ b/media/cast/sender/openscreen_frame_sender.cc
@@ -10,7 +10,6 @@ #include <utility> #include <vector> -#include "base/cxx17_backports.h" #include "base/feature_list.h" #include "base/functional/bind.h" #include "base/logging.h" @@ -110,8 +109,8 @@ return; } - new_target_playout_delay = base::clamp( - new_target_playout_delay, min_playout_delay_, max_playout_delay_); + new_target_playout_delay = std::clamp(new_target_playout_delay, + min_playout_delay_, max_playout_delay_); VLOG_WITH_SSRC(2) << "Target playout delay changing from " << target_playout_delay_.InMilliseconds() << " ms to " << new_target_playout_delay.InMilliseconds() << " ms.";
diff --git a/media/filters/vp9_parser.cc b/media/filters/vp9_parser.cc index 0e2bb6e..683f1197 100644 --- a/media/filters/vp9_parser.cc +++ b/media/filters/vp9_parser.cc
@@ -14,7 +14,6 @@ #include <algorithm> #include "base/containers/circular_deque.h" -#include "base/cxx17_backports.h" #include "base/functional/bind.h" #include "base/functional/callback_helpers.h" #include "base/logging.h" @@ -149,7 +148,7 @@ int ClampLf(int lf) { constexpr int kMaxLoopFilterLevel = 63; - return base::clamp(lf, 0, kMaxLoopFilterLevel); + return std::clamp(lf, 0, kMaxLoopFilterLevel); } std::string IncrementIV(const std::string& iv, uint32_t by) {
diff --git a/media/gpu/mac/vt_video_decode_accelerator_mac.cc b/media/gpu/mac/vt_video_decode_accelerator_mac.cc index ea7c4ba..1d669939 100644 --- a/media/gpu/mac/vt_video_decode_accelerator_mac.cc +++ b/media/gpu/mac/vt_video_decode_accelerator_mac.cc
@@ -10,13 +10,13 @@ #include <OpenGL/gl.h> #include <stddef.h> +#include <algorithm> #include <iterator> #include <memory> #include "base/atomic_sequence_num.h" #include "base/containers/contains.h" #include "base/containers/span.h" -#include "base/cxx17_backports.h" #include "base/functional/bind.h" #include "base/logging.h" #include "base/mac/mac_logging.h" @@ -499,7 +499,7 @@ int max_dpb_frames = max_dpb_mbs / ((sps->pic_width_in_mbs_minus1 + 1) * (sps->pic_height_in_map_units_minus1 + 1)); - max_dpb_frames = base::clamp(max_dpb_frames, 0, 16); + max_dpb_frames = std::clamp(max_dpb_frames, 0, 16); // See AVC spec section E.2.1 definition of |max_num_reorder_frames|. if (sps->vui_parameters_present_flag && sps->bitstream_restriction_flag) {
diff --git a/media/gpu/v4l2/v4l2_jpeg_encode_accelerator.cc b/media/gpu/v4l2/v4l2_jpeg_encode_accelerator.cc index 0bac940..243c7a16 100644 --- a/media/gpu/v4l2/v4l2_jpeg_encode_accelerator.cc +++ b/media/gpu/v4l2/v4l2_jpeg_encode_accelerator.cc
@@ -9,11 +9,11 @@ #include <string.h> #include <sys/mman.h> +#include <algorithm> #include <memory> #include <tuple> #include <utility> -#include "base/cxx17_backports.h" #include "base/functional/bind.h" #include "base/functional/callback_helpers.h" #include "base/task/bind_post_task.h" @@ -162,7 +162,7 @@ for (size_t i = 0; i < kDctSize; i++) { temp = ((unsigned int)basic_table[kZigZag8x8[i]] * quality + 50) / 100; /* limit the values to the valid range */ - dst_table[i] = base::clamp(temp, 1u, 255u); + dst_table[i] = std::clamp(temp, 1u, 255u); } } @@ -1006,7 +1006,7 @@ for (size_t i = 0; i < kDctSize; i++) { temp = ((unsigned int)basic_table[kZigZag8x8[i]] * quality + 50) / 100; /* limit the values to the valid range */ - dst_table[i] = base::clamp(temp, 1u, 255u); + dst_table[i] = std::clamp(temp, 1u, 255u); } }
diff --git a/media/gpu/vaapi/test/vp8_decoder.cc b/media/gpu/vaapi/test/vp8_decoder.cc index aac996d2..262b3db 100644 --- a/media/gpu/vaapi/test/vp8_decoder.cc +++ b/media/gpu/vaapi/test/vp8_decoder.cc
@@ -5,9 +5,10 @@ #include "media/gpu/vaapi/test/vp8_decoder.h" #include <va/va.h> + +#include <algorithm> #include <memory> -#include "base/cxx17_backports.h" #include "media/filters/ivf_parser.h" #include "media/gpu/vaapi/test/macros.h" #include "media/parsers/vp8_parser.h" @@ -94,7 +95,7 @@ } } -#define CLAMP_Q(q) base::clamp(q, 0, 127) +#define CLAMP_Q(q) std::clamp(q, 0, 127) iq_matrix_buf.quantization_index[i][0] = CLAMP_Q(q); iq_matrix_buf.quantization_index[i][1] = CLAMP_Q(q + quant_hdr.y_dc_delta); iq_matrix_buf.quantization_index[i][2] = CLAMP_Q(q + quant_hdr.y2_dc_delta); @@ -154,7 +155,7 @@ } } - pic_param.loop_filter_level[i] = base::clamp(lf_level, 0, 63); + pic_param.loop_filter_level[i] = std::clamp(lf_level, 0, 63); } static_assert(
diff --git a/media/gpu/vaapi/vaapi_jpeg_encoder.cc b/media/gpu/vaapi/vaapi_jpeg_encoder.cc index 7226b21..50c91f5 100644 --- a/media/gpu/vaapi/vaapi_jpeg_encoder.cc +++ b/media/gpu/vaapi/vaapi_jpeg_encoder.cc
@@ -4,14 +4,14 @@ #include "media/gpu/vaapi/vaapi_jpeg_encoder.h" -#include <array> -#include <type_traits> - #include <stddef.h> #include <string.h> +#include <algorithm> +#include <array> +#include <type_traits> + #include "base/check_op.h" -#include "base/cxx17_backports.h" #include "base/numerics/safe_conversions.h" #include "media/gpu/macros.h" #include "media/gpu/vaapi/vaapi_wrapper.h" @@ -214,7 +214,7 @@ VaapiWrapper::GetImplementationType() == VAImplementation::kIntelIHD ? 50 : 0; uint32_t scaled_quant_value = (quant_table.value[kZigZag8x8[j]] * quality_normalized + shift) / 100; - scaled_quant_value = base::clamp(scaled_quant_value, 1u, 255u); + scaled_quant_value = std::clamp(scaled_quant_value, 1u, 255u); header[idx++] = static_cast<uint8_t>(scaled_quant_value); } }
diff --git a/media/gpu/vaapi/vaapi_utils.cc b/media/gpu/vaapi/vaapi_utils.cc index 1fe2a25..06d1588 100644 --- a/media/gpu/vaapi/vaapi_utils.cc +++ b/media/gpu/vaapi/vaapi_utils.cc
@@ -4,10 +4,10 @@ #include "media/gpu/vaapi/vaapi_utils.h" +#include <algorithm> #include <type_traits> #include <utility> -#include "base/cxx17_backports.h" #include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/synchronization/lock.h" @@ -218,7 +218,7 @@ } } -#define CLAMP_Q(q) base::clamp(q, 0, 127) +#define CLAMP_Q(q) std::clamp(q, 0, 127) iq_matrix_buf->quantization_index[i][0] = CLAMP_Q(q); iq_matrix_buf->quantization_index[i][1] = CLAMP_Q(q + quant_hdr.y_dc_delta); iq_matrix_buf->quantization_index[i][2] = @@ -300,7 +300,7 @@ } } - pic_param->loop_filter_level[i] = base::clamp(lf_level, 0, 63); + pic_param->loop_filter_level[i] = std::clamp(lf_level, 0, 63); } static_assert(
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 f69f1cb..d541b17 100644 --- a/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc +++ b/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc
@@ -10,12 +10,12 @@ #include <mftransform.h> #include <objbase.h> +#include <algorithm> #include <iterator> #include <memory> #include <utility> #include <vector> -#include "base/cxx17_backports.h" #include "base/features.h" #include "base/memory/shared_memory_mapping.h" #include "base/memory/unsafe_shared_memory_region.h" @@ -812,7 +812,7 @@ bitrate_allocation.GetMode() == bitrate_allocation_.GetMode(), "Invalid bitrate mode", ); framerate = - base::clamp(framerate, 1u, static_cast<uint32_t>(kMaxFrameRateNumerator)); + std::clamp(framerate, 1u, static_cast<uint32_t>(kMaxFrameRateNumerator)); if (framerate == frame_rate_ && bitrate_allocation == bitrate_allocation_) { return;
diff --git a/media/learning/impl/distribution_reporter.cc b/media/learning/impl/distribution_reporter.cc index 1e83192..684794e 100644 --- a/media/learning/impl/distribution_reporter.cc +++ b/media/learning/impl/distribution_reporter.cc
@@ -4,7 +4,8 @@ #include "media/learning/impl/distribution_reporter.h" -#include "base/cxx17_backports.h" +#include <algorithm> + #include "base/functional/bind.h" #include "base/metrics/histogram_functions.h" #include "services/metrics/public/cpp/ukm_builders.h" @@ -214,7 +215,7 @@ (task().ukm_max_input_value - task().ukm_min_input_value) + output_min; // Clip to [0, 100] and truncate to an integer. - return base::clamp(static_cast<int>(scaled_value), output_min, output_max); + return std::clamp(static_cast<int>(scaled_value), output_min, output_max); } };
diff --git a/media/video/av1_video_encoder.cc b/media/video/av1_video_encoder.cc index b3942c5..e9130ff 100644 --- a/media/video/av1_video_encoder.cc +++ b/media/video/av1_video_encoder.cc
@@ -4,9 +4,9 @@ #include "media/video/av1_video_encoder.h" +#include <algorithm> #include <cmath> -#include "base/cxx17_backports.h" #include "base/logging.h" #include "base/numerics/checked_math.h" #include "base/strings/stringprintf.h" @@ -493,7 +493,7 @@ constexpr auto min_duration = base::Seconds(1.0 / 60.0); constexpr auto max_duration = base::Seconds(1.0 / 24.0); auto duration = frame.timestamp() - last_frame_timestamp_; - return base::clamp(duration, min_duration, max_duration); + return std::clamp(duration, min_duration, max_duration); } void Av1VideoEncoder::DrainOutputs(int temporal_id,
diff --git a/media/video/vpx_video_encoder.cc b/media/video/vpx_video_encoder.cc index 8e6fe3c..f5fec72 100644 --- a/media/video/vpx_video_encoder.cc +++ b/media/video/vpx_video_encoder.cc
@@ -6,7 +6,6 @@ #include <algorithm> -#include "base/cxx17_backports.h" #include "base/logging.h" #include "base/numerics/checked_math.h" #include "base/strings/stringprintf.h" @@ -687,7 +686,7 @@ constexpr auto min_duration = base::Seconds(1.0 / 60.0); constexpr auto max_duration = base::Seconds(1.0 / 24.0); auto duration = frame.timestamp() - last_frame_timestamp_; - return base::clamp(duration, min_duration, max_duration); + return std::clamp(duration, min_duration, max_duration); } VpxVideoEncoder::~VpxVideoEncoder() {
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc index fbe810a2..0b96947 100644 --- a/net/http/http_network_transaction_unittest.cc +++ b/net/http/http_network_transaction_unittest.cc
@@ -23546,6 +23546,110 @@ trans3.reset(); } +TEST_F(HttpNetworkTransactionTest, SSLConfigChangedDuringTransaction) { + SSLContextConfig ssl_context_config; + ssl_context_config.version_max = SSL_PROTOCOL_VERSION_TLS1_3; + auto ssl_config_service = + std::make_unique<TestSSLConfigService>(ssl_context_config); + TestSSLConfigService* ssl_config_service_raw = ssl_config_service.get(); + session_deps_.ssl_config_service = std::move(ssl_config_service); + + // First request will start connecting before SSLConfig change. + HttpRequestInfo request1; + request1.method = "GET"; + request1.url = GURL("https://foo.test/1"); + request1.traffic_annotation = + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); + + const MockWrite kWrites1[] = { + MockWrite("GET /1 HTTP/1.1\r\n" + "Host: foo.test\r\n" + "Connection: keep-alive\r\n\r\n"), + }; + const MockRead kReads1[] = { + MockRead(ASYNC, ERR_IO_PENDING, 1), + MockRead(ASYNC, 2, + "HTTP/1.1 200 OK\r\n" + "Connection: keep-alive\r\n" + "Content-Length: 1\r\n\r\n" + "1"), + }; + + // Second request will be after SSLConfig changes so it should be on a new + // socket. + HttpRequestInfo request2; + request2.method = "GET"; + request2.url = GURL("https://foo.test/2"); + request2.traffic_annotation = + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); + + const MockWrite kWrites2[] = { + MockWrite("GET /2 HTTP/1.1\r\n" + "Host: foo.test\r\n" + "Connection: keep-alive\r\n\r\n")}; + + const MockRead kReads2[] = { + MockRead("HTTP/1.1 200 OK\r\n" + "Connection: keep-alive\r\n" + "Content-Length: 1\r\n\r\n" + "2")}; + + SequencedSocketData data1(kReads1, kWrites1); + StaticSocketDataProvider data2(kReads2, kWrites2); + session_deps_.socket_factory->AddSocketDataProvider(&data1); + session_deps_.socket_factory->AddSocketDataProvider(&data2); + + SSLSocketDataProvider ssl1(ASYNC, OK); + // 1st request starts before config change, so should see the initial + // SSLConfig. + ssl1.expected_ssl_version_max = SSL_PROTOCOL_VERSION_TLS1_3; + + SSLSocketDataProvider ssl2(ASYNC, OK); + // 2nd request should be made on a new socket after config change, so should + // see the new SSLConfig. + ssl2.expected_ssl_version_max = SSL_PROTOCOL_VERSION_TLS1_2; + + session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1); + session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2); + + std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_); + + TestCompletionCallback callback1; + auto trans1 = + std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get()); + int rv = trans1->Start(&request1, callback1.callback(), NetLogWithSource()); + EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); + + // Wait for the first transaction to connect and start reading data. + data1.RunUntilPaused(); + + // Change network config. + ssl_context_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2; + ssl_config_service_raw->UpdateSSLConfigAndNotify(ssl_context_config); + + // Resume the first transaction reads. + data1.Resume(); + EXPECT_THAT(callback1.GetResult(rv), IsOk()); + std::string response_data1; + EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk()); + EXPECT_EQ("1", response_data1); + trans1.reset(); + + // Start 2nd transaction. Since the config was changed, it should use a new + // socket. + TestCompletionCallback callback2; + auto trans2 = + std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get()); + rv = trans2->Start(&request2, callback2.callback(), NetLogWithSource()); + EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); + + EXPECT_THAT(callback2.GetResult(rv), IsOk()); + std::string response_data2; + EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk()); + EXPECT_EQ("2", response_data2); + trans2.reset(); +} + TEST_F(HttpNetworkTransactionTest, SSLConfigChangedPendingConnect) { SSLContextConfig ssl_context_config; ssl_context_config.version_max = SSL_PROTOCOL_VERSION_TLS1_3; @@ -23561,11 +23665,27 @@ request.traffic_annotation = net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); - // Make a socket which never connects. - StaticSocketDataProvider data({}, {}); - session_deps_.socket_factory->AddSocketDataProvider(&data); - SSLSocketDataProvider ssl_data(SYNCHRONOUS, ERR_IO_PENDING); - ssl_data.expected_ssl_version_max = SSL_PROTOCOL_VERSION_TLS1_3; + const MockWrite kWrites1[] = { + MockWrite("GET /1 HTTP/1.1\r\n" + "Host: foo.test\r\n" + "Connection: keep-alive\r\n\r\n"), + }; + const MockRead kReads1[] = { + MockRead("HTTP/1.1 200 OK\r\n" + "Connection: keep-alive\r\n" + "Content-Length: 1\r\n\r\n" + "1"), + }; + + StaticSocketDataProvider data1(kReads1, kWrites1); + session_deps_.socket_factory->AddSocketDataProvider(&data1); + session_deps_.socket_factory->AddSocketDataProvider(&data1); + + // Even though the transaction was created before the change, the connection + // shouldn't happen until after the SSLConfig change, so expect that the + // socket will be created with the new SSLConfig. + SSLSocketDataProvider ssl_data(ASYNC, OK); + ssl_data.expected_ssl_version_max = SSL_PROTOCOL_VERSION_TLS1_2; session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data); std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_); @@ -23579,7 +23699,11 @@ ssl_context_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2; ssl_config_service_raw->UpdateSSLConfigAndNotify(ssl_context_config); - EXPECT_THAT(callback.GetResult(rv), IsError(ERR_NETWORK_CHANGED)); + EXPECT_THAT(callback.GetResult(rv), IsOk()); + std::string response_data; + EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk()); + EXPECT_EQ("1", response_data); + trans.reset(); } // Test that HttpNetworkTransaction correctly handles existing sockets when the
diff --git a/net/http/transport_security_state_static.json b/net/http/transport_security_state_static.json index 4ad5b64a..480a0f12 100644 --- a/net/http/transport_security_state_static.json +++ b/net/http/transport_security_state_static.json
@@ -3165,7 +3165,6 @@ { "name": "harmoney.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "istheapplestoredown.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "jayblock.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "jgid.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "juergenhecht.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "kpvpn.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "labrador-retrievers.com.au", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -3203,7 +3202,6 @@ { "name": "stugb.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "swapadoodle.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "syncer.jp", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "tannenhof-moelln.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "theintercept.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "thinklikeanentrepreneur.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "ulabox.cat", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -3213,7 +3211,6 @@ { "name": "upstats.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "usgande.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "vat-eu.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "veblen.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "viemeister.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "wait.jp", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "wohnsitz-ausland.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -3647,7 +3644,6 @@ { "name": "eeqj.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "elitefishtank.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "englerts.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "eugenekay.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "evasovova.cz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "eyasc.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "eydesignguidelines.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -4639,7 +4635,6 @@ { "name": "faspirits.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "faspirits.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "feezmodo.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "floridaescapes.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "florismouwen.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "fotostudio-schweiz.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "freiwurst.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -5391,10 +5386,6 @@ { "name": "livnev.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "loafbox.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "localchum.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "logicsale.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "logicsale.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "logicsale.fr", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "logicsale.it", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "loginseite.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "loli.bz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "loopstart.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -6050,7 +6041,6 @@ { "name": "javalestari.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "jayschulman.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "jayscoaching.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "jcoscia.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "jensenbanden.no", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "jetsetcharge.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "jetsieswerda.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -6881,7 +6871,6 @@ { "name": "linkenheil.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "linkmaker.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "linkonaut.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "linpx.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "liquidcomm.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "loadingdeck.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "locomotive.ca", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -6964,7 +6953,6 @@ { "name": "politologos.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "pro-link.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "punknews.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "pvcvoordeel.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "quera.ir", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "quire.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "racius.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -7768,7 +7756,6 @@ { "name": "kolmann.at", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "kroon.email", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "kuemmling.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "kzsdabas.hu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "leardev.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "life-time.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "livecards.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -7814,7 +7801,6 @@ { "name": "oogami.name", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "onysix.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "orleika.ml", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "oleksii.name", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "ostr.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "papa-webzeit.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "percolate.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -8027,7 +8013,6 @@ { "name": "microco.sm", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "mizque.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "moe4sale.in", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "mvbits.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "mysignal.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "narindal.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "nasrsolar.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -8362,7 +8347,6 @@ { "name": "labourreedevergheas.fr", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "lacyc3.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "laextra.mx", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "langworth.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "lattyware.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "lattyware.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "lavita.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -10841,7 +10825,6 @@ { "name": "secundity.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "sectelligence.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "saz.sh", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "rue-de-la-vieille.fr", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "shareoffice.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "sfirat-haomer.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "sapac.es", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -11222,7 +11205,6 @@ { "name": "ryazan-region.ru", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "sackmesser.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "salde.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "sam-football.fr", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "sauerland-schnittgruen.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "scheinlichter.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "scherfke.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -11532,7 +11514,6 @@ { "name": "codestudies.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "collabora-office.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "collabora.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "collaboracloudsuite.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "collaboraoffice.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "collaboraoffice.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "communitycodeofconduct.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -12424,7 +12405,6 @@ { "name": "wallabies.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "walruses.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "weare1inspirit.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "webart-factory.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "webcrm.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "websiteservice.pro", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "webspotter.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -13034,7 +13014,6 @@ { "name": "musikverein-elten.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "neostralis.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "nickcraver.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "nicolasiung.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "nebulae.co", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "newgrowbook.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "michaeln.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -14578,7 +14557,6 @@ { "name": "insult.es", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "integratedmedicalonline.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "introvertedtravel.space", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "invisible-college.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "itzap.com.au", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "ivanbenito.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "japaneseemoticons.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -14592,7 +14570,6 @@ { "name": "juergenspecht.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "juniperroots.ca", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "k8r.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "kaatha-kamrater.se", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "karina.gd", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "kdw.cloud", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "kimisia.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -16018,7 +15995,6 @@ { "name": "collinel-hossari.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "collinelhossari.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "csfd.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "cybercloud.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "datatruckers.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "datatruckers.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "degracetechnologie.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -17412,7 +17388,6 @@ { "name": "ruediger-voigt.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "scoop6.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "sealoffantasy.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "seibert.ninja", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "serviziourgente.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "shakerwebdesign.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "shankangke.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -18291,7 +18266,6 @@ { "name": "lineageos.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "macros.co.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "magicvodi.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "manuscriptlink.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mariapietropola.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "markdain.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mathsource.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -18363,7 +18337,6 @@ { "name": "synccentre.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "syscoon.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "teplofom.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "teplomash24.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "thebusinessofgoodfilm.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "think-asia.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "thirdbearsolutions.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -18384,18 +18357,12 @@ { "name": "usninosnikrcni.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "usnti.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "uvenuse.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "valcano-krd.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "valcano.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "venturebanners.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "vikapaula.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "villehardouin.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "visitcambridgeshirefens.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "vlndc.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "volcano-kazan.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "volcano-spb.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "volcano-vts.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "volcano24.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "volcanov.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "wanderzoom.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "web-art.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "webline.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -18404,9 +18371,7 @@ { "name": "whatismycountry.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "xerownia.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "xif.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "xn--24-6kch4bfqee.xn--p1ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "xn--80adb4aeode.xn--p1ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "xn--e1aoahhqgn.xn--p1ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "xn--myrepubic-wub.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "xn--myrepublc-x5a.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "xserownia.com.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -18496,7 +18461,6 @@ { "name": "sparta-en.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "talentcast.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "thenowheremen.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "tunaut.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "undeductive.media", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "utwente.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "uzsvm.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -20353,7 +20317,6 @@ { "name": "billionaire365.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "binnenmeer.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "biztouch.work", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "blinds-unlimited.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "blogdelosjuguetes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "bluimedia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "bokkeriders.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -21247,7 +21210,6 @@ { "name": "develops.co.il", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "diatrofi-ygeia.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "dixibox.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "dnakids.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "domob.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "drewapianostudio.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "drtimmarch.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -21690,7 +21652,6 @@ { "name": "myhuthwaite.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mypnu.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "nakliyat.name.tr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "nange.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ndpigskin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "nmmlp.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "nogetime.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -24836,7 +24797,6 @@ { "name": "fleetyards.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "fosgreece.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "getintopc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "gmuh.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "headforcloud.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hell.sh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hicts.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -26577,7 +26537,6 @@ { "name": "yappy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "yorgosbos.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "youneedfame.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "zety.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "0--1.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "a1post.bg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "alaskabuylocal.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -27438,7 +27397,6 @@ { "name": "kathy.lgbt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "kinderopvangthuis.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "kreditkoll.nu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "krumpf.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "kubabrussel.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "lacuerba.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "lolcloud.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -28813,7 +28771,6 @@ { "name": "timich.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "tips4india.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "tirteafuera.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "tixio.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "tolerance-zero.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "tomsk.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "tonorosario.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -30824,7 +30781,6 @@ { "name": "iancu.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ifbagro.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "infans.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "infinity3dengine.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "iosecurity.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "jaluzelemoderne.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "jarmandental.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -32441,7 +32397,6 @@ { "name": "hartleighclyde.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hceu-performance.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hennesshop.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "hiwannz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hly0928.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hofstaetter.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hotelcorporatecodes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -32521,7 +32476,6 @@ { "name": "prodentalsantacruz.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "pusehusetkattehotell.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "pusehusetmalvik.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "radiosdeguate.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "recruit.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "rekurasi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ricardotaakehb.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -34040,7 +33994,6 @@ { "name": "abstimmen.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "acpica.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "alimentsduquebecaumenu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "alternatyv.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "bayer.earth", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "bridgeforcefinancial.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "bushfirerecovery.gov.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -34139,7 +34092,6 @@ { "name": "teq-automotive.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "tewkesburyyoga.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "texteditor.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "thecreativeedgeinc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "thinkbot.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "tocasoft.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "tomvst.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -34352,7 +34304,6 @@ { "name": "xormatic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "yoogirls.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "zusterjansen.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "1abcicka.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "365.systems", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "abetterdeath.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "abi95oha.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -34478,7 +34429,6 @@ { "name": "seminarraum-isny.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "sequachee.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "shipmonk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "shippinglabel.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "smlk.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "softskills.tech", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "standheizung-shop.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -34499,13 +34449,10 @@ { "name": "vanuithartenziel.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "vizedia.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "vleo.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "volcano-x.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "wildfoxlady.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "wippie.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "wiseradiology.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "www.gov.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "xn----7sbbagp2bcfwdeee1afm.xn--p1ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "xn----dtbhcpoeofgcvoic1s.xn--p1ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "xn--pascal-klsch-cjb.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "xoan.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "yn.org.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -34643,7 +34590,6 @@ { "name": "detroitjockcity.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "developingtheworkforce.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "devignstudios.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "dgl-24.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "digchip.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "digchip.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "digchip.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -35050,7 +34996,6 @@ { "name": "thgstardragon.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "tilellit.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "tiltedscalescollective.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "tiqets.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "toolsense.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "trackulo.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "trainingminds.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -35638,7 +35583,6 @@ { "name": "m7rxx.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mallgastronomico.com.ar", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "malsignature.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "marketingproducts.review", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "melonhub.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mental-check.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "meulk.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -45716,7 +45660,6 @@ { "name": "raulmalea.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "reciplast.cl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "redcupit.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "remhomut.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "reto.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "rosewater.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "saipeople.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -46888,7 +46831,6 @@ { "name": "bakerbasements.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "beautyest.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "benmedia.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "bigeasygrille.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "bka.li", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "bowlidex.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "breffa.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -47552,7 +47494,6 @@ { "name": "avclub.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "avogel-company.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "avogel.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "avogel.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "avogel.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "avogel.ie", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "avogel.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -49667,7 +49608,6 @@ { "name": "igolf.in.th", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ilovias-farm.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "index.law", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "infinite.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "infinitysportsandfitness.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "interlinked.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ireiguam.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -49948,7 +49888,6 @@ { "name": "chronicals.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "cinemaz.to", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "circleofhealthlongmont.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "clarisights.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "clegc-gckey.gc.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "clodo.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "cloudinfinit.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -50906,7 +50845,6 @@ { "name": "mylover.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mynic.my", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "myparadigm.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "mzrme.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "nanaimo.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "nationalfleetparts.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "neweggsoft.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -53621,7 +53559,6 @@ { "name": "topsvet.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "toys4education.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "tradagars.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "trihunter6000.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "truckerjobusa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "tun.bible", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "uberalles.live", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -57182,7 +57119,6 @@ { "name": "amazinations.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "americancomfortexperts.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "americanflooringservicesinc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "ammachiyudeadukkala.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "anniangel-porn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "annitrinity.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "apexperformancegym.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -58013,7 +57949,6 @@ { "name": "tiffanyblooms.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "tilitoimistokota.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "timeswiki.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "timosfoodbar.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "topmotoric.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "toptravelgram.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "tournaments.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -62912,7 +62847,6 @@ { "name": "clovorin.gq", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "codigomusical.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "commercegurus.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "comunecampodigiove.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "conexresearch.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "cooferro.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "coombsinc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -71674,7 +71608,6 @@ { "name": "foundland.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "freemchosting.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "freeme.gq", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "freenome.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "gaborg.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "gamepuzzleinfo.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "gassycat.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -72449,7 +72382,6 @@ { "name": "grupomonti.com.ar", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "gutshaus-marketing.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "gwmjordan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "haitrieu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hannahbarrettyoga.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "happiness.solutions", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hasansaribas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -75260,7 +75192,6 @@ { "name": "portalchega.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "porumaoutrareforma.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "potemkin.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "pother.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "preciofishbone.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "pridurok.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "privacy-web.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -76338,7 +76269,6 @@ { "name": "unsupervised.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "uwe-arzt.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "valedigitalservice.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "valisevoyage.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "vanndigital.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "vasconcellos.casa", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "vasficelik.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -76351,7 +76281,6 @@ { "name": "vulnerable.af", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "weitundbreit.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "wikimho.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "willship.co.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "wkd.one", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "wordindonesia.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "writingontablets.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -77508,7 +77437,6 @@ { "name": "certified-parts.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "charliejonas.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "charliejonas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "chieuminh.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "christchapel.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "chtj.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ciao.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -77996,7 +77924,6 @@ { "name": "somsak.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "square-phone.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "squarenoid.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "ssst.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "structure.gov.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "sydneyshisha.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "taoismus.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -78067,7 +77994,6 @@ { "name": "alpaca.haus", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "alpenguides.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "amalou-photografie.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "amikton.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "andresguiarealtor.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "anesterov.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "angel-jrk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -78742,7 +78668,6 @@ { "name": "grechutaszkolenia.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "green-version.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "greendotcredit.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "greenface.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "gresrewop.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "gridgain.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "gridgames.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -78873,7 +78798,6 @@ { "name": "nettikasino247.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "neue-energien.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "newsliner.gq", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "nicolas-hoizey.photo", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "nkg-mosbach.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "noblechemical.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "nobleproducts.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -78995,7 +78919,6 @@ { "name": "shkola1.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "shopbackyardpro.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "shoplistic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "simpul.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "siptls.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "sitnikov.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "sittingwell.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -79274,7 +79197,6 @@ { "name": "estudiarperiodismoonline.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "estudiarpsicologiaonline.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "etalentos.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "ethanopp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "eurocontrol.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "eurodata.sk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "evangelicalplatform.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -79483,7 +79405,6 @@ { "name": "redoikos.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "relookdecoration.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "resimdo.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "resistancebooks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "restream.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "reviewengin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "rhinobase.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -80220,7 +80141,6 @@ { "name": "2ndface.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "absolutelybaching.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "achicrip.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "acorta.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "acsiresearch.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "adverganda.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "adverganda.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -80615,7 +80535,6 @@ { "name": "lesbicas.com.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "liivimeretuulepark.ee", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "limitlex.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "lindeal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "loading.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "lonestarpediatricdental.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "lovell.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -81234,7 +81153,6 @@ { "name": "billigflug.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "binarycom.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "bioenergie-eferding.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "biohof-paas.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "biomarket24.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "biopro-st.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "birdist.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -82299,7 +82217,6 @@ { "name": "globedx.exchange", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "glorystar.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "glossar.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "gmundner.africa", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "gmz.cx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "gnomen.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "go-cqhttp.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -82704,7 +82621,6 @@ { "name": "itoezichtprotocol.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "itsbananas.life", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "itsecrnd.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "itsmeaxel.ovh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "itworks.agency", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ivan-popov.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ivana-models-escorts.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -83184,7 +83100,6 @@ { "name": "maxroganov.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mcpe.computer", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mcpepc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "mcpepc.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mcsfikirsanat.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "md-events.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mddetails.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -84020,7 +83935,6 @@ { "name": "smartphonefixen.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "smartplus.ae", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "smashcooper.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "smashingconf.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "smashingmagazine.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "smgl.cm", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "smilecliniq.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -86611,7 +86525,6 @@ { "name": "petrofac.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "pettreats.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "pfd-nz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "pfingstsportfest.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "pfr.email", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "pfwarriors.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "pg-forum.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -87668,7 +87581,6 @@ { "name": "culturehatti.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "customerservicepal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "customhealthplans.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "cwgadvisors.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "daganghalal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "daymail.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "dcvc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -87827,7 +87739,6 @@ { "name": "heatcheck.security", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "heerenveenlokaal.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "helhetsframtradande.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "hell.rodeo", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "helmondautoschade.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hennes-pokalshop.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "henrikjosefsson.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -87991,7 +87902,6 @@ { "name": "martdev.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "martnlab.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mascoteando.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "matemonsac.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "material.security", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "matindustrial.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "matkuling.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -88105,7 +88015,6 @@ { "name": "paycomdfw.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "paycomonline.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "peblet.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "peko.com.mk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "penrite.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "pepe.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "perdele-draperii.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -88251,7 +88160,6 @@ { "name": "sogesel.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "soillessgeek.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "solanacasinos.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "solanaroyale.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "sophiekush.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "spaceholder.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "spaceint.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -88703,7 +88611,6 @@ { "name": "opdera.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "operationlifeline.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "operationlifeline.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "opportunityfund.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "optgo.com.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "orchideemilano.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "organicindiausa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -89411,7 +89318,6 @@ { "name": "jugendpresse-hessen.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "justindianporn.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "jz.lc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "kano.fan", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "kashta-svgeorgi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "kavinchauhan.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "keralamurals.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -89447,7 +89353,6 @@ { "name": "mamacoolinar.bg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "marcheuparis.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mario420.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "masharphomecooking.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "masite.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mastodonperu.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mbrental.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -90434,7 +90339,6 @@ { "name": "nordgravite.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "nordicsemi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "northshoremums.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "novatelecom.cl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "novyzelandnamiru.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "nsepapa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "nso.li", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -90802,7 +90706,6 @@ { "name": "zozitdat.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "zq.com.sg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "zta.training", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "zzdiesel.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "10001000.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "125-rue.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "7bandarqq.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -90947,7 +90850,6 @@ { "name": "dizzidecalz.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "dksoft.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "dlg.im", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "dnhome.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "doehle-group.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "domus-rely.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "doverfcu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -91016,7 +90918,6 @@ { "name": "foreverpontiac.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "forgeary.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "formassembly.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "foundmyself.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "fqcstandard.com.tr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "france-orchidees.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "friendofpaws.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -91076,7 +90977,6 @@ { "name": "holyrosary.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "home.saxo", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hospicewise.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "hospitalcruzvermelha.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hostelio.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hyperreal.chat", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hyunbridge.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -91392,7 +91292,6 @@ { "name": "wuz.com.tw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "wzh.one", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "xayah.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "xn--80adydmce.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "xn--tftel-tom-q9a.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "yacg.asia", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "yateam.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -91753,7 +91652,6 @@ { "name": "wpsitesuccess.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "wvdn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "xn--80aacgbiy5akmx.xn--e1a4c", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "xn--80aae7aeoh.xn--p1ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "yamaken.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "yangxi.tech", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "yaslink.ir", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -92271,7 +92169,6 @@ { "name": "chorleycaninesolutions.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "christianreimold.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "cirkelinecocodesign.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "ck12.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "clicksacolas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "climeradar.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "clocklink.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -93652,7 +93549,6 @@ { "name": "connecticallc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "connectto.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "consiglidisalute.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "consuladospanama.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "convoyin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "cordalife.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "cozmerce.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -94904,7 +94800,6 @@ { "name": "advocatealliancegroup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "adwallgate.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "aegon.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "aem.com.sg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "aerialforce.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "aeroequity.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "aeron.aero", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -95753,7 +95648,6 @@ { "name": "bluecatnetworks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "bluelinestation.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "bluemarlin.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "blueport.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "bluespirit.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "blufashion.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "bluzone.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -96552,7 +96446,6 @@ { "name": "deepid.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "defectivebydesign.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "defenceiq.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "defichain.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "dejuzconsults.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "delaquila.com.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "delhi-escorts.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -96686,7 +96579,6 @@ { "name": "dmesg.sk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "dnaspaces.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "dngsnl.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "dnhome.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "dnshotel.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "dnsrevolve.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "dock.tech", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -97435,7 +97327,6 @@ { "name": "gammaboxtech.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ganneff.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "gannett-cdn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "garciacarrion.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "garco.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "garrettpopcorn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "gastepress.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -97590,7 +97481,6 @@ { "name": "gpskoordinaten.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "gradientthemes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "grand-challenge.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "grandx86.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "grannynude.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "grannypussy.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "grannypussypics.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -97820,7 +97710,6 @@ { "name": "hmshost.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hmv.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hno-arzt-thomitzek.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "hobartcorp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hobbybrauer.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hoerspielbox.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hofbraeu-muenchen.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -97830,7 +97719,6 @@ { "name": "hollywoodbios.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "holo.host", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "home24bank.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "homecreatives.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "homelaps.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "homeoperator.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "homepage-nach-preis.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -98183,7 +98071,6 @@ { "name": "it-connect.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "it-stek.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "itape.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "itcinfotech.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "itechbrand.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "itefix.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "iteracy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -99008,7 +98895,6 @@ { "name": "menterarchitects.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "menti.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mentimeter.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "meraki.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mercadocampesino.com.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "merchantsbankofindiana.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mercosuleditora.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -99524,7 +99410,6 @@ { "name": "nutriciously.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "nuvemshop.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "nvio.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "nvkc.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "nwaafund.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "nwtl.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "nxtport.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -99732,7 +99617,6 @@ { "name": "pagiamtzis.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "pahe.win", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "paho.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "paidnaija.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "paininthearsenal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "pakfactory.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "pakpedia.pk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -100307,7 +100191,6 @@ { "name": "realestates.istanbul", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "realestatestagingassociation.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "realgoods.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "realimagess.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "realityjunkies.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "realitypanel.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "realmadrid-bet1x2.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -101194,7 +101077,6 @@ { "name": "supplements101.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "supplyoutlook.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "supportlafd.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "surest.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "surgatekno.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "surpasshosting.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "surreysportspark.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -102316,7 +102198,6 @@ { "name": "xboxdynasty.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "xebecinc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "xia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "xiaomihubs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "xidax.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "xillimite.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "xilnex.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -102514,7 +102395,6 @@ { "name": "2daysmood.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "2one.one", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "365canvas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "3commas.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "3dmili.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "3sisecurity.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "401ksite.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -103028,7 +102908,6 @@ { "name": "casinoua.club", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "castit.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "catalogueau.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "catchapp.mobi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "catsmotors.com.ph", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "caw.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "cbd-world-online.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -103062,7 +102941,6 @@ { "name": "checkmk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "checknetworks.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "checkusernames.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "cheflindseyfarr.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "chelseagroton.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "chennaimetrorail.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "chesterfieldmayfair.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -103252,12 +103130,10 @@ { "name": "dature.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "daunt.link", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "davidcrousehouse.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "davidkuhls.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "davidlouisedelman.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "davidmgarvin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "davosalestax.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "dawnzine.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "dayanode.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "dblsuretybonds.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "dcso.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "dda.gov.ae", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -103716,7 +103592,6 @@ { "name": "getriebeservice-gse.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "gfleaks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "gfrevenge.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "gfxload.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ghnewslive.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ghostfiregaming.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "giaimanhacai.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -103914,7 +103789,6 @@ { "name": "ihrgluecksbringer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ii-vi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "iiinhoj.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "ikk-classic.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "iknowthatgirl.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ilgisaglik.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ilienonline.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -104740,7 +104614,6 @@ { "name": "pcfunder.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "pcminsk.by", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "pcsystem.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "pderas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "peachstateaesthetics.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "peacockn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "peaksupport.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -104825,7 +104698,6 @@ { "name": "praxis-fickenscher.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "praxis-kjpt.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "predator-league.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "prefect.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "premier-dream.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "premiumcs.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "premiumkeystore.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -104852,7 +104724,6 @@ { "name": "progroep.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "proloyalweb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "promarketingplus.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "promwad.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "propertyme.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "proserialkey.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "prosperoarts.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -105163,7 +105034,6 @@ { "name": "slizgawka.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "slushe.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "slycepay.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "smalldaymc.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "smarthalal.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "smartme.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "smartmodularhoardings.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -105523,7 +105393,6 @@ { "name": "unternehmensberater-website.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "upahminimum.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "upr.edu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "upschreven.blog", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "uptimeradar.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "usgs.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ustoy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -106121,7 +105990,6 @@ { "name": "comprajuguete.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "comunitalemargherite.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "conceptfontaines.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "condo.do", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "conferencemanager.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "conferencemanager.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "conferencemanager.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -106262,7 +106130,6 @@ { "name": "edocperso.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "edsys.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "educa.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "edusektor.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "edvan.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "eelabs.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "eeymuc.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -106282,7 +106149,6 @@ { "name": "empowered-decision.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "endcottagevets.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "enet.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "engagementlettercpa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "englesh.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "engsoyouth.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "enkolaysertifika.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -106614,7 +106480,6 @@ { "name": "jk-regeltechnik.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "joaopaulopaim.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "joaosantos.net.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "jogoshoje.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "johanna-besmier.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "johnlewis.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "join-aomori.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -107333,7 +107198,6 @@ { "name": "team-building.madrid", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "tece.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "techcareeredu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "techpressable.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "techwestsolutions.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "tedcell.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "tee-suche.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -107480,7 +107344,6 @@ { "name": "vps.tg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "vrh.net.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "vue-sur-mer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "vv066.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "w3basic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "w3i.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "waferscriber.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -107599,7 +107462,6 @@ { "name": "ammoland.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "angleline.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "anol.loan", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "aorgroup.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "aova.loan", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "aplicaciones.ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "apnic.network", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -107720,7 +107582,6 @@ { "name": "degreesofcomfort.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "degrootsteshop.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "dein.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "dengi.desa.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "desinsectisation-punaise-de-lit.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "dghyp.ag", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "diariodicucina.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -107774,7 +107635,6 @@ { "name": "expertowears.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "extremetreeandlandscape.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ezyfitdoors.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "fadhlan.web.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "famousintel.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "fasab-portcenter.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "festfabriken.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -108082,7 +107942,6 @@ { "name": "nullvoid.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "numerama.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "nyliveauctions.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "nynadynasir.co.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "nynadynasir.my.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "o11y.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "observability.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -108577,7 +108436,6 @@ { "name": "2chi1.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "2class.eu.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "3078i.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "320331.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "331977.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "33ffaaa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "33ffbbb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -109051,8 +108909,6 @@ { "name": "altes-rathaus.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "altoinsuranceagency.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ames-fzco.ae", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "amicare-france.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "amicare.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "amnathrig.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "amogus.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "analyser-mon-site.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -109085,12 +108941,10 @@ { "name": "argo.vision", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "argus01.bg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "arihantone.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "arklow.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "armsco.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "arounddeal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "arset.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "art-boeden.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "artroom-design.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "arzua.gal", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "asdfqwerty.duckdns.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "assignmenthelpservices.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -109199,7 +109053,6 @@ { "name": "btsresearch.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "bu-e.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "bucapositano.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "bugbountytip.tech", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "buildingcleaningchicago.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "buildwealth.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "burb.social", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -109286,7 +109139,6 @@ { "name": "codingame.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "comicborgs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "comitedal974.re", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "commander-seo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "communityparentsinc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "compensadosbello.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "concretepressurewashing.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -109628,7 +109480,6 @@ { "name": "florisbrunet.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "fluffy.tools", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "flyforpoints.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "flyzold.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "folwia.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "fomobremen.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "food-animall.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -110025,7 +109876,6 @@ { "name": "natviehealthcare.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "naukriresults.co.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "naxsnaps.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "nbl-forklift.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ncadc.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "neishe.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "nelswong.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -110065,7 +109915,6 @@ { "name": "o6i.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "oasis.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "occam-consulting.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "octaon.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "odeliabridal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ogon.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ohbutt.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -111089,14 +110938,12 @@ { "name": "cs2.pub", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "cs2.ren", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "csghomedesignbuild.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "ctrgc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "cubeinstallations.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "cuo.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "customer2you.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "cyberfla.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "cybersecuritydegreeguide.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "cybersecurityeducationguides.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "cybersecurityguide.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "cyberwarhq.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "cyprusivfcentre.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "cysecure.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -111556,7 +111403,6 @@ { "name": "lavadodesalascdmx.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "lawenforcementedu.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "lawyeredu.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "lazismuprovgorontalo.or.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "lbio.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "learnoutlive.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "learnwithcorne.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -111602,7 +111448,6 @@ { "name": "lrq.icu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "lschimanski.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ltn.pw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "lumencasalinghi.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "lumine.work", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "lunaluna.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "luojan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -111674,9 +111519,7 @@ { "name": "military-veteran.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "millhousen.tech", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mini-zoo.club", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "minigolf-oase.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mira.fun", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "mirekng.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mitchell.to", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mixom.by", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "miyazakian.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -111990,7 +111833,6 @@ { "name": "salunganogroup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "samanhatami.ir", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "sammich.social", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "samsepi0l.ovh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "samsung-easydrivers.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "samy.rip", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "sand-bleibt.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -112020,7 +111862,6 @@ { "name": "serenaweb.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "serializacion.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "servpress.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "seucurioso.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "sf-kurzgeschichten.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "sfdchub.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "shamesofhungary.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -112059,7 +111900,6 @@ { "name": "socialmediadisruption.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "socialworkdegrees.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "sohanman.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "sokaksepeti.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "solechuva.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "solidgroundchiro.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "soliver-group.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -112133,7 +111973,6 @@ { "name": "technikplanet.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "techno-utopia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "techramer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "techvaz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "tecob.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "tectas.co.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "teedinsiam.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -112276,7 +112115,6 @@ { "name": "xn--naade-dta.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "xpews.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "xuan-hao.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "xzib.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "yaballe.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "yapper.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "yarmarka-megamarket.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -112307,6 +112145,2290 @@ { "name": "zukunftswege.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "zypernreisen.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "zyphorq.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "0066.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "011631.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "013458.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "026637.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "027862.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "029637.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "042230.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "057180.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "066630.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "083321.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "083326.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "083329.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "084709.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "086486.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "090136.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "091630.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "097712.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "0x7d7b.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "100sovetov.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "100time.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "10218g.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "10218h.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "10218i.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "1037thefoxrocks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "1040taxfirm.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "11it.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "1200.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "123womenslife.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "128012.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "128612.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "132813.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "149481.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "1650thefan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "186588.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "1bk.ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "1bk.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "1opochkah.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "1profile.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "1zwolle.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "200mmx.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "207708.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "208930.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "22-gradusa.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "2211.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "221791.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "22hd.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "240786.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "244821.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "24hrbrandbash.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "24x7aircargoservices.co.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "2500.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "259454.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "261082.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "275004.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "285128.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "288628.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "2diets.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "2jtech.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "2manydits.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "2nodez.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "30daystosoc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "314257.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "319064.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "329.im", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "342960.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "360degreecloud.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "363418.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "369bin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "371437.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "374161.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "375realty.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "3800.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "3niu010.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "3niu161.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "3niu186.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "3niu226.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "3niu24.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "3niu282.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "3niu353.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "3niu51.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "3niu57.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "3niu599.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "3niu67.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "3niu699.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "3niu72.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "3niu885.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "3tiers.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "404.pw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "409564.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "4100.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "413504.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "4222.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "42bit.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "4333.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "439182.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "452895.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "455555.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "489491.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "491783.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "497891.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "4chairs.bg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "4gtrackers.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "4hourmini.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "51357.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "550885.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "555554.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "5611.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "5677.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "582303.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "608854.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "620862.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "626562.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "628062.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "628462.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "637663.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "656265.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "679470.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "683168.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "683968.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "689368.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "698134.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "702341.win", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "702342.win", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "702343.win", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "702344.win", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "702345.win", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "703700.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "709644.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "725134.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "732959.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "736416.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "746104.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "7478vip1.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "7478vip2.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "783306.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "7dies.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "7sotok.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "803970.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "80thcork.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "817181.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "829917.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "830891.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "831783.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "835183.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "836436.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "867104.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "872787.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "877287.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "87738cp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "9118cp.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "918991a.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "918991b.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "918991c.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "918991d.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "918991dhz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "918991e.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "919391.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "921892.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "924592.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "928092.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "929592.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "932993.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "935themix.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "937093.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "938193.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "9412220.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "951thebull.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "987kisscountry.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "999003.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "999004.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "999005.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "999006.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "999008.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "9993358.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "99perf.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "9etl.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "9tl.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "aahhbali.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "abcideabased.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "abdulraheem.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "abdulraheemalick.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "abirmas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "abogadosviolenciagenero.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "abraofilho.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "absolutepackaging.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "abstractive.ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "acacia-education.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "accessauto.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "acd-c.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "acht-pfade.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "achtpfade.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "acidtool.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ackermannevents.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "acnenaturalhealing.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "acobex.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "acraftedpassion.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "act-web-sa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "activosenlaweb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "adacomputerscience.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "adaeze-wolf.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "addictless.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "adndigital.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "adt.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "advancedridertraining.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "adventuredental.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "adventuretoursbend.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "advritujeph.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "affordableasphaltcompany.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "agadir24.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "agenciazoe.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "aginion.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "agro-portal.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "agurskie-vodopadi.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "agvlectoure.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ahmt.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ahmu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "aipixel.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "airstop.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "airtrafficcontrol.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "aistdent.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ajiloot.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ak-wohnen.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "akaike.co.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "akaremavideos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "akashi-kiharu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "akashiya-b.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "akemisp.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "aktelectric.com.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "alcogolizmstop.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "alexdelpiero.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "algbra.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "aline-cannabis.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "alisonswindles.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "allfansleak.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "allforcreate.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "allgreenlawncare.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "alliedartistswv.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "allxon.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "almarin.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "alonlevinart.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "alp-eastlink-portal-model.azurewebsites.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "alp-samsungca-portal-model.azurewebsites.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "alp-spectrum-portal-model.azurewebsites.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "alpa.social", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "alt-bookings.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "altenagala.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "aluminaty.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "amaris-pr.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "amateku.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ambasador-dibo.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "amdiving.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "americanfan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "americanwalkincoolers.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "amicus-webdesign.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "amigodepets.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ampflower.gay", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "amz-tas.ba", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "anaricompras.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "andobil.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "androidtorrent.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "andysroom.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "angelguerrerotech.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "angstakademie.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "anshlag.co.il", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "anti-ddos.group", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "antikpest.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "apaesthetics.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "apix.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "apixmessaging.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "apkclup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "aplusz.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "app-alp-cp-boost-model.azurewebsites.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "app.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "appliancerepairtime.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "applicablesecurity.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "apthesys.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "archion.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "architecturequebec.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "arcolasecurities.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "arenaforum.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "aresico.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "argxentakato.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ariensfoundation.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "armadale.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "armateursderhum.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "armorguides.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "arqandes.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "art-athens.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "artificialdiffusion.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "artisanhd.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "artisanity.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "artsmagazine.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "arturkraak.duckdns.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "arviamedspa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "as200351.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "asco.com.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "asecla.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "aseityresearch.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ashishchamoli.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "asiaround.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "assamecareer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "astleyplumbing.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "astonbysqli.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "astro22.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "atletismosudamericano.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "atmospheremarketingwy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "atproducts.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "atticlightstudio.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "august.tw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "autantic.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "autoambulanza.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "automaticmsp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "automation-tools.stream", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "autorabit.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "aux-bonnes-affaires-by-alf.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "avalonartstudio.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "avantagetaxi.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "aventure-chasse-peche.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "avounossoupes.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "avtoritet78.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "avtorspb.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "awwwcats.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "axitech.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ayhanotomotiv.com.tr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "azure-informatique.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "b1031.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "b11p.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "baang.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "babamamatermek.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "backslash-n.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "baithuti.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bakesy.shop", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "balogkrisztian.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bandaancha.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bandolino-bewind.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bandtcollections.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bangsparks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "banki-finance-credit.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "banyarukami.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "barcotrucks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "barhan-sarykum.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "barnumiidev.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "baronessonenotaryservices.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "barreiroappraisals.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "based.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "baskideposu.com.tr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bclserver.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bconcept.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bcs-talk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bcsnygroup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bdasites.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bdeducator.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bealeslandscaping.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "beargorilla.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bedsoon.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "beeming.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "beeportfolio.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "beginnercampingguide.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "behomewithlove.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bellastate.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "benemortasia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bentcreekfarm.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bernd-ungerer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestgardener.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestjigsawreview.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestsidelka.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestvape.ie", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "betnation.win", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "beworksite.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bewustwinkelen.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "beyoursell.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bgp.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "biaccountancy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "biancavandenberg.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "biblicalbeliefs.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bidbuy.co.kr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bigband-a.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "biggive.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bigideachallenge.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bigudi.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "billiard-group.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "binnacle.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bio-dolt-aveyron.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "biologymusicvideos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "biotorrents.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "biserica-antiohia.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bitcoinforthe.lol", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bitga.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bitkiselreyonum.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "biznotes.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "blackbirdsigns.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "blake-thickbroom.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "blistertrackandtrace.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "blockstream.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "blogstrend.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "blueplanet.social", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "blueprintsdogstudio.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "blueprotocol-cn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "blueridgemachinery.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bmskibaru.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bnssigns.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "boardgameshots.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bodies.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "boesckens.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bointon.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bolognatsrmpstrp.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bookmysplash.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bootsy.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "boraarat.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "borsa2k.com.tr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "boutique-pcland.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bovileva.com.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "boxiruem.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "boxlegal.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "boxofficefunding.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bramstonbeach.org.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "branaher.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "branchchristianschool.org.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "brandmixer.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "brandwatchmail.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bregmanfance.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "brewcentralny.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "brgsmartcity.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "briggsandlittle.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "brightmovers.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "britanniawellness.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "britishftv.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "broadstreetalerts.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "brocos.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "brokerageservicesinc.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bruyerre.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bs09.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bsid-clan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "buchelstore.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "buddobot.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "buenosairesconnect.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bufeteesquire.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "buharkeyf1.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "burg-esslingen.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "business-network.or.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bustepaga.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "butenhofbomster.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "buybitmain.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "buzzclub.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "buzzeditora.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bzfit.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "caetanotec.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cagalogluhamami.com.tr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "callanetica.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "callum.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "callummoore.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "caluette.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "calumcrawford.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cambiata.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "camelia.bg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "campamerika.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "camping-everywhere.fun", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "campsite-explorer.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "campuscom.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "canae.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cankutahya.com.tr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "canvaspersonalized.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "canyon-psaho.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cardmates.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cardmates.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "carecm.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cargotransinfo.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cars-project.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cats-dom.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cavsusa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ccbccc.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cdsfinancial.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cdt.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cec.org.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cedricpim.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cellnatsci.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "center-strategy.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "centrselstroy.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cerbos.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "certificationacademy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "certiquali.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cfvbfbtlotto.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "chainataun.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "charlottejulienne.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "charmpets.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "chasalin.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "chatbo.ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "chatcontrol.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "chatgptwith.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "chatrisityodtong.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "chessmatesny.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "chessresult.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "chessustron.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "chiesanuova.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "chillcicada.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "chinamallonlin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "chistim.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "chooserealleather.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "chopper-parts.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "christinasattler.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "christthegoodshepherd.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cincydeckandpatio.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cinet.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "citharas.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "classcreator.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cleanweb.solutions", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cleanzer.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "clear-eyes.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "clickapro.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "clickforspeed.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "clicktheright.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "clinic-narcom.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cloverleafmoving.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "clown-workshop.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "clubtraining.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cmrcustomcreations.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cmrnw.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cmveraopersonalizados.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "coalanews.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "coastalmotorcoach.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "coastsport.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cobitis.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cochranwriting.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cod4mw.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "codeprotocols.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "coduca88.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "coffeechi.ir", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "coffeeruta.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cointofreedom.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cok.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "colchesterglobal.co.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "colchesterglobal.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "collegegirlsmarts.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "coloffmedia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "colonialfilings.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "colonialmanufacturing.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "coloradosportsofficials.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "colorfulworld.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "com.com.tr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "comm-chat.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "commuty.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "completecomps.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "completeonlinepharmacy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "comptoirducycle.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "comwwwcomcom.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "connyandthecrazydogs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "consejoescolardecanarias.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "consolemania.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "consultaveiculopelaplaca.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "coor.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "corentin-et-rosalie.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cors-amenagement.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "courstoujours.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "couteauxsurvie.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "covechat.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "covid19elite.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cpme-industrial.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "craftandart.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "craftarea.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "craftart.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "craftmenu.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "craftportal.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "craftzone.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "crashinc.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cratitadelicioasa.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "creative2.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "creativeground.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "creativescastle.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "creatuasociacion.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "credit-mgmt.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "creditsummerevent.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "credot.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "crepaway.com.ng", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "criaraposta.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cridigital.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "crimewatchus.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "crimsh.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "crossroadsdentalgroup.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cryo-fit.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cryosite.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "crystalprinting.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cs2.chat", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cs2.net.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "csc-muenchen.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cscholz.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cswatch.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ctafo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cubistmediagroup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "curationsblog.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cureforlife.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "curiousduck.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "currytech.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cursoauxiliarveterinariaonline.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cursodeauxiliardefarmaciaonline.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cw3.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cyberalternance.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cybercic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cyberresilience.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cyraco.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "czihak.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "d-influencers.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dacgroup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dachnie-reshenia.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dachnyvopros.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "daer.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dagestan-guide.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "daisydollyandme-dev.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "daisydollyandme.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dajaskincare.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dallincooper.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dan-saba.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dani-ward.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "danmakus.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "darkbit.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "datavoiceoptions.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dati.plus", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "davesasphalt.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "davidczihak.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "daviddesberg.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "davinciwaldorfschool.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "daycomtech.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dayekelly.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "daynightdrugs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "daytonpcrepair.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dbs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dbs.com.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dbs.com.hk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dbs.com.tw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dbs.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dcmeventmanagement.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dcustody.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "deanvending.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "decompressneuroma.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "deepbuy.tech", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "def-pos.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "deisedigital.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dejon-whirlpools.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dekordrop.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "delphij.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "delrayengineering.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "deltasul.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "deltavite.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "deltawolf.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dentalunion.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "deshalb.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "detdom-48.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "devdiggers.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "devicenow.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dewitt-associates.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dexon.ws", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dezinsekcija.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dg-komm.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dhpdq.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "diagnostics.stream", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "diamondcarpetcleaning.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "diankpi.ws", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "diegott.ddns.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "diggerlandusa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "digimortals.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "digital-vorwaerts.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "directadmin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "directions.ee", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "distriwan.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "divinaoracion.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "divinglive.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "diy-projects.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "diyportal.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "diyzone.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "djthibodeau.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dm-0.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dmu.ac.ae", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dnevnichok.club", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "doclures.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "docugate.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "document-translation-nationwide.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dogsport.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dogtrainingnaples.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dommaster.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "domokode.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "donedeal.ie", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "donghuapiandaquan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "donkerslootjes.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "doriansgypsylife.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "downthebayoucharters.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "downtoearthjewelry.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dqcertificaciones.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "drawingdownthemoon.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "drbarryapplegate.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "drblend.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dreamesportsindia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "drinksontap.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "driventheatre.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "drivewaymaintenance.repair", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "drpush.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "drtanyaescobedo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "drtragency.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "drybms.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dtdi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dtsdschoolboard.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dubaiaward.link", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dvd.wtf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dvds.casa", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dyma.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "e-goi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "e-networks.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "e-petition-support-us.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "e-petition.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "e4mc.link", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eaglesightproperties.tech", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "earthvoice.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ease.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "easternbreezes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "easternskatesupply.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eastleigh.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eca.nb.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ece-inc.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ecenglishlive.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "echipamente-protectie.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "echovintage.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "echt.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "echtcache.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ecoeat.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ecomgigs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ecopy.ir", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ecostroika.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ecosuds.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ecsafety.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "edudip-next.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "edudip.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "edudip.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "effectiveconsulting.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "egitimpusulam.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "egotickets.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "egypt-turism.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eikoh.nsw.edu.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eine-domain-ist-wichtig.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ekranoplan-lun.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "elcient.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "electro.moe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "elektromosev.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "elektron-elektrotechnik.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "elektroniksigarasehri1.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "elemanpersonelalimi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "elephant-orchestra.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "elephant-orchestra.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "elephantorchestra.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "elit-logistic.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "elitedns.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "elitemdsupply.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "elitewealth.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ellevate.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "elliotlewisms.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "elsassdestination.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eminencepools.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "emkan-furniture.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "empatify.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "emurom.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "enattendantpauline.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "encore.tech", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "endlessgrind.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "endustriyelmutfak.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "energetic.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "energoset-spb.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "energy-transporter.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "entruempelung-berlin.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "enviroli.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "enviroli.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "enviroli.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "enviroli.li", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "enviroli.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "enviroli.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eos-utility.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "epicawesomemods.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "equans-kaelte.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "equisa-verpackung.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "erasinged.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ersei.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "esburgos.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "escortes.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "escriva.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eslutt.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "essexgardenstudios.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "estetica-bilbao.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "estimateone.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "estradatech.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "estudiojuridicovyv.cl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "et.gd", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "etigold.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "etterretningstjenesten.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "europatrans.com.tr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "euroskulpa.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eurotechme.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "evdenevenakliyatistanbul.gen.tr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "everdivemarine.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "evergreenservice.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "everride.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eviltwins.studio", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "evolve-mma.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "evolve-university.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "evolve-vacation.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "exabike.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "exceptionalfirm.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "exdomo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "exodus-net.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "expertcomics.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "expertembeleza.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "explorerdispatch.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "expressivee.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "extensions-chrome.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ezekia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ezoterizm.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fabim.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "faceblock.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "faces4watch.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "factorchave.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fairwayhomebuyers.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "faithriders.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "famschaefer.ddns.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fanart.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fancars.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fatih-catering.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fedifeed.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fedistatus.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fedupwithliberals.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "feelgoodcasino.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "feezlinkz.com.ng", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "feikuai.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fencethisyard.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ferhatsurer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fesne.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fezbet.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fh-jituan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fijneboeken.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fileport.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "filmovka.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "filmzwesela.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "finalesuperuser.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "finanzen-az.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "firstlegal.group", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "firstperformance.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fisio-clinics.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fisioterapia-online.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fisvo.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fit-portal.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fitnessupreme.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fitotovar.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fitrospective.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fiyatgraf.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fjkl.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fl-catering.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "flareweb.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fleetlinkatlascopco.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "flipnhotdeals.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "floreal.site", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "flosuretechnologies.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "flowerstopetersburg.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "floyt.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "flugrueckerstattung.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "flyforsinkelse.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "flyforsinkelser.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "flygforsening.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fnlcontent.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "focored.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "focuscomic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "focusti.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "followpharma.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "foottube.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "forgetfulmomma.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "forixcommerce.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "form100.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "formation.tech", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "foro.trading", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "forsvarsmakten.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "foryoumer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "foutras.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "foxbox.moe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "foxholehq.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "foxus.lt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "frances8.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "frankmungoattorney.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "frederictonrealestate.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fredtalk.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "freedomaircharters.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "freenft.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "freight-news.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "friendsonline.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "frogeducation.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "froginfra.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "froglms.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "frogos.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "frogplay.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "frogtest.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fspk.shop", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ftmyersdogtraining.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ftpporto.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "full-hd.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fundex.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "funraiser.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "futureimmigration.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fxcm-markets.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fxcm-online.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fxcm.com.tw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fxcm.com.vn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fxcmaffiliates.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fy.ink", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fyrebox.guru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "g-dart.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "g15ubezpieczenia.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "g5yss.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gabskent.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gabz.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gadgetgazette.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "galia.bg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gametainment.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "garage042.bg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gardenwildflowerhunt.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gardurialuminiuiasi.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "garip.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "geekelectronico.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "geropa.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gesnerfigueiredo.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gesundheit-ifg-muenchen.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "getboomerangwater.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gfsolucoesdigitais.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gfsolucoesdigitais.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gge16.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ghafatzayed.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gibsonmemorial.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ginzago.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "girlschandigarh.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "girlswhonerd.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gitelermitage.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "glase.shop", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gloryhealthcarellc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "glucometros.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "go-sprout.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gobeline.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gocct.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "going.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gojoebean.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "golfedumorbihan56.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "golootlo.pk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "goodearth.com.tw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "goodtimesrvsales.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "goringdogsitting.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gospelnarrative.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gpstrackersaustralia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gptscdn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gracealexwatch.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gracereminder.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "grafphoto.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "granigroup.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "graphicinfo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "graphicps.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gravely-dealers.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "greatdanemowers.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "greenfunder.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "greenmonkeydesignstudio.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "greymuzzlemanor.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "grillboxtaxi.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gritsany.hopto.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "grovefinancialgroup.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "groveland.place", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "groweb.design", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "growers.social", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "growitsecure.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "grupolegalsgf.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gruzmt.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "guardianangelportraits.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gurutraveltraining.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gyro.com.tr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ha34.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "habnubis.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hackedthe.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "halterner-tc.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "halv.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "handicap-job.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hannagroup.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "harappahomes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "harmonyroomspa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "harrisrealestate.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "harzlaender.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hasel.news", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hastingsapplianceservice.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hasx.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hatakekaigi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "haulpackaging.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hausmann-versorgungstechnik.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hausresidential.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hayalgucu.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hayvid.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hba1crechner.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hdatraining.ma", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hdredtubeporns.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hdrip.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "headwall-hosting.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healmaster.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthhair.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthyoptions4me.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "heartwork.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "heavenlylanka.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hedefkompresor.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hedonisticimperative.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hedweb.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hefty.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hekatija.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "helena-loos.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "helia.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hellocash.business", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "helpwiki.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hemmersbach.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "henrik-sachse.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "henriksachse.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "henriksachse.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "her123.win", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "heracasinos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "herbariaunited.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "heshamelsawah.clinic", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hexusmigration.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hey.pw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "heyblogging.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "higsegeirl.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hiiumeretuulepark.ee", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "himmi.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hinatayamagolf.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hithai.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hmgym.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "holisticinnovationdental.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "holisticzen.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "holzbau-lepski.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedizz.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homesense.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hondaindiafoundation.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "honkai.sr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "horwood.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "horyawatch.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hotheart.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hotpinkbraces.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hotprintind.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hsbuild.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "huangban.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "huepfburggiessen.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hushhush.store", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hydrozen.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hylark.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hypernet.co.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "i-stream2watch.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "i1430.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "iadminify.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "iamlearning.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ibei.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "icnsk.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "iconique-menuiserie.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "idealni-hypoteka.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "identity.aero", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ihersua.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ijianli.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ikara.social", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ikoreg.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "iksworld.kr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ila.tw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "illuminated-security.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ilussao.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "imbri.tech", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "img.cm", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "imidge.com.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "imosthailand.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "imperiodeleones.cl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "imyupi.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "inboxxme.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "inchirierepatinoar.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "increyble.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "independent-photo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "indexbase.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "indi.market", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "indianrelaypodcast.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "indigterms.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "inferencium.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "infinan.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "infiniteserieslabs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "influentsolutions.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "info-thailand.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "infouspekh.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ingrain-ed.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "innovativetrials.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "inputdriven.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "instantinsightinc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "insyde.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "insydesw.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "int-refer.nhs.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "integralabstudio.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "internationaldesigncomp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "intosec.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "invisionretail.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "iogamers.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "iovo.consulting", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "iowacorncountry.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ioxio-showroom.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "irakturkleri.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "irbot.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "irlpack.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "irweb.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ishtamar.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "islasvirgenes.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "islide-powerpoint.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "isowebtech.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "istevitrin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "italianettepizza.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "iternova.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ith-heerlen.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "itninja.one", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "itradeit.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "itsecboecker.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ivansgroups.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ivn999.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jaajko.me.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jagsttalschule.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jamestgh.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jamestilburg.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jaott.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "japico.or.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jatekjatek.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jaykuhns.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jeepspares.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jesen.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jessetorrenga.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jimbeam-welcomesessions.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jjphotographyia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "johannabest.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jordanwd.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "joshcaluette.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "josie.boutique", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jotoma.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jsn.one", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jstanleyasphaltpaving.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jtxmail.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jugoncalv.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "julien-noyelle.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "july52.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "justbydesign.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "k-amenix.co.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "k29.ee", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kaida-rybak.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kaizendigitalstudios.live", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kallanda.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kamienie-migdalkowe.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kampanyaradar.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "karaj.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "karolinamed.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kasanikares.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kassa24.kz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kassianoff.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "katlaniryatakci.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kawandegroup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kazvet.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kcfiradio.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kchanews.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kemian.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kensingtonsqca.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kerkukkitapcisi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kidderminster.ac.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kijkmeaanwanneerik.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kikikanri.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "killeenhardware.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kinamedia.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kindcompany.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kinderchirurgie-muenchen.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kiow.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kishenya.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kita.moe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kkpig.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "klempin.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "klempin.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kloudstack.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kmch.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kmhesaplama.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kondi-flex.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kondi-flex.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kondiflex.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kondiflex.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "koningsdag-arnhem.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "koppbilling.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kopsinc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kotydomowe.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kozmetikatrend.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kredibanka.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ksato.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kupidon-rt.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kupon-proxy6.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kutyamacskashop.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kysepticservice.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lacounty.homes", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ladislav-antos.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "laisk.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lakecity-obgyn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lalicence.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lanconstruct.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "landshaftnic.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lansdell.family", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lapari.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "laptoppowerjackinc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "larcaenviro.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lasalle.org.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lasanious.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lasinfusiones.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "laslo-hauschild.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lathamwatkinsplatform.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lavish.co.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "layt.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lazell.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lazell.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lazynap.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lbbw-markets.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lcistit.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "leafandanchorco.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lear.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "leasing.my", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "leblogdumineur.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lechoppe-parisienne.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lekasedgar.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lemieuxbedard.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lemitron.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "leptitbaltar.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lerks.blog", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "leskei.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lesparqueteurs.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lesrivesdegaronne.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lestudiopecot.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "letyro.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "levati.name", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lexeri.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lfg.com.ph", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lgelectric.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "librairiez.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "licesisters.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lifeinheart.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lifelinespublishing.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lillenordmann.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "linkgiamgia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "liquidcorp.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "listehub.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "liteanalytics.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "littlegianttraveler.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "livepodcast.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "livingislands.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "livingislands.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lizhuan.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lkmt.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lobbster.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lockdownfm.live", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lockemower.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "logue.media", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lojasvirtuaisesites.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "londonwomensclinic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "longlh.vn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "losangelescarpetcleaning.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lospadillas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lostfilm-tv.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lotusdiving.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lotushouse.yoga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "loveasiangroup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lovelandelec.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "loveuno.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lqy.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "luijken-naturephotography.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lukeswiki.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lunguflorin.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "luxinfine.su", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lvkasz.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lx-is.lu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ly-nux.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lycan-fitness.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "madeitstick.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "madetosave.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "madou278.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "maialeechin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mailia.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "maitum.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "makingbusinessmatter.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "maltarugs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mamkin-wp.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "manab-it.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "manausagil.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "manitobapropertybuyers.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "manrollo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "marczocher.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "marilynandsarah.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mark07.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "marshalls.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "martinenrique.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mashine-art.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "massagepraktijkamyklappe.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mast-jaegermeister.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "masterproseo.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "masterpsylogos.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mastersservices.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "masterurist.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "matchmove.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mathsensical.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "matreon.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "matsson.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mattpeterson.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "maxair-systems.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "may-tree.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mbdou50.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mbr.moe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mccarthyprestige.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mcirculo.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mcost.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mdangels.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "med-banki.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "medbankishop.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mediametrix.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "medicimaging.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "medievalexpert.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "meditationsydney.org.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "medlink.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "medycznyangielski.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "meesman.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "meetcleo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "meinbuild.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mejpbs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mending.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mentesperfectas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mentrixpill.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "merisia.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mesquitelandscapeservices.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "metacred.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "metaformarketing.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "metalarea.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "method.cl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "methodist.com.tr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "meusucesso.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mf.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mhastey.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "michiganfthb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mickaelbonnard.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "midesa.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "midesa.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "midwestdfe.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "midwestragdolls.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "midwifeschooling.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mijndiad.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mijnstembureau-amsterdam.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mikelawson.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "milmmed.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "min2.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mindmynature.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mindscapephotos.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mirogrdnika.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "missourivalleyhomes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "miyohiro.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mkbofficeshop.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mlclaw.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mobilci.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mobile-master.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mobile-pedia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mobilemondayaustin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mobilephoneadvise.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "modforward.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "moemdom.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "moin.solar", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "moneydecadadia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "moodyfss.marketing", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "moonlanders.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "moonproject.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "motorparts-online.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "motorviet.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "motostyle.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mountainspiritinn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "movavi.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "moveme.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "moy-ogorod.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "moy-urozhay.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "moyogorod.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mpfront.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mpi-sws.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "msn.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "msnedu.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mt1130.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mtlebanonbaptist.church", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mudrex.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mulchexpressusa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "multisportaustralia.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mundofriki.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "muonmarketing.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mustangapparel.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mustardinkstudios.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "muzcomedia.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mvpzd.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "my-darkon.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "my-meal.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "my-pharmacie.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mybro.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mybudgetapp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mydx.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "myflightrefund.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "myowntutor.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mypocketai.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "myreferral.systems", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mystex.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mysticalroseschoolofcaloocan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mytamarin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mzplumber.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nadache.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "naine.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nalanyinyun.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "naseong.kim", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nashsovetik.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nathalie-guillaumin.coach", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "natualsmoke.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "naturallyuncommon.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "natureshealthandbody.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nbaac.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nbao.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nbaot.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nbapc.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nbios.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ncbham.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nccny.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ndigen.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nedemek.com.tr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nelebaehre.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "neonbutik.com.tr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nerotv.live", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nesev.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "netcake.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "netcitycheb.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "netco-group.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "netco-solution.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "netco-system.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "netmt.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nettoptangida.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "neuca.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "neurojournal.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "newsportbox.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "newwavelinen.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nextgenerationaccessories.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nextgenerationaccessories.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nextgenerationaccessories.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nextgenerationaccessories.store", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nexttune.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ngbilling.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nhacthanhcavietnam.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nhk-nbs.co.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nhr.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nickmazuk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nicolelaby.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nicolettapallotta.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ninjacosmico.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "niro.bio", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nirvel-shop.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "njmd.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nkbi.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nonslipdeckingco.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "norcalworkcomp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "normanhurstldc.nsw.edu.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "northernwolf.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "northiowatractorride.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "northstarmodular.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nostrum.ee", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "notactivelylooking.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nottwo.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nowoe.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nuraling.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nutra.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nxdomain.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nyeclipse.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "o2fitnes.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "obesidadenmallorca.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "obmax.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ocbc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "oceanearth.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "octodex.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "oddsseeker.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "oemparcacim.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "offbeatbeats.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "og-chemistry.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ogorodnik.guru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ogorodoved.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "oksichemk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "oldhousetonewhome.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "olivier-verbois.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "olofly.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ommam.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "oneclick.accountant", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "onefocusapp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "onegeeks.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ongoal.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "online-concepts.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "online.forum", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "onlinehypermarket.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "onlstreet.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "open-greenenergy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "open-procurement.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "openagenda.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "opensecurity.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "operalogg.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "opioids.wiki", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "opsbase.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "optigear.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "optimizedbyalex.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "optiwebopz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "optykgill.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ord-airportparking.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "origent.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ormuratore.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "orthoprax.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "oruzjeonline.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "osoo.kg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ostalb.social", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "oth666.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "oukasou.moe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "oukasou.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "outdoorphoto.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "outofthefog.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "outtask.ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "outworking.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ovalterfurtado.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "owenet.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "oxylabs-china.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ozero-kardyvach.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "p3medicalinc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "p99perf.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "p99performance.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "paardenfotografie-nederland.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pacem.global", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pacemigration.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pacificislander.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pacificstates.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pack1537.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pagespeedwizard.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "paine.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pak-kazan.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "palau-pizza.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "palkhifashion.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pana4ucloud.ddns.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pancake-world.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pandillatel.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "panhandleprairiewings.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pantonshire.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "paparoach-fans.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "papinido4ki.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "paradise-villa.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "paragliding-lessons.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "paramloda.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "parchmentdownunder.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "parfums4u.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "paridurable.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "parkeerzeker.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "parkplus.in.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "parktraum.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "partiellkorrekt.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "partigoldendoodle.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "partsandscore.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "passbypointer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pat3dx.shop", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "patent-sternika.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "patient.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pauljamesblinds.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pc-pharma.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pc-reanimator.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pcland.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pcnetinc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pdfchef.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "peifeng.li", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pelinca.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pennylane.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pensierolaterale.tech", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "penultimategaming.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "perfect-seo.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "performansguru.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "personabrindesbr.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "peruutetutlennot.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "peshakoo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "petsmundoanimal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pfandbriefe.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pha.one", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "philhugo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "phonex.com.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "phormulagroup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "phqsoft.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "phwoarbeauty.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "physicalmedicineandrehab.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "physio-nrj.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pianopronto.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "picalendar.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "piifunding.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pinedahair.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pingpongsourcing.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pinoyequalizer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pintiaktivasyon.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "piratepcs.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pittsburghhiresveterans.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pixelpaper.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pixicom.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "plai.gov.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "plantalert.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "plantepakken.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "plasmatrap.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "plasticonion.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "plumefox.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "plumsail.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pochikikaku.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pochkiguru.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "podcastpulse.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "poleznie-soveti.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "policyhub.gov.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pollock.gallery", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "portcomputingsolutions.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "portofsubs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "portraitcameos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "posa.moe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "potatosoft.kr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "potencial-school.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pourali.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "power-plugins.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "power-recovery.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "powerfulcom.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "powerhouse.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pozaapteczny.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ppsltd.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ppter8.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pracovita.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pranavida.cl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "prauxilium.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "praxisamziegetsberg.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "premier-hub.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "premier-mag.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "premierflmagazine.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "premiumusedautoparts.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "press.lv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pressurewashingchicago.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pricesmax.com.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "prillwitzgroup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "primsports.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "princewen.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "prio.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "privacydev.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pro-babochek.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pro-ogorod.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "proadvisorcoach.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "proamis-moodle.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "processtec.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "prochaj.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "procountor.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "procountor.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "productionsinc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "professionalfinance.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "professorart.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "profilepk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "profor.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "progres.construction", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "project-alice.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "project-trans.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "projectresidence.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "prolobziki.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "prologicabg.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "prototypofablab.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "psaho.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pskhu-wedding.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "psychistory.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "psychotropical.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "psyhoslovar.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pub-med.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "publis.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pujcky.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pulsestaffingllc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pulsus.mobi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "punchequipment.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "qcdjco.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "qeddi.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "qform.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "qfurs.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "qitabbs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "qpipi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "qualityroofingservices.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "quatdientico.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "qzr.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "raassembly.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rabbithash.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rabbitserverlist.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "radicaltransformationproject.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "radio.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "railsperformance.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rainbowstars.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ralum.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ran-ran.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "randomforestweb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rarous.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rattanhousecarpentry.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rawballs.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rawmonolife.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rayonbricolage.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rc-refer.nhs.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rcelectronica.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "receitasfavoritas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rectoverso61.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "redehiperfarma.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "reehomes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "reel360.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "reelchicago.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "reelobsessionwi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "referko.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "reflab.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "regalfille.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "regiaodeaveiro.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "reisbergadr.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "reja.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "reliablecanadianpharmacy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "reliablepi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "renewedhr.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "repairpoint.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rercel.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rette-ein-kinderleben.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "reusesti.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "revechat.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "reverce.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "reviewspotly.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rhyswebbmassage.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ricelasvegas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rickmanlegal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ridho.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rightstartcapital.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rightstartent.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rightstartinc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rikki.moe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rikmeijer.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "riosat.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ripplenews.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rivervista-vacationhomes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rjclegeplads.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rmbnsw.org.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rmw-energy.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rnp.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rodpenroseracing.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rogerfages-peinture.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rogplus.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "roguetech.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "romana.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "romerska-ringar.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rosevillekindy.nsw.edu.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rossdak.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rottig.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "routage.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "roverkob.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "royship.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rpgfan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rpnt.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rtebensoc.ie", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rubonnek.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rugbyrama.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rukiyegarip.art", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ruspolik.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "russianbridge.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "russpuss.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rustdesk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rzsmt.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "s-zwrm.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sa-refer.nhs.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "saaral.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "saboresdamontanha.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "safehousepestcontrol.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "safewatchsecurity.ie", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "safinamide.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "saidigi.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "saintgabrielparish.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "saintjamestheapostle.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sakirdak.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "salesdock.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "salesdock.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "salesdock.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "salva.ovh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "salvageforgood.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "salz-und-sinn.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "same.lol", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sammich.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sampath.lk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "samroelants.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "samuelharmon.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sanche.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sancpa.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sanfordguide.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sansdb.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "santarosasegurapp.gov.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "santomospb.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sarahbowling.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "saraskins.space", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sareena.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sausagefesttravel.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "savingmoses.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sba7a.loans", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sbspp.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "schaumburg-dachundwand.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "scheidegger-kaesealpe.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "schipholwatch.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sclasupplychain.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "scottishbotanistsconference.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "scottsdaleaz.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "scottsfreightshipping.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "scpsecretlab.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sdesam.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "seaif.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sebastian-elisa-pfeifer.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "secretdoorsa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "seecat.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "segurancati.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "seitokai.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sekretiki.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sellerwiz.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "selokids.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "seo-tools4u.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "seoptimize.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "seozen.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "seozen.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "seresco.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "servicemasterlawncare.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sevenseasmarble.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "seventymania.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sexosintabues30.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sextw.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sfnetwork.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sfoks33.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sgnation.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shafa.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shan.sg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shanwong.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shanwong.design", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sharaf.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sharona.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sheepymeh.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shiftfrequency.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shilvister.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shiptest.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shkola-95.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shochufes.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shoesandmorebdn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shoppsb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shutts.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shw-bw.dyndns.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shw-nc.dyndns.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shw-rz.dyndns.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sib-taxi.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sideofburritos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sideofburritos.social", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sidrabitkisel.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "simon-templar.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "simplifyingcollege.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "simply-bob.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "simply-pdf.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sizinajans.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "skachat-filmi.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "skatrey.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "skillup.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "skinmedshop.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "skiptontownhall.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "skolplattformen.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sks.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "skyrider.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "slaght.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "smallbatchclay.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "smaltimentocalcinacci.roma.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "smartchezvous.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "smartphone.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "smartzonemikulov.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "smereka.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "smileofindia.co.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "smrtgeekdevs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sniffnfetch.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "snippetpress.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sno-tek.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "snotekbyariens.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "socblock.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "socious.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "solifi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "something.pink", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "somevideotapes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sorellinteriors.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sos-brigade.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sovet4ik.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "soveti.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sovetidachniku.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sovetiogorodniku.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "spadehousemusic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "spanglishls.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sparkeddigital.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "spbfavourite.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "spbgorod.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "specialisedhealth.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "spectrum3d.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "speedwell.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "spfusion.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "spiritualpsychologyofacting.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "spoonnspice.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sprawdzanie-pozycji.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sq0z.ovh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "squareinchhome.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "squid-board.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "squiresinsurance.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sremodelingnyc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sridevi.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "srmllc.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "srmstatic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "srv-4g-test.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sslhello.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sssib.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "staceygillinphotography.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "stahlzart-moebel.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "stahlzart.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "stahlzart.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "stanbul.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "standardwohnungsbaukredit.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "standardwohnungsbaukredit.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "stefaanoyen.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "steingergreeneandfeiner.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "steltzer-scheidung.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "stiveschase.nsw.edu.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "stjlogistics.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "stopklopam.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "storepaperoomates.co.bw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "storepaperoomates.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "storepaperoomates.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "stralau.kicks-ass.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "stratuscloud.group", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "streamrare.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "streetwitnessing.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "strenge-zucht.schule", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sub-health.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "subastatutraslado.com.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "subiaco-physiotherapy.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "suckerberg.gay", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sulakskii-canyon.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "summit-research.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sumtotal.host", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sunnysideinc.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sunpower.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sunsetservicecentre.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sunsparksolar.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sunvillas.vn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "suomentilitoimistot.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "super-60.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "super60plus.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "superb.games", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "superkakdoma.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "superuser.one", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "suppchat.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sv-webdesign.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "svetix.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "swim-play.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "swimclubinsurance.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "swiss-watch.com.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sylmar-cash-for-cars.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "symposit.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "synapsemedical.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "synthetis.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "synthgularity.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "syscap.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "syscap.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "syscapassetfinance.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "syscaponline.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "t-op10.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "t-op6.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "t-op7.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "t-op8.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "t-op9.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tabulartools.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "takao.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "taksimax.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "taloman.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tangofoxi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tanzaniauk.org.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "taraweehonline.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tarihpedia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "taura.vn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "taxi-5plus.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "taxirostova.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tc-solutions.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tcddtrensaatleri.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tchak.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tcholet.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tcschwabfinancialplanning.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "td-zolotoy.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "teachernewsbd.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "techava.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "techstation.co.il", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tecnicainnovacion.com.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tedamos.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tedamos.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tedamos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tedamos.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tedulearning.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tefly-frhaty.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "teknoweek.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "telfordopticians.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "teligram.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tenantprotect.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tencur.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "terobait48.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "terrasandcookingoutdoor.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "terredilyana.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "teshuzi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "testaustime.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "textura.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tflonprocess.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thanhphophuquoc.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "theaidigitalmarketingblog.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "theanimalskingdom.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thebuttonpost.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thecdev.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "theconveyer.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thedaimon.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thedataexaminer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "theestateplanninggroup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "theeyewearshop.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "themagicalbohemian.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thenotarynetwork.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "theoaksatlanier.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "theprimepr.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "theredhouse.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thetrusth.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "theuhlesteam.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thibautdecherit.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thomaswicklaw.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thoughtleadersnetwork.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "threefisheswebdesign.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thrivingsmart.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thuongluu.vn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tidal.zone", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tiendamagia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tieredaccess.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tiete.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tilitoimistopaiva.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tiloschroeder.space", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tinastouchmassage.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "titularizadora.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tizreu.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tkafinearts.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tkhsurgery.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tldata.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "todayhap.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tomarlacalle.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tomaskopa.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tonsil-stone.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "top-azia.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "topluxitalia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "torontolife.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "toughcoding.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tpcrestorationllc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tpltestsg-mythiess-test.azurewebsites.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tqsintegration.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "traccxs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "trackadblock.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "transanglo.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "transav.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "transfer-sheregesh.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "transfer-v-sheregesh.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "transfer-vsheregesh.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "transfera-sheregesh.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "transfero-sheregesh.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "transfery-sheregesh.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "transhumanism.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "translation.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "traslochiinternazionali.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "travel2you.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "triglovian-clades.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tristatechess.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tronglu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "trtadalafil.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "trucockpit.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "trucockpit.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "truebarbershopinc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "trueflowplumbing.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tryrfsfirst.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tsbraz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tsbraz.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tsg0o0.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tshirai.work", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tt.gt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tudoxwallprinter.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tueri.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "turizm21.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tw.edu.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tz.mn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "u-olymp.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "u7ae.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ucih.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ueliexpress.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ufar-ntds.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ufoet.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "uizard.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ujjivan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ulbr.dnshome.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ulnesshealth.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ulrikethiele.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ultra.gen.tr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "umojawendanihousing.co.ke", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "umoman.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "unaligned.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "unalignment.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "unblock.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "unblockit.click", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "unhub.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "unidata.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "uniqclothing.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "uniquest.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "unisnu.ac.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "uniteddirectlending.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "unity-lepetitshop.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "upforshare.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "upwardflourish.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "urburb.social", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "usabusinessdirectories.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "usgovernmentnews.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "uspory.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "uss-electro.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "utageno.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "v-ogorode.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vadidanismanlik.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "van.ddns.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vanna-original.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vanna5.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vapehousebh.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vapeshoppos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vapotank.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "var.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "varuniyer.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vat-funding.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vbtk.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vc123.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vdwaart.synology.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vee.ci", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "veles-moto.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vendor-finance.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vendorleasing.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "venster.com.tr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "veren-group.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "verticalstructure.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vertichost.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vezettaksii.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "victoria-clinic.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "videoregion.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vigilanza.milano.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vilgain.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vilgain.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "viliko.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ville-nesle.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vinitour.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vipline.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "virkhost.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "virtualparalegal.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "visapro.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "visapro.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "visaprolaw.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "visavtodor.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "visitafuengirola.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "visitafuengirola.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "visitbinghamton.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "visitsights.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vitaerotaksi.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vitaminegeszseg.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vivendoapalavra.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vkontakte-poisk.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vle.id.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "voidbits.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "voigt-it.solutions", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "voxfa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vpn-sverige.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vrimmoinvest.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vrimmoworld.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vrrebank.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vsoflavors.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vypij.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vyrubka-derevya.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wa-m-web-alpcustomer-portal-caixabank.azurewebsites.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wa-m-web-alpcustomer-portal-timfin.azurewebsites.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wafflehacks.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wakeupeire.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "washed-house.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "washedupmeathead.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "web-wack.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "webappperformance.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "webcam.ninja", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "webcarebox.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "webdgc.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "webdock.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "webdrino.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "webowell.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wekurate.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wenducation.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "westrydeldc.nsw.edu.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wh-verwaltung.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "whyinsurance.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wichtel-umzuege.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wieldberis.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wifi.com.vn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wiki-rostelecom.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wildtattoo.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "windowscult.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "winma.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "winners.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "winnerschapelbelgium.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "winpic.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wise-parenting.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wiseup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wohnungsaufloesung-berlin.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wohnungsmarktbeobachtung.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wolfie.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "womenagainstviolence.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "woodstar.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "words-are-pictures.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "workshop-assets.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "worldofdiy.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "worldpool.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "worldsystems.com.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wouter.site", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wouterpetri.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wpinsides.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wrhomedecor.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wtawi.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wuast24.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wwtelenet.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wwtelenet.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wwwsberdahk.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wydmy.com.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wynajmijkontener.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wyofitclubs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wz.my", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xbdm.fun", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xkwy2018.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xn--3bt625flzps8a.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xn--d1acj9c.xn--90ais", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xn--h-1ga.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xn--l8jer.moe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xn--l8js6h.moe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xn--lk1a.moe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xn--mlkky-jua.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xsave.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xszys.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xszys.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xttt.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xuecheng.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xyactive.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xycommunication.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yaazhtech.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yagodigribi.guru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yamunaexpresswayplot.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yatserver.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yellowball.fm", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yellowbrick.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yoga-masterskaya.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "you-working.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yourgifttoyou.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yoursupportline.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "youston.agency", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "youthsadda.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yozucreative.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yrityksen-perustaminen.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yvonnetake.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zaba.training", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zadavalka.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zahnarzt.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zapsibir.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zasolka.guru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zdorovyj-rebjonok.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zebsaestheticsspa.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zelpc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zemledel.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zenpromo.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zepig.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zeusembroidery.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zeynabacademy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zhiboba.fun", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zjeunesse.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zollo-hauswartung.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zolotoinform.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zoo-dog.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zoomir-ra.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zoosfera12.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zpozdeno.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ztu75.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zubprotez.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zuixindianshiju.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zwrotzalot.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zxdsj1.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, // END OF 1-YEAR BULK HSTS ENTRIES // Only eTLD+1 domains can be submitted automatically to hstspreload.org,
diff --git a/net/socket/transport_client_socket_pool.cc b/net/socket/transport_client_socket_pool.cc index 337276d..03180c6c 100644 --- a/net/socket/transport_client_socket_pool.cc +++ b/net/socket/transport_client_socket_pool.cc
@@ -806,19 +806,27 @@ void TransportClientSocketPool::OnSSLConfigChanged( SSLClientContext::SSLConfigChangeType change_type) { - // When the user changes the SSL config, flush all idle sockets so they won't - // get re-used. + const char* message = nullptr; + // When the SSL config or cert verifier config changes, flush all idle + // sockets so they won't get re-used, and allow any active sockets to finish, + // but don't put them back in the socket pool. switch (change_type) { case SSLClientContext::SSLConfigChangeType::kSSLConfigChanged: - FlushWithError(ERR_NETWORK_CHANGED, kNetworkChanged); + message = kNetworkChanged; break; case SSLClientContext::SSLConfigChangeType::kCertDatabaseChanged: - FlushWithError(ERR_CERT_DATABASE_CHANGED, kCertDatabaseChanged); + message = kCertDatabaseChanged; break; case SSLClientContext::SSLConfigChangeType::kCertVerifierChanged: - FlushWithError(ERR_CERT_VERIFIER_CHANGED, kCertVerifierChanged); + message = kCertVerifierChanged; break; }; + + base::TimeTicks now = base::TimeTicks::Now(); + for (auto it = group_map_.begin(); it != group_map_.end();) { + it = RefreshGroup(it, now, message); + } + CheckForStalledSocketGroups(); } // TODO(crbug.com/1206799): Get `server` as SchemeHostPort?
diff --git a/net/socket/transport_client_socket_pool_unittest.cc b/net/socket/transport_client_socket_pool_unittest.cc index 004ab5e7..112eef9 100644 --- a/net/socket/transport_client_socket_pool_unittest.cc +++ b/net/socket/transport_client_socket_pool_unittest.cc
@@ -1126,23 +1126,68 @@ EXPECT_TRUE(handle.socket()); } -TEST_F(TransportClientSocketPoolTest, CloseIdleSocketsOnSSLConfigChange) { - TestCompletionCallback callback; - ClientSocketHandle handle; - int rv = - handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */, - LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, - callback.callback(), ClientSocketPool::ProxyAuthCallback(), - pool_.get(), NetLogWithSource()); - EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); - EXPECT_FALSE(handle.is_initialized()); - EXPECT_FALSE(handle.socket()); +namespace { +class TransportClientSocketPoolSSLConfigChangeTest + : public TransportClientSocketPoolTest, + public ::testing::WithParamInterface< + SSLClientContext::SSLConfigChangeType> { + public: + void SimulateChange() { + switch (GetParam()) { + case SSLClientContext::SSLConfigChangeType::kSSLConfigChanged: + session_deps_.ssl_config_service->NotifySSLContextConfigChange(); + break; + case SSLClientContext::SSLConfigChangeType::kCertDatabaseChanged: + // TODO(mattm): For more realistic testing this should call + // `CertDatabase::GetInstance()->NotifyObserversCertDBChanged()`, + // however that delivers notifications asynchronously, and running + // the message loop to allow the notification to be delivered allows + // other parts of the tested code to advance, breaking the test + // expectations. + pool_->OnSSLConfigChanged(GetParam()); + break; + case SSLClientContext::SSLConfigChangeType::kCertVerifierChanged: + session_deps_.cert_verifier->SimulateOnCertVerifierChanged(); + break; + } + } - EXPECT_THAT(callback.WaitForResult(), IsOk()); - EXPECT_TRUE(handle.is_initialized()); - EXPECT_TRUE(handle.socket()); + const char* ExpectedMessage() { + switch (GetParam()) { + case SSLClientContext::SSLConfigChangeType::kSSLConfigChanged: + return TransportClientSocketPool::kNetworkChanged; + case SSLClientContext::SSLConfigChangeType::kCertDatabaseChanged: + return TransportClientSocketPool::kCertDatabaseChanged; + case SSLClientContext::SSLConfigChangeType::kCertVerifierChanged: + return TransportClientSocketPool::kCertVerifierChanged; + } + } +}; +} // namespace - handle.Reset(); +TEST_P(TransportClientSocketPoolSSLConfigChangeTest, GracefulConfigChange) { + // Create a request and finish connection of the socket, and release the + // handle. + { + TestCompletionCallback callback; + ClientSocketHandle handle1; + int rv = + handle1.Init(group_id_, params_, /*proxy_annotation_tag=*/absl::nullopt, + LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource()); + EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); + EXPECT_FALSE(handle1.is_initialized()); + EXPECT_FALSE(handle1.socket()); + + EXPECT_THAT(callback.WaitForResult(), IsOk()); + EXPECT_TRUE(handle1.is_initialized()); + EXPECT_TRUE(handle1.socket()); + EXPECT_EQ(0, handle1.group_generation()); + EXPECT_EQ(0, pool_->IdleSocketCount()); + + handle1.Reset(); + } // Need to run all pending to release the socket back to the pool. base::RunLoop().RunUntilIdle(); @@ -1150,11 +1195,59 @@ // Now we should have 1 idle socket. EXPECT_EQ(1, pool_->IdleSocketCount()); - // After an SSL configuration change, we should have 0 idle sockets. - RecordingNetLogObserver net_log_observer; - session_deps_.ssl_config_service->NotifySSLContextConfigChange(); - base::RunLoop().RunUntilIdle(); // Notification happens async. + // Create another request and finish connection of the socket, but hold on to + // the handle until later in the test. + ClientSocketHandle handle2; + { + ClientSocketPool::GroupId group_id2( + url::SchemeHostPort(url::kHttpScheme, "bar.example.com", 80), + PrivacyMode::PRIVACY_MODE_DISABLED, NetworkAnonymizationKey(), + SecureDnsPolicy::kAllow); + TestCompletionCallback callback; + int rv = + handle2.Init(group_id2, params_, /*proxy_annotation_tag=*/absl::nullopt, + LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource()); + EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); + EXPECT_FALSE(handle2.is_initialized()); + EXPECT_FALSE(handle2.socket()); + EXPECT_THAT(callback.WaitForResult(), IsOk()); + EXPECT_TRUE(handle2.is_initialized()); + EXPECT_TRUE(handle2.socket()); + EXPECT_EQ(0, handle2.group_generation()); + } + + // Still only have 1 idle socket since handle2 is still alive. + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(1, pool_->IdleSocketCount()); + + // Create a pending request but don't finish connection. + ClientSocketPool::GroupId group_id3( + url::SchemeHostPort(url::kHttpScheme, "foo.example.com", 80), + PrivacyMode::PRIVACY_MODE_DISABLED, NetworkAnonymizationKey(), + SecureDnsPolicy::kAllow); + TestCompletionCallback callback3; + ClientSocketHandle handle3; + int rv = + handle3.Init(group_id3, params_, /*proxy_annotation_tag=*/absl::nullopt, + LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback3.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource()); + EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); + EXPECT_FALSE(handle3.is_initialized()); + EXPECT_FALSE(handle3.socket()); + + // Do a configuration change. + RecordingNetLogObserver net_log_observer; + SimulateChange(); + + // Allow handle3 to advance. + base::RunLoop().RunUntilIdle(); + // After a configuration change, we should have 0 idle sockets. The first + // idle socket should have been closed, and handle2 and handle3 are still + // alive. EXPECT_EQ(0, pool_->IdleSocketCount()); // Verify the netlog messages recorded the correct reason for closing the @@ -1164,50 +1257,36 @@ ASSERT_EQ(events.size(), 1u); std::string* reason = events[0].params.FindString("reason"); ASSERT_TRUE(reason); - EXPECT_EQ(*reason, TransportClientSocketPool::kNetworkChanged); -} + EXPECT_EQ(*reason, ExpectedMessage()); -TEST_F(TransportClientSocketPoolTest, CloseIdleSocketsOnCertVerifierChange) { - TestCompletionCallback callback; - ClientSocketHandle handle; - int rv = - handle.Init(group_id_, params_, /*proxy_annotation_tag=*/absl::nullopt, - LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, - callback.callback(), ClientSocketPool::ProxyAuthCallback(), - pool_.get(), NetLogWithSource()); - EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); - EXPECT_FALSE(handle.is_initialized()); - EXPECT_FALSE(handle.socket()); + // The pending request for handle3 should have succeeded under the new + // generation since it didn't start until after the change. + EXPECT_THAT(callback3.WaitForResult(), IsOk()); + EXPECT_TRUE(handle3.is_initialized()); + EXPECT_TRUE(handle3.socket()); + EXPECT_EQ(1, handle3.group_generation()); - EXPECT_THAT(callback.WaitForResult(), IsOk()); - EXPECT_TRUE(handle.is_initialized()); - EXPECT_TRUE(handle.socket()); - - handle.Reset(); - - // Need to run all pending to release the socket back to the pool. + // After releasing handle2, it does not become an idle socket since it was + // part of the first generation. + handle2.Reset(); base::RunLoop().RunUntilIdle(); - - // Now we should have 1 idle socket. - EXPECT_EQ(1, pool_->IdleSocketCount()); - - // After a cert verifier configuration change, we should have 0 idle sockets. - RecordingNetLogObserver net_log_observer; - session_deps_.cert_verifier->SimulateOnCertVerifierChanged(); - base::RunLoop().RunUntilIdle(); // Notification happens async. - EXPECT_EQ(0, pool_->IdleSocketCount()); - // Verify the netlog messages recorded the correct reason for closing the - // idle sockets. - auto events = net_log_observer.GetEntriesWithType( - NetLogEventType::SOCKET_POOL_CLOSING_SOCKET); - ASSERT_EQ(events.size(), 1u); - std::string* reason = events[0].params.FindString("reason"); - ASSERT_TRUE(reason); - EXPECT_EQ(*reason, TransportClientSocketPool::kCertVerifierChanged); + // After releasing handle3, there is now one idle socket, since that socket + // was connected during the new generation. + handle3.Reset(); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(1, pool_->IdleSocketCount()); } +INSTANTIATE_TEST_SUITE_P( + All, + TransportClientSocketPoolSSLConfigChangeTest, + testing::Values( + SSLClientContext::SSLConfigChangeType::kSSLConfigChanged, + SSLClientContext::SSLConfigChangeType::kCertDatabaseChanged, + SSLClientContext::SSLConfigChangeType::kCertVerifierChanged)); + TEST_F(TransportClientSocketPoolTest, BackupSocketConnect) { // Case 1 tests the first socket stalling, and the backup connecting. MockTransportClientSocketFactory::Rule rules1[] = {
diff --git a/sandbox/win/src/ipc_leak_test.cc b/sandbox/win/src/ipc_leak_test.cc index 44db9aa..596bfdd3 100644 --- a/sandbox/win/src/ipc_leak_test.cc +++ b/sandbox/win/src/ipc_leak_test.cc
@@ -201,7 +201,7 @@ // broker. PolicyGlobal* policy = GenerateBlankPolicy(); PolicyGlobal* current_policy = - (PolicyGlobal*)sandbox::GetGlobalPolicyMemory(); + (PolicyGlobal*)sandbox::GetGlobalPolicyMemoryForTesting(); CopyPolicyToTarget(policy, policy->data_size + sizeof(PolicyGlobal), current_policy); @@ -271,6 +271,10 @@ static_assert(std::size(test_data) == TESTIPC_LAST, "Not enough tests."); for (auto test : test_data) { TestRunner runner; + // There has to be a policy allocated for the child to have one to replace. + runner.AddRule(sandbox::SubSystem::kFiles, + sandbox::Semantics::kFilesAllowReadonly, + L"c:\\Windows\\System32\\Nothing.txt"); std::wstring command = std::wstring(L"IPC_Leak "); command += std::to_wstring(test.test_id); EXPECT_EQ(test.expected_result,
diff --git a/sandbox/win/src/policy_target.cc b/sandbox/win/src/policy_target.cc index f80507d..aff1537 100644 --- a/sandbox/win/src/policy_target.cc +++ b/sandbox/win/src/policy_target.cc
@@ -25,12 +25,16 @@ bool QueryBroker(IpcTag ipc_id, CountedParameterSetBase* params) { DCHECK_NT(static_cast<size_t>(ipc_id) < kMaxServiceCount); - DCHECK_NT(g_shared_policy_memory); - DCHECK_NT(g_shared_policy_size > 0); if (static_cast<size_t>(ipc_id) >= kMaxServiceCount) return false; + // Policy is only sent if required. + if (!g_shared_policy_memory) { + CHECK_NT(g_shared_policy_size); + return false; + } + PolicyGlobal* global_policy = reinterpret_cast<PolicyGlobal*>(g_shared_policy_memory);
diff --git a/sandbox/win/src/sandbox_nt_util.cc b/sandbox/win/src/sandbox_nt_util.cc index 68d6839a..2d5dc866 100644 --- a/sandbox/win/src/sandbox_nt_util.cc +++ b/sandbox/win/src/sandbox_nt_util.cc
@@ -204,11 +204,12 @@ GetNtExports()->UnmapViewOfSection(NtCurrentProcess, memory)); } DCHECK_NT(g_shared_IPC_size > 0); - g_shared_policy_memory = - reinterpret_cast<char*>(g_shared_IPC_memory) + g_shared_IPC_size; + if (g_shared_policy_size > 0) { + g_shared_policy_memory = + reinterpret_cast<char*>(g_shared_IPC_memory) + g_shared_IPC_size; + } } - DCHECK_NT(g_shared_policy_memory); - DCHECK_NT(g_shared_policy_size > 0); + return true; } @@ -218,7 +219,7 @@ return g_shared_IPC_memory; } -void* GetGlobalPolicyMemory() { +void* GetGlobalPolicyMemoryForTesting() { if (!MapGlobalMemory()) return nullptr; return g_shared_policy_memory;
diff --git a/sandbox/win/src/sandbox_nt_util.h b/sandbox/win/src/sandbox_nt_util.h index b09b759..311683d 100644 --- a/sandbox/win/src/sandbox_nt_util.h +++ b/sandbox/win/src/sandbox_nt_util.h
@@ -100,7 +100,7 @@ void* GetGlobalIPCMemory(); // Returns a pointer to the Policy shared memory. -void* GetGlobalPolicyMemory(); +void* GetGlobalPolicyMemoryForTesting(); // Returns a reference to imported NT functions. const NtExports* GetNtExports();
diff --git a/sandbox/win/src/sandbox_policy_base.cc b/sandbox/win/src/sandbox_policy_base.cc index a163e993..58865dc 100644 --- a/sandbox/win/src/sandbox_policy_base.cc +++ b/sandbox/win/src/sandbox_policy_base.cc
@@ -10,6 +10,7 @@ #include <memory> #include <utility> +#include "base/containers/span.h" #include "base/functional/callback.h" #include "base/logging.h" #include "base/win/access_control_list.h" @@ -155,6 +156,16 @@ return policy_; } +absl::optional<base::span<const uint8_t>> ConfigBase::policy_span() { + if (policy_) { + // Note: this is not policy().data_size as that relates to internal data, + // not the entire allocated policy area. + return base::span<const uint8_t>(reinterpret_cast<uint8_t*>(policy_.get()), + kPolMemSize); + } + return absl::nullopt; +} + std::vector<std::wstring>& ConfigBase::blocklisted_dlls() { DCHECK(configured_); return blocklisted_dlls_; @@ -617,8 +628,8 @@ DWORD win_error = ERROR_SUCCESS; // Initialize the sandbox infrastructure for the target. // TODO(wfh) do something with win_error code here. - ret = target->Init(dispatcher_.get(), config()->policy(), kIPCMemSize, - kPolMemSize, &win_error); + ret = target->Init(dispatcher_.get(), config()->policy_span(), kIPCMemSize, + &win_error); if (ret != SBOX_ALL_OK) return ret;
diff --git a/sandbox/win/src/sandbox_policy_base.h b/sandbox/win/src/sandbox_policy_base.h index 635083f..3c361d2f 100644 --- a/sandbox/win/src/sandbox_policy_base.h +++ b/sandbox/win/src/sandbox_policy_base.h
@@ -14,6 +14,7 @@ #include <vector> #include "base/compiler_specific.h" +#include "base/containers/span.h" #include "base/dcheck_is_on.h" #include "base/memory/raw_ptr.h" #include "base/memory/scoped_refptr.h" @@ -113,6 +114,7 @@ // Should only be called once the object is configured. PolicyGlobal* policy(); + absl::optional<base::span<const uint8_t>> policy_span(); std::vector<std::wstring>& blocklisted_dlls(); AppContainerBase* app_container(); IntegrityLevel integrity_level() { return integrity_level_; }
diff --git a/sandbox/win/src/target_process.cc b/sandbox/win/src/target_process.cc index 1a33897..7cd7e8a 100644 --- a/sandbox/win/src/target_process.cc +++ b/sandbox/win/src/target_process.cc
@@ -55,14 +55,15 @@ return cur + 1; } -void CopyPolicyToTarget(const void* source, size_t size, void* dest) { - if (!source || !size) +void CopyPolicyToTarget(base::span<const uint8_t> source, void* dest) { + if (!source.size()) { return; - memcpy(dest, source, size); + } + memcpy(dest, source.data(), source.size()); sandbox::PolicyGlobal* policy = reinterpret_cast<sandbox::PolicyGlobal*>(dest); - size_t offset = reinterpret_cast<size_t>(source); + size_t offset = reinterpret_cast<size_t>(source.data()); for (size_t i = 0; i < sandbox::kMaxServiceCount; i++) { size_t buffer = reinterpret_cast<size_t>(policy->entry[i]); @@ -246,9 +247,8 @@ // Construct the IPC server and the IPC dispatcher. When the target does // an IPC it will eventually call the dispatcher. ResultCode TargetProcess::Init(Dispatcher* ipc_dispatcher, - void* policy, + absl::optional<base::span<const uint8_t>> policy, uint32_t shared_IPC_size, - uint32_t shared_policy_size, DWORD* win_error) { ResultCode ret = VerifySentinels(); if (ret != SBOX_ALL_OK) @@ -261,8 +261,11 @@ // the rest, which boils down to calling MapViewofFile() // We use this single memory pool for IPC and for policy. - DWORD shared_mem_size = - static_cast<DWORD>(shared_IPC_size + shared_policy_size); + DWORD shared_mem_size = static_cast<DWORD>(shared_IPC_size); + if (policy.has_value()) { + shared_mem_size += static_cast<DWORD>(policy->size()); + } + shared_section_.Set(::CreateFileMappingW(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE | SEC_COMMIT, 0, shared_mem_size, nullptr)); @@ -278,8 +281,10 @@ return SBOX_ERROR_MAP_VIEW_OF_SHARED_SECTION; } - CopyPolicyToTarget(policy, shared_policy_size, - reinterpret_cast<char*>(shared_memory) + shared_IPC_size); + if (policy.has_value()) { + CopyPolicyToTarget(policy.value(), reinterpret_cast<char*>(shared_memory) + + shared_IPC_size); + } // Set the global variables in the target. These are not used on the broker. g_shared_IPC_size = shared_IPC_size; @@ -290,13 +295,15 @@ *win_error = ::GetLastError(); return ret; } - g_shared_policy_size = shared_policy_size; - ret = TransferVariable("g_shared_policy_size", &g_shared_policy_size, - sizeof(g_shared_policy_size)); - g_shared_policy_size = 0; - if (SBOX_ALL_OK != ret) { - *win_error = ::GetLastError(); - return ret; + if (policy.has_value()) { + g_shared_policy_size = policy->size(); + ret = TransferVariable("g_shared_policy_size", &g_shared_policy_size, + sizeof(g_shared_policy_size)); + g_shared_policy_size = 0; + if (SBOX_ALL_OK != ret) { + *win_error = ::GetLastError(); + return ret; + } } ipc_server_ = std::make_unique<SharedMemIPCServer>(
diff --git a/sandbox/win/src/target_process.h b/sandbox/win/src/target_process.h index bd5d9c7..6e85354d 100644 --- a/sandbox/win/src/target_process.h +++ b/sandbox/win/src/target_process.h
@@ -58,9 +58,8 @@ // Creates the IPC objects such as the BrokerDispatcher and the // IPC server. The IPC server uses the services of the thread_pool. ResultCode Init(Dispatcher* ipc_dispatcher, - void* policy, + absl::optional<base::span<const uint8_t>> policy, uint32_t shared_IPC_size, - uint32_t shared_policy_size, DWORD* win_error); // Returns the handle to the target process.
diff --git a/services/audio/public/cpp/output_device.cc b/services/audio/public/cpp/output_device.cc index 702a1ee..414e5e1 100644 --- a/services/audio/public/cpp/output_device.cc +++ b/services/audio/public/cpp/output_device.cc
@@ -42,17 +42,23 @@ void OutputDevice::Play() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - stream_->Play(); + if (stream_.is_bound()) { + stream_->Play(); + } } void OutputDevice::Pause() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - stream_->Pause(); + if (stream_.is_bound()) { + stream_->Pause(); + } } void OutputDevice::SetVolume(double volume) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - stream_->SetVolume(volume); + if (stream_.is_bound()) { + stream_->SetVolume(volume); + } } void OutputDevice::StreamCreated( @@ -81,6 +87,8 @@ // simpler. base::ScopedAllowBaseSyncPrimitivesOutsideBlockingScope allow_thread_join; CleanUp(); + + render_callback_->OnRenderError(); } void OutputDevice::CleanUp() {
diff --git a/services/audio/public/cpp/output_device.h b/services/audio/public/cpp/output_device.h index cc956c5..3559de7 100644 --- a/services/audio/public/cpp/output_device.h +++ b/services/audio/public/cpp/output_device.h
@@ -52,7 +52,7 @@ std::unique_ptr<media::AudioOutputDeviceThreadCallback> audio_callback_; std::unique_ptr<media::AudioDeviceThread> audio_thread_; media::AudioParameters audio_parameters_; - raw_ptr<media::AudioRendererSink::RenderCallback> render_callback_; + const raw_ptr<media::AudioRendererSink::RenderCallback> render_callback_; mojo::Remote<media::mojom::AudioOutputStream> stream_; mojo::Remote<media::mojom::AudioStreamFactory> stream_factory_;
diff --git a/services/audio/public/cpp/sounds/audio_stream_handler.cc b/services/audio/public/cpp/sounds/audio_stream_handler.cc index c74bfd6..3129551 100644 --- a/services/audio/public/cpp/sounds/audio_stream_handler.cc +++ b/services/audio/public/cpp/sounds/audio_stream_handler.cc
@@ -12,6 +12,7 @@ #include "base/cancelable_callback.h" #include "base/functional/bind.h" #include "base/logging.h" +#include "base/memory/weak_ptr.h" #include "base/notreached.h" #include "base/synchronization/lock.h" #include "base/task/sequenced_task_runner.h" @@ -83,7 +84,7 @@ base::AutoLock al(state_lock_); delayed_stop_posted_ = false; - stop_closure_.Reset(base::BindRepeating(&AudioStreamContainer::StopStream, + stop_closure_.Reset(base::BindRepeating(&AudioStreamContainer::Stop, base::Unretained(this))); if (started_) { @@ -109,8 +110,18 @@ void Stop() { DCHECK(task_runner_->RunsTasksInCurrentSequence()); - StopStream(); + if (started_) { + // Do not hold the |state_lock_| while stopping the output stream. + if (g_observer_for_testing) { + g_observer_for_testing->OnStop(); + } else { + device_->Pause(); + } + } + + started_ = false; stop_closure_.Cancel(); + device_.reset(); } private: @@ -135,23 +146,9 @@ } void OnRenderError() override { - task_runner_->PostTask( - FROM_HERE, - base::BindOnce(&AudioStreamContainer::Stop, base::Unretained(this))); - } - - void StopStream() { - DCHECK(task_runner_->RunsTasksInCurrentSequence()); - - if (started_) { - // Do not hold the |state_lock_| while stopping the output stream. - if (g_observer_for_testing) - g_observer_for_testing->OnStop(); - else - device_->Pause(); - } - - started_ = false; + task_runner_->PostTask(FROM_HERE, + base::BindOnce(&AudioStreamContainer::Stop, + weak_factory_.GetWeakPtr())); } bool started_ = false; @@ -164,6 +161,9 @@ bool delayed_stop_posted_ = false; std::unique_ptr<media::AudioHandler> audio_handler_; base::CancelableRepeatingClosure stop_closure_; + + base::WeakPtrFactory<AudioStreamHandler::AudioStreamContainer> weak_factory_{ + this}; }; AudioStreamHandler::AudioStreamHandler( @@ -213,6 +213,9 @@ } AudioStreamHandler::~AudioStreamHandler() { + // TODO(b/279455052): A question about the overall design for if this class + // need to post functions into `task_runner`. Same questions for the `Play` + // and `Stop`. DCHECK(task_runner_->RunsTasksInCurrentSequence()); if (IsInitialized()) { task_runner_->PostTask(FROM_HERE,
diff --git a/services/audio/public/java/BUILD.gn b/services/audio/public/java/BUILD.gn new file mode 100644 index 0000000..4826513 --- /dev/null +++ b/services/audio/public/java/BUILD.gn
@@ -0,0 +1,15 @@ +# Copyright 2023 The Chromium Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//build/config/android/rules.gni") + +android_library("audio_feature_list_java") { + sources = [ "src/org/chromium/audio/AudioFeatureList.java" ] + deps = [ + "//base:base_java", + "//base:jni_java", + "//build/android:build_java", + ] + annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ] +}
diff --git a/testing/buildbot/chrome.json b/testing/buildbot/chrome.json index 6451ab75..06d75ca 100644 --- a/testing/buildbot/chrome.json +++ b/testing/buildbot/chrome.json
@@ -2850,6 +2850,25 @@ "test_id_prefix": "ninja://ui/display:display_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04", + "pool": "chrome.tests", + "ssd": "0" + } + ], + "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -3142,6 +3161,25 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04", + "pool": "chrome.tests", + "ssd": "0" + } + ], + "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" },
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json index 5c2f402..304d0fd 100644 --- a/testing/buildbot/chromium.android.json +++ b/testing/buildbot/chromium.android.json
@@ -4147,6 +4147,66 @@ "--recover-devices", "--avd-config=../../tools/android/avd/proto/generic_android30.textpb" ], + "ci_only": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "env_chromium_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cores": "4", + "cpu": "x86-64", + "device_os": null, + "device_type": null, + "os": "Ubuntu-18.04", + "pool": "chromium.tests.avd" + } + ], + "named_caches": [ + { + "name": "generic_android30", + "path": ".android_emulator/generic_android30" + } + ], + "optional_dimensions": { + "60": [ + { + "caches": "generic_android30" + } + ] + }, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices", + "--avd-config=../../tools/android/avd/proto/generic_android30.textpb" + ], "merge": { "args": [ "--bucket", @@ -4799,6 +4859,66 @@ "--recover-devices", "--avd-config=../../tools/android/avd/proto/generic_android30.textpb" ], + "ci_only": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "leveldb_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cores": "4", + "cpu": "x86-64", + "device_os": null, + "device_type": null, + "os": "Ubuntu-18.04", + "pool": "chromium.tests.avd" + } + ], + "named_caches": [ + { + "name": "generic_android30", + "path": ".android_emulator/generic_android30" + } + ], + "optional_dimensions": { + "60": [ + { + "caches": "generic_android30" + } + ] + }, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices", + "--avd-config=../../tools/android/avd/proto/generic_android30.textpb" + ], "merge": { "args": [ "--bucket", @@ -8330,6 +8450,67 @@ "--recover-devices", "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], + "ci_only": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "env_chromium_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cores": "8", + "cpu": "x86-64", + "device_os": null, + "device_type": null, + "os": "Ubuntu-22.04", + "pool": "chromium.tests.avd" + } + ], + "named_caches": [ + { + "name": "generic_android31", + "path": ".android_emulator/generic_android31" + } + ], + "optional_dimensions": { + "60": [ + { + "caches": "generic_android31" + } + ] + }, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { + "args": [ + "--use-persistent-shell", + "--gs-results-bucket=chromium-result-details", + "--recover-devices", + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" + ], "merge": { "args": [ "--bucket", @@ -8994,6 +9175,67 @@ "--recover-devices", "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" ], + "ci_only": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "leveldb_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cores": "8", + "cpu": "x86-64", + "device_os": null, + "device_type": null, + "os": "Ubuntu-22.04", + "pool": "chromium.tests.avd" + } + ], + "named_caches": [ + { + "name": "generic_android31", + "path": ".android_emulator/generic_android31" + } + ], + "optional_dimensions": { + "60": [ + { + "caches": "generic_android31" + } + ] + }, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { + "args": [ + "--use-persistent-shell", + "--gs-results-bucket=chromium-result-details", + "--recover-devices", + "--avd-config=../../tools/android/avd/proto/generic_android31.textpb" + ], "merge": { "args": [ "--bucket", @@ -12617,6 +12859,66 @@ "--recover-devices", "--avd-config=../../tools/android/avd/proto/generic_android32_foldable.textpb" ], + "ci_only": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "env_chromium_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cores": "8", + "cpu": "x86-64", + "device_os": null, + "device_type": null, + "os": "Ubuntu-18.04", + "pool": "chromium.tests.avd" + } + ], + "named_caches": [ + { + "name": "generic_android32_foldable", + "path": ".android_emulator/generic_android32_foldable" + } + ], + "optional_dimensions": { + "60": [ + { + "caches": "generic_android32_foldable" + } + ] + }, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices", + "--avd-config=../../tools/android/avd/proto/generic_android32_foldable.textpb" + ], "merge": { "args": [ "--bucket", @@ -13269,6 +13571,66 @@ "--recover-devices", "--avd-config=../../tools/android/avd/proto/generic_android32_foldable.textpb" ], + "ci_only": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "leveldb_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cores": "8", + "cpu": "x86-64", + "device_os": null, + "device_type": null, + "os": "Ubuntu-18.04", + "pool": "chromium.tests.avd" + } + ], + "named_caches": [ + { + "name": "generic_android32_foldable", + "path": ".android_emulator/generic_android32_foldable" + } + ], + "optional_dimensions": { + "60": [ + { + "caches": "generic_android32_foldable" + } + ] + }, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices", + "--avd-config=../../tools/android/avd/proto/generic_android32_foldable.textpb" + ], "merge": { "args": [ "--bucket", @@ -15866,7 +16228,8 @@ "--gs-results-bucket=chromium-result-details", "--recover-devices", "--avd-config=../../tools/android/avd/proto/generic_android33.textpb", - "--git-revision=${got_revision}" + "--git-revision=${got_revision}", + "--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator_13.chrome_public_test_apk.filter" ], "merge": { "args": [ @@ -16606,6 +16969,66 @@ "--recover-devices", "--avd-config=../../tools/android/avd/proto/generic_android33.textpb" ], + "ci_only": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "env_chromium_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cores": "8", + "cpu": "x86-64", + "device_os": null, + "device_type": null, + "os": "Ubuntu-18.04", + "pool": "chromium.tests.avd" + } + ], + "named_caches": [ + { + "name": "generic_android33", + "path": ".android_emulator/generic_android33" + } + ], + "optional_dimensions": { + "60": [ + { + "caches": "generic_android33" + } + ] + }, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices", + "--avd-config=../../tools/android/avd/proto/generic_android33.textpb" + ], "merge": { "args": [ "--bucket", @@ -17258,6 +17681,66 @@ "--recover-devices", "--avd-config=../../tools/android/avd/proto/generic_android33.textpb" ], + "ci_only": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "leveldb_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cores": "8", + "cpu": "x86-64", + "device_os": null, + "device_type": null, + "os": "Ubuntu-18.04", + "pool": "chromium.tests.avd" + } + ], + "named_caches": [ + { + "name": "generic_android33", + "path": ".android_emulator/generic_android33" + } + ], + "optional_dimensions": { + "60": [ + { + "caches": "generic_android33" + } + ] + }, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices", + "--avd-config=../../tools/android/avd/proto/generic_android33.textpb" + ], "merge": { "args": [ "--bucket", @@ -20300,6 +20783,51 @@ "--gs-results-bucket=chromium-result-details", "--recover-devices" ], + "ci_only": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "env_chromium_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "device_os": "PQ3A.190801.002", + "device_os_flavor": "google", + "device_os_type": "userdebug", + "device_type": "walleye", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], "merge": { "args": [ "--bucket", @@ -20787,6 +21315,51 @@ "--gs-results-bucket=chromium-result-details", "--recover-devices" ], + "ci_only": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "leveldb_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "device_os": "PQ3A.190801.002", + "device_os_flavor": "google", + "device_os_type": "userdebug", + "device_type": "walleye", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], "merge": { "args": [ "--bucket", @@ -27984,6 +28557,68 @@ "--recover-devices", "--avd-config=../../tools/android/avd/proto/generic_android24.textpb" ], + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "env_chromium_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cores": "4", + "cpu": "x86-64", + "device_os": null, + "device_type": null, + "os": "Ubuntu-18.04", + "pool": "chromium.tests.avd" + } + ], + "named_caches": [ + { + "name": "generic_android24", + "path": ".android_emulator/generic_android24" + } + ], + "optional_dimensions": { + "60": [ + { + "caches": "generic_android24" + } + ] + }, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { + "args": [ + "--use-persistent-shell", + "--gs-results-bucket=chromium-result-details", + "--recover-devices", + "--avd-config=../../tools/android/avd/proto/generic_android24.textpb" + ], "isolate_profile_data": true, "merge": { "args": [ @@ -30622,7 +31257,6 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/android.nougat-x86-rel.chrome_junit_tests.filter", "--use-persistent-shell" ], "isolate_name": "chrome_junit_tests", @@ -34494,6 +35128,66 @@ "--recover-devices", "--avd-config=../../tools/android/avd/proto/generic_android28.textpb" ], + "ci_only": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "env_chromium_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cores": "4", + "cpu": "x86-64", + "device_os": null, + "device_type": null, + "os": "Ubuntu-18.04", + "pool": "chromium.tests.avd" + } + ], + "named_caches": [ + { + "name": "generic_android28", + "path": ".android_emulator/generic_android28" + } + ], + "optional_dimensions": { + "60": [ + { + "caches": "generic_android28" + } + ] + }, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices", + "--avd-config=../../tools/android/avd/proto/generic_android28.textpb" + ], "merge": { "args": [ "--bucket", @@ -35146,6 +35840,66 @@ "--recover-devices", "--avd-config=../../tools/android/avd/proto/generic_android28.textpb" ], + "ci_only": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "leveldb_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cores": "4", + "cpu": "x86-64", + "device_os": null, + "device_type": null, + "os": "Ubuntu-18.04", + "pool": "chromium.tests.avd" + } + ], + "named_caches": [ + { + "name": "generic_android28", + "path": ".android_emulator/generic_android28" + } + ], + "optional_dimensions": { + "60": [ + { + "caches": "generic_android28" + } + ] + }, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices", + "--avd-config=../../tools/android/avd/proto/generic_android28.textpb" + ], "merge": { "args": [ "--bucket",
diff --git a/testing/buildbot/chromium.cft.json b/testing/buildbot/chromium.cft.json index d4a0b53..bde44c28 100644 --- a/testing/buildbot/chromium.cft.json +++ b/testing/buildbot/chromium.cft.json
@@ -561,6 +561,24 @@ "test_id_prefix": "ninja://ui/display:display_unittests/" }, { + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -820,6 +838,24 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -2646,6 +2682,25 @@ "test_id_prefix": "ninja://ui/display:display_unittests/" }, { + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-12" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -2921,6 +2976,25 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-12" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4559,6 +4633,25 @@ "test_id_prefix": "ninja://chrome/elevation_service:elevation_service_unittests/" }, { + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-10-19045" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4918,6 +5011,25 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-10-19045" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py"
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json index 8020d72..8f8a7485 100644 --- a/testing/buildbot/chromium.chromiumos.json +++ b/testing/buildbot/chromium.chromiumos.json
@@ -2326,6 +2326,23 @@ "test_id_prefix": "ninja://ui/display:display_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -2583,6 +2600,23 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -3922,6 +3956,24 @@ "test_id_prefix": "ninja://ui/display:display_unittests/" }, { + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4196,6 +4248,24 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5420,6 +5490,24 @@ "test_id_prefix": "ninja://ui/display:display_unittests/" }, { + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -6088,6 +6176,24 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py"
diff --git a/testing/buildbot/chromium.clang.json b/testing/buildbot/chromium.clang.json index be5168b..a8ef47a 100644 --- a/testing/buildbot/chromium.clang.json +++ b/testing/buildbot/chromium.clang.json
@@ -512,6 +512,23 @@ "test_id_prefix": "ninja://ui/display:display_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -769,6 +786,23 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -1988,6 +2022,24 @@ "test_id_prefix": "ninja://chrome/elevation_service:elevation_service_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-10-19045" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -2296,6 +2348,24 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-10-19045" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -3569,6 +3639,24 @@ "test_id_prefix": "ninja://chrome/elevation_service:elevation_service_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-10-19045" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -3825,6 +3913,24 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-10-19045" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -5743,6 +5849,51 @@ "--gs-results-bucket=chromium-result-details", "--recover-devices" ], + "ci_only": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "env_chromium_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "device_os": "PQ3A.190801.002", + "device_os_flavor": "google", + "device_os_type": "userdebug", + "device_type": "walleye", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], "merge": { "args": [ "--bucket", @@ -6230,6 +6381,51 @@ "--gs-results-bucket=chromium-result-details", "--recover-devices" ], + "ci_only": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "leveldb_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "device_os": "PQ3A.190801.002", + "device_os_flavor": "google", + "device_os_type": "userdebug", + "device_type": "walleye", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], "merge": { "args": [ "--bucket", @@ -10732,6 +10928,23 @@ "test_id_prefix": "ninja://ui/display:display_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -10973,6 +11186,23 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -12240,6 +12470,26 @@ "args": [ "--test-launcher-print-test-stdio=always" ], + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { + "args": [ + "--test-launcher-print-test-stdio=always" + ], "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -12507,6 +12757,26 @@ "args": [ "--test-launcher-print-test-stdio=always" ], + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { + "args": [ + "--test-launcher-print-test-stdio=always" + ], "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -13764,6 +14034,23 @@ "test_id_prefix": "ninja://ui/display:display_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -14005,6 +14292,23 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -15163,6 +15467,24 @@ "test_id_prefix": "ninja://ui/display:display_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04", + "pool": "chrome.tests" + } + ], + "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -15419,6 +15741,24 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04", + "pool": "chrome.tests" + } + ], + "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -16358,6 +16698,23 @@ "test_id_prefix": "ninja://crypto:crypto_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -16486,6 +16843,23 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -17251,6 +17625,23 @@ "test_id_prefix": "ninja://ui/display:display_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -17492,6 +17883,23 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -18636,6 +19044,23 @@ "test_id_prefix": "ninja://ui/display:display_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -18877,6 +19302,23 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -20017,6 +20459,24 @@ "test_id_prefix": "ninja://ui/display:display_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-12" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -20273,6 +20733,24 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-12" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -21878,6 +22356,27 @@ "args": [ "--test-launcher-print-test-stdio=always" ], + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-12" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { + "args": [ + "--test-launcher-print-test-stdio=always" + ], "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -22179,6 +22678,27 @@ "args": [ "--test-launcher-print-test-stdio=always" ], + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-12" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { + "args": [ + "--test-launcher-print-test-stdio=always" + ], "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -23411,6 +23931,25 @@ "test_id_prefix": "ninja://ui/display:display_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-12", + "pool": "chrome.tests" + } + ], + "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -23682,6 +24221,25 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-12", + "pool": "chrome.tests" + } + ], + "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -25308,6 +25866,23 @@ "test_id_prefix": "ninja://chrome/elevation_service:elevation_service_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Windows-10-19045" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -25598,6 +26173,23 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Windows-10-19045" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -26873,6 +27465,23 @@ "test_id_prefix": "ninja://chrome/elevation_service:elevation_service_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Windows-10-19045" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -27163,6 +27772,23 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Windows-10-19045" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -28402,6 +29028,23 @@ "test_id_prefix": "ninja://chrome/elevation_service:elevation_service_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Windows-10-19045" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -28692,6 +29335,23 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Windows-10-19045" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -30003,6 +30663,24 @@ "test_id_prefix": "ninja://chrome/elevation_service:elevation_service_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-10-19045" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -30311,6 +30989,24 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-10-19045" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -31664,6 +32360,24 @@ "test_id_prefix": "ninja://chrome/elevation_service:elevation_service_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-10-19045" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -31972,6 +32686,24 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-10-19045" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -33325,6 +34057,24 @@ "test_id_prefix": "ninja://chrome/elevation_service:elevation_service_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-10-19045" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -33633,6 +34383,24 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-10-19045" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -34662,6 +35430,24 @@ "test_id_prefix": "ninja://crypto:crypto_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-10-19045" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -34798,6 +35584,24 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-10-19045" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -35718,6 +36522,24 @@ "test_id_prefix": "ninja://chrome/elevation_service:elevation_service_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Windows-10", + "pool": "chrome.tests" + } + ], + "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -36026,6 +36848,24 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Windows-10", + "pool": "chrome.tests" + } + ], + "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -37379,6 +38219,24 @@ "test_id_prefix": "ninja://chrome/elevation_service:elevation_service_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Windows-10", + "pool": "chrome.tests" + } + ], + "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -37687,6 +38545,24 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Windows-10", + "pool": "chrome.tests" + } + ], + "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -40747,6 +41623,23 @@ "test_id_prefix": "ninja://chrome/elevation_service:elevation_service_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Windows-10-19045" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -41037,6 +41930,23 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Windows-10-19045" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" },
diff --git a/testing/buildbot/chromium.coverage.json b/testing/buildbot/chromium.coverage.json index f0fdbae..ff37983 100644 --- a/testing/buildbot/chromium.coverage.json +++ b/testing/buildbot/chromium.coverage.json
@@ -1899,6 +1899,52 @@ "--gs-results-bucket=chromium-result-details", "--recover-devices" ], + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "env_chromium_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "device_os": "PQ3A.190801.002", + "device_os_flavor": "google", + "device_os_type": "userdebug", + "device_type": "walleye", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], "isolate_profile_data": true, "merge": { "args": [ @@ -2398,6 +2444,52 @@ "--gs-results-bucket=chromium-result-details", "--recover-devices" ], + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "leveldb_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "device_os": "PQ3A.190801.002", + "device_os_flavor": "google", + "device_os_type": "userdebug", + "device_type": "walleye", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], "isolate_profile_data": true, "merge": { "args": [ @@ -5200,6 +5292,68 @@ "--recover-devices", "--avd-config=../../tools/android/avd/proto/generic_android24.textpb" ], + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "env_chromium_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cores": "4", + "cpu": "x86-64", + "device_os": null, + "device_type": null, + "os": "Ubuntu-18.04", + "pool": "chromium.tests.avd" + } + ], + "named_caches": [ + { + "name": "generic_android24", + "path": ".android_emulator/generic_android24" + } + ], + "optional_dimensions": { + "60": [ + { + "caches": "generic_android24" + } + ] + }, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { + "args": [ + "--use-persistent-shell", + "--gs-results-bucket=chromium-result-details", + "--recover-devices", + "--avd-config=../../tools/android/avd/proto/generic_android24.textpb" + ], "isolate_profile_data": true, "merge": { "args": [ @@ -5874,6 +6028,68 @@ "--recover-devices", "--avd-config=../../tools/android/avd/proto/generic_android24.textpb" ], + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "leveldb_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cores": "4", + "cpu": "x86-64", + "device_os": null, + "device_type": null, + "os": "Ubuntu-18.04", + "pool": "chromium.tests.avd" + } + ], + "named_caches": [ + { + "name": "generic_android24", + "path": ".android_emulator/generic_android24" + } + ], + "optional_dimensions": { + "60": [ + { + "caches": "generic_android24" + } + ] + }, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { + "args": [ + "--use-persistent-shell", + "--gs-results-bucket=chromium-result-details", + "--recover-devices", + "--avd-config=../../tools/android/avd/proto/generic_android24.textpb" + ], "isolate_profile_data": true, "merge": { "args": [ @@ -7837,7 +8053,6 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/android.nougat-x86-rel.chrome_junit_tests.filter", "--use-persistent-shell" ], "isolate_name": "chrome_junit_tests", @@ -21346,6 +21561,24 @@ "test_id_prefix": "ninja://ui/display:display_unittests/" }, { + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -21619,6 +21852,24 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -22865,6 +23116,24 @@ "test_id_prefix": "ninja://ui/display:display_unittests/" }, { + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -23121,6 +23390,24 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -24983,6 +25270,24 @@ "test_id_prefix": "ninja://ui/display:display_unittests/" }, { + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -25651,6 +25956,24 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -26750,6 +27073,25 @@ "test_id_prefix": "ninja://ui/display:display_unittests/" }, { + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-12" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -27024,6 +27366,25 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-12" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -28282,6 +28643,24 @@ "test_id_prefix": "ninja://chrome/elevation_service:elevation_service_unittests/" }, { + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Windows-10-19045" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -28590,6 +28969,24 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Windows-10-19045" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py"
diff --git a/testing/buildbot/chromium.dev.json b/testing/buildbot/chromium.dev.json index 2cdedbc2..0d52b167c 100644 --- a/testing/buildbot/chromium.dev.json +++ b/testing/buildbot/chromium.dev.json
@@ -302,7 +302,6 @@ } ] }, - "linux-ssd-rel-dev": {}, "mac-arm-rel-dev": { "gtest_tests": [ {
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 99abb2ec..245caf2 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -677,6 +677,24 @@ "test_id_prefix": "ninja://ui/display:display_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "os": "Mac-13" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -933,6 +951,24 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "os": "Mac-13" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -2527,6 +2563,17 @@ "test_id_prefix": "ninja://chrome/elevation_service:elevation_service_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": false + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -2707,6 +2754,17 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": false + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -39222,6 +39280,23 @@ "test_id_prefix": "ninja://crypto:crypto_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -39350,6 +39425,23 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -39980,6 +40072,23 @@ "test_id_prefix": "ninja://crypto:crypto_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -40108,6 +40217,23 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -41188,6 +41314,24 @@ "test_id_prefix": "ninja://ui/display:display_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04", + "ssd": "0" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -41856,6 +42000,24 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04", + "ssd": "0" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -42946,6 +43108,24 @@ "test_id_prefix": "ninja://ui/display:display_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04", + "ssd": "0" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -43608,6 +43788,24 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04", + "ssd": "0" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -45117,6 +45315,26 @@ "test_id_prefix": "ninja://ui/display:display_unittests/" }, { + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04", + "pool": "chromium.tests.no-external-ip" + } + ], + "expiration": 43200, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -45403,6 +45621,26 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04", + "pool": "chromium.tests.no-external-ip" + } + ], + "expiration": 43200, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -47965,6 +48203,25 @@ "test_id_prefix": "ninja://ui/display:display_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "expiration": 21600, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -48237,6 +48494,25 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "expiration": 21600, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -51104,6 +51380,27 @@ "test_id_prefix": "ninja://chrome/elevation_service:elevation_service_unittests/" }, { + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-10-19045", + "pool": "chromium.tests.no-external-ip" + } + ], + "expiration": 43200, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -51498,6 +51795,27 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-10-19045", + "pool": "chromium.tests.no-external-ip" + } + ], + "expiration": 43200, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py"
diff --git a/testing/buildbot/chromium.linux.json b/testing/buildbot/chromium.linux.json index a47622d..1f47c4a 100644 --- a/testing/buildbot/chromium.linux.json +++ b/testing/buildbot/chromium.linux.json
@@ -401,6 +401,23 @@ "test_id_prefix": "ninja://crypto:crypto_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -529,6 +546,23 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -1252,6 +1286,23 @@ "test_id_prefix": "ninja://crypto:crypto_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -1380,6 +1431,23 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -2352,6 +2420,24 @@ "test_id_prefix": "ninja://ui/display:display_unittests/" }, { + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-22.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -2608,6 +2694,24 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-22.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4558,6 +4662,28 @@ "--use-weston", "--ozone-platform=wayland" ], + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-22.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { + "args": [ + "--no-xvfb", + "--use-weston", + "--ozone-platform=wayland" + ], "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -4854,6 +4980,28 @@ "--use-weston", "--ozone-platform=wayland" ], + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-22.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { + "args": [ + "--no-xvfb", + "--use-weston", + "--ozone-platform=wayland" + ], "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -6131,6 +6279,23 @@ "test_id_prefix": "ninja://ui/display:display_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -6372,6 +6537,23 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" },
diff --git a/testing/buildbot/chromium.mac.json b/testing/buildbot/chromium.mac.json index 33d90056..ec39445 100644 --- a/testing/buildbot/chromium.mac.json +++ b/testing/buildbot/chromium.mac.json
@@ -534,6 +534,24 @@ "test_id_prefix": "ninja://ui/display:display_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-10.13.6" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -790,6 +808,24 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-10.13.6" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -2231,6 +2267,24 @@ "test_id_prefix": "ninja://ui/display:display_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-10.14.6" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -2487,6 +2541,24 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-10.14.6" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -3936,6 +4008,24 @@ "test_id_prefix": "ninja://ui/display:display_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-10.15" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -4192,6 +4282,24 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-10.15" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -5664,6 +5772,25 @@ "test_id_prefix": "ninja://ui/display:display_unittests/" }, { + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-11|Mac-10.16" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5936,6 +6063,25 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-11|Mac-10.16" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -7487,6 +7633,25 @@ "test_id_prefix": "ninja://ui/display:display_unittests/" }, { + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-12" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -7759,6 +7924,25 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-12" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -9263,6 +9447,24 @@ "test_id_prefix": "ninja://ui/display:display_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-12" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -9520,6 +9722,24 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-12" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -21130,6 +21350,24 @@ "test_id_prefix": "ninja://ui/display:display_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "os": "Mac-11" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -21386,6 +21624,24 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "os": "Mac-11" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -22795,6 +23051,24 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "os": "Mac-12" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, "test": "events_unittests", "test_id_prefix": "ninja://ui/events:events_unittests/" }, @@ -23066,6 +23340,24 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "arm64", + "os": "Mac-12" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, "test": "libjingle_xmpp_unittests", "test_id_prefix": "ninja://third_party/libjingle_xmpp:libjingle_xmpp_unittests/" },
diff --git a/testing/buildbot/chromium.memory.fyi.json b/testing/buildbot/chromium.memory.fyi.json index 5f4c460..8ded5fd 100644 --- a/testing/buildbot/chromium.memory.fyi.json +++ b/testing/buildbot/chromium.memory.fyi.json
@@ -555,6 +555,24 @@ "test_id_prefix": "ninja://ui/display:display_unittests/" }, { + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -811,6 +829,24 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py"
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json index 12d51ba..03d195b 100644 --- a/testing/buildbot/chromium.memory.json +++ b/testing/buildbot/chromium.memory.json
@@ -624,6 +624,26 @@ "args": [ "--test-launcher-print-test-stdio=always" ], + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { + "args": [ + "--test-launcher-print-test-stdio=always" + ], "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -936,6 +956,26 @@ "args": [ "--test-launcher-print-test-stdio=always" ], + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { + "args": [ + "--test-launcher-print-test-stdio=always" + ], "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -2231,6 +2271,23 @@ "test_id_prefix": "ninja://ui/display:display_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -2513,6 +2570,23 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -3805,6 +3879,26 @@ "args": [ "--test-launcher-print-test-stdio=always" ], + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { + "args": [ + "--test-launcher-print-test-stdio=always" + ], "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -4092,6 +4186,26 @@ "args": [ "--test-launcher-print-test-stdio=always" ], + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { + "args": [ + "--test-launcher-print-test-stdio=always" + ], "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -5592,6 +5706,27 @@ "args": [ "--test-launcher-print-test-stdio=always" ], + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { + "args": [ + "--test-launcher-print-test-stdio=always" + ], "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -5893,6 +6028,27 @@ "args": [ "--test-launcher-print-test-stdio=always" ], + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { + "args": [ + "--test-launcher-print-test-stdio=always" + ], "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -7326,6 +7482,27 @@ "args": [ "--test-launcher-print-test-stdio=always" ], + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { + "args": [ + "--test-launcher-print-test-stdio=always" + ], "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -7627,6 +7804,27 @@ "args": [ "--test-launcher-print-test-stdio=always" ], + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Ubuntu-20.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { + "args": [ + "--test-launcher-print-test-stdio=always" + ], "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -8960,6 +9158,26 @@ "args": [ "--test-launcher-print-test-stdio=always" ], + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { + "args": [ + "--test-launcher-print-test-stdio=always" + ], "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -9291,6 +9509,26 @@ "args": [ "--test-launcher-print-test-stdio=always" ], + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { + "args": [ + "--test-launcher-print-test-stdio=always" + ], "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -10591,6 +10829,27 @@ "args": [ "--test-launcher-print-test-stdio=always" ], + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-12" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { + "args": [ + "--test-launcher-print-test-stdio=always" + ], "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -10893,6 +11152,27 @@ "args": [ "--test-launcher-print-test-stdio=always" ], + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-12" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { + "args": [ + "--test-launcher-print-test-stdio=always" + ], "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -12889,6 +13169,50 @@ "--gs-results-bucket=chromium-result-details", "--recover-devices" ], + "ci_only": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "env_chromium_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "device_os": "N2G48C", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], "merge": { "args": [ "--bucket", @@ -13365,6 +13689,50 @@ "--gs-results-bucket=chromium-result-details", "--recover-devices" ], + "ci_only": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "leveldb_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "device_os": "N2G48C", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], "merge": { "args": [ "--bucket", @@ -17446,6 +17814,29 @@ "--combine-ash-logs-on-bots", "--asan-symbolize-output" ], + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { + "args": [ + "--test-launcher-print-test-stdio=always", + "--combine-ash-logs-on-bots", + "--asan-symbolize-output" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -18222,6 +18613,29 @@ "--combine-ash-logs-on-bots", "--asan-symbolize-output" ], + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { + "args": [ + "--test-launcher-print-test-stdio=always", + "--combine-ash-logs-on-bots", + "--asan-symbolize-output" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -19467,6 +19881,23 @@ "test_id_prefix": "ninja://ui/display:display_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -19708,6 +20139,23 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -20895,6 +21343,23 @@ "test_id_prefix": "ninja://chrome/elevation_service:elevation_service_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Windows-10-19045" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -21188,6 +21653,23 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Windows-10-19045" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" },
diff --git a/testing/buildbot/chromium.win.json b/testing/buildbot/chromium.win.json index 787e97c..3e7ed83 100644 --- a/testing/buildbot/chromium.win.json +++ b/testing/buildbot/chromium.win.json
@@ -824,6 +824,25 @@ "test_id_prefix": "ninja://chrome/elevation_service:elevation_service_unittests/" }, { + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-10-19045" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -1180,6 +1199,25 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-10-19045" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -2923,6 +2961,24 @@ "test_id_prefix": "ninja://chrome/elevation_service:elevation_service_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-10-19045" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -3233,6 +3289,24 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-10-19045" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -4819,6 +4893,25 @@ "test_id_prefix": "ninja://chrome/elevation_service:elevation_service_unittests/" }, { + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-11-22000" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5175,6 +5268,25 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-11-22000" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py"
diff --git a/testing/buildbot/filters/BUILD.gn b/testing/buildbot/filters/BUILD.gn index 65c52b93..07c2858 100644 --- a/testing/buildbot/filters/BUILD.gn +++ b/testing/buildbot/filters/BUILD.gn
@@ -74,12 +74,6 @@ ] } -source_set("chrome_junit_tests_filters") { - testonly = true - - data = [ "//testing/buildbot/filters/android.nougat-x86-rel.chrome_junit_tests.filter" ] -} - source_set("chrome_public_test_apk_filters") { testonly = true @@ -88,6 +82,7 @@ "//testing/buildbot/filters/android.emulator_11.chrome_public_test_apk.filter", "//testing/buildbot/filters/android.emulator_12.chrome_public_test_apk.filter", "//testing/buildbot/filters/android.emulator_12l.chrome_public_test_apk.filter", + "//testing/buildbot/filters/android.emulator_13.chrome_public_test_apk.filter", "//testing/buildbot/filters/android.emulator_n.chrome_public_test_apk.filter", "//testing/buildbot/filters/android.emulator_p.chrome_public_test_apk.filter", ]
diff --git a/testing/buildbot/filters/android.emulator_13.chrome_public_test_apk.filter b/testing/buildbot/filters/android.emulator_13.chrome_public_test_apk.filter new file mode 100644 index 0000000..882db10 --- /dev/null +++ b/testing/buildbot/filters/android.emulator_13.chrome_public_test_apk.filter
@@ -0,0 +1,2 @@ +# crbug.com/1435573 +-org.chromium.chrome.browser.tasks.tab_management.TabGridDialogTest.*
diff --git a/testing/buildbot/filters/android.nougat-x86-rel.chrome_junit_tests.filter b/testing/buildbot/filters/android.nougat-x86-rel.chrome_junit_tests.filter deleted file mode 100644 index c4215eb6..0000000 --- a/testing/buildbot/filters/android.nougat-x86-rel.chrome_junit_tests.filter +++ /dev/null
@@ -1,6 +0,0 @@ -# crbug.com/1378315 --org.chromium.chrome.browser.subscriptions.ImplicitPriceDropSubscriptionsManagerUnitTest* - -# crbug.com/1378779 --org.chromium.chrome.browser.share.link_to_text.LinkToTextHelperTest.hasTextFragment --org.chromium.chrome.browser.share.link_to_text.LinkToTextHelperTest.hasTextFragment_URLWithNoTextSelector
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl index 93af1f48..578d74e 100644 --- a/testing/buildbot/gn_isolate_map.pyl +++ b/testing/buildbot/gn_isolate_map.pyl
@@ -753,6 +753,10 @@ "label": "//testing:empty_main", "type": "additional_compile_target", }, + "env_chromium_unittests": { + "label": "//third_party/leveldatabase:env_chromium_unittests", + "type": "console_test_launcher", + }, "events_unittests": { "label": "//ui/events:events_unittests", "type": "windowed_test_launcher", @@ -1063,6 +1067,10 @@ "label": "//ui/latency:latency_unittests", "type": "console_test_launcher", }, + "leveldb_unittests": { + "label": "//third_party/leveldatabase:leveldb_unittests", + "type": "console_test_launcher", + }, "libcups_unittests": { "label": "//chrome/services/cups_proxy:libcups_unittests", "type": "console_test_launcher",
diff --git a/testing/buildbot/internal.chrome.fyi.json b/testing/buildbot/internal.chrome.fyi.json index db5e79c..304f24a 100644 --- a/testing/buildbot/internal.chrome.fyi.json +++ b/testing/buildbot/internal.chrome.fyi.json
@@ -910,6 +910,28 @@ "test_id_prefix": "ninja://chrome/elevation_service:elevation_service_unittests/" }, { + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": null, + "os": "Windows-11", + "pool": "chrome.tests.arm64" + } + ], + "expiration": 64800, + "hard_timeout": 43200, + "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "env_chromium_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:env_chromium_unittests/" + }, + { "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -1323,6 +1345,28 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": null, + "os": "Windows-11", + "pool": "chrome.tests.arm64" + } + ], + "expiration": 64800, + "hard_timeout": 43200, + "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "leveldb_unittests", + "test_id_prefix": "ninja://third_party/leveldatabase:leveldb_unittests/" + }, + { "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py"
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index 2216b17..3d198fc 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -1416,6 +1416,11 @@ '--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator_12l.chrome_public_test_apk.filter', ], }, + 'android-13-x64-rel': { + 'args': [ + '--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator_13.chrome_public_test_apk.filter', + ], + }, 'android-arm64-proguard-rel': { 'swarming': { 'shards': 25, @@ -2834,6 +2839,12 @@ }, }, }, + 'leveldb_unittests': { + 'remove_from': [ + # TODO(https://crbug.com/1432753): Runs too slowly in this configuration. + 'android-nougat-x86-rel', + ], + }, 'mac_signing_tests': { 'remove_from': [ # This is intentional and explained in the waterfalls.pyl comment for
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index 8c07e86..15fcc905 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -1021,6 +1021,9 @@ }, 'crashpad_tests': {}, 'crypto_unittests': {}, + 'env_chromium_unittests': { + 'ci_only': True, + }, 'events_unittests': {}, 'gcm_unit_tests': {}, 'gin_unittests': {}, @@ -1029,6 +1032,9 @@ 'gwp_asan_unittests': {}, 'ipc_tests': {}, 'latency_unittests': {}, + 'leveldb_unittests': { + 'ci_only': True, + }, 'libjingle_xmpp_unittests': {}, 'liburlpattern_unittests': {}, 'media_unittests': {}, @@ -1263,9 +1269,6 @@ 'use_isolated_scripts_api': True, }, 'chrome_junit_tests': { - 'args': [ - '--test-launcher-filter-file=../../testing/buildbot/filters/android.nougat-x86-rel.chrome_junit_tests.filter', - ], 'mixins': [ 'x86-64', 'linux-bionic',
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index 32d2e99..ccd76f6 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -2661,11 +2661,6 @@ 'gtest_tests': 'chromium_dev_linux_gtests', }, }, - 'linux-ssd-rel-dev': { - 'mixins': [ - 'linux-bionic', - ], - }, 'mac-arm-rel-dev': { 'mixins': [ 'mac_12_arm64',
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 43f280b4..3df53c9 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -1960,6 +1960,26 @@ ] } ], + "BetterUpdateChipsStudy": [ + { + "platforms": [ + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "EnabledWithFinishUpdate", + "params": { + "UpdateTextOptionNumber": "1" + }, + "enable_features": [ + "UpdateTextOptions" + ] + } + ] + } + ], "BiometricAuthPwdFillAndroid": [ { "platforms": [ @@ -11188,9 +11208,9 @@ ], "experiments": [ { - "name": "Enabled_30_0_20230127", + "name": "Enabled_33_0_20230323", "params": { - "reporter_omaha_tag": "30.0" + "reporter_omaha_tag": "33.0" }, "enable_features": [ "ClientSideDetectionTag"
diff --git a/third_party/android_sdk/README.chromium b/third_party/android_sdk/README.chromium index 1804f73..d550ffc 100644 --- a/third_party/android_sdk/README.chromium +++ b/third_party/android_sdk/README.chromium
@@ -34,7 +34,7 @@ * Adding new sdk packages: * Prepare the CIPD yaml files for packages in the cipd/ directory. * Add them to android-sdk-packager buildbucket configuation file: - infra/config/subprojects/chromium/ci/chromium.packager.star + infra/config/subprojects/chromium/ci/chromium.infra.star * Submit the changes into gerrit (See crrev.com/c/2241994 as a reference) * Follow the update instructions to get a build from the CI builder. * Updating this file:
diff --git a/third_party/blink/PRESUBMIT.py b/third_party/blink/PRESUBMIT.py index caee178d..29d9a73 100644 --- a/third_party/blink/PRESUBMIT.py +++ b/third_party/blink/PRESUBMIT.py
@@ -81,12 +81,6 @@ 'third_party/blink/public/mojom/worker/subresource_loader_updater', 'third_party/blink/public/mojom/loader/transferrable_url_loader', 'third_party/blink/public/mojom/loader/code_cache', - # The `shared_storage_worklet_service` and `private_aggregation_host` - # are tentatively included here when shared storage is migrating to - # the blink-style worklet infrastructure. - # TODO(crbug.com/1414951): Remove once the migration completes. - 'third_party/blink/public/mojom/shared_storage/shared_storage_worklet_service', - 'third_party/blink/public/mojom/private_aggregation/private_aggregation_host', 'media/mojo/mojom/interface_factory', 'media/mojo/mojom/audio_decoder', 'media/mojo/mojom/audio_encoder',
diff --git a/third_party/blink/common/BUILD.gn b/third_party/blink/common/BUILD.gn index 1ea03285..c8d71878 100644 --- a/third_party/blink/common/BUILD.gn +++ b/third_party/blink/common/BUILD.gn
@@ -219,6 +219,7 @@ "mediastream/media_stream_controls.cc", "mediastream/media_stream_mojom_traits.cc", "mediastream/media_stream_request.cc", + "messaging/accelerated_static_bitmap_image_mojom_traits.cc", "messaging/cloneable_message.cc", "messaging/cloneable_message_mojom_traits.cc", "messaging/message_port_channel.cc",
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc index 9fd7de1..9e81d69 100644 --- a/third_party/blink/common/features.cc +++ b/third_party/blink/common/features.cc
@@ -833,6 +833,10 @@ "KalmanDirectionCutOff", base::FEATURE_DISABLED_BY_DEFAULT); +BASE_FEATURE(kAcceleratedStaticBitmapImageSerialization, + "AcceleratedStaticBitmapImageSerialization", + base::FEATURE_ENABLED_BY_DEFAULT); + const char kSkipTouchEventFilterTypeParamName[] = "type"; const char kSkipTouchEventFilterTypeParamValueDiscrete[] = "discrete"; const char kSkipTouchEventFilterTypeParamValueAll[] = "all";
diff --git a/third_party/blink/common/interest_group/ad_auction_currencies.cc b/third_party/blink/common/interest_group/ad_auction_currencies.cc index d467a2d..fa9346e 100644 --- a/third_party/blink/common/interest_group/ad_auction_currencies.cc +++ b/third_party/blink/common/interest_group/ad_auction_currencies.cc
@@ -18,16 +18,17 @@ base::IsAsciiUpper(code[2]); } -bool IsValidOrUnspecifiedAdCurrencyCode(const std::string& input) { - return input == kUnspecifiedAdCurrency || IsValidAdCurrencyCode(input); -} - -bool VerifyAdCurrencyCode(const std::string& expected, - const std::string& actual) { +bool VerifyAdCurrencyCode(const absl::optional<AdCurrency>& expected, + const absl::optional<AdCurrency>& actual) { // TODO(morlovich): Eventually we want to drop the compatibility // exceptions. - return expected == actual || expected == kUnspecifiedAdCurrency || - actual == kUnspecifiedAdCurrency; + return !expected.has_value() || !actual.has_value() || + expected->currency_code() == actual->currency_code(); +} + +std::string PrintableAdCurrency(const absl::optional<AdCurrency>& currency) { + return currency.has_value() ? currency->currency_code() + : kUnspecifiedAdCurrency; } } // namespace blink
diff --git a/third_party/blink/common/interest_group/ad_auction_currencies_unittest.cc b/third_party/blink/common/interest_group/ad_auction_currencies_unittest.cc index d2bf4e6..1b47208 100644 --- a/third_party/blink/common/interest_group/ad_auction_currencies_unittest.cc +++ b/third_party/blink/common/interest_group/ad_auction_currencies_unittest.cc
@@ -18,24 +18,19 @@ EXPECT_FALSE(IsValidAdCurrencyCode("ABc")); } -TEST(AdAuctionCurrenciesTest, IsValidOrUnspecifiedAdCurrencyCode) { - EXPECT_FALSE(IsValidOrUnspecifiedAdCurrencyCode("A")); - EXPECT_FALSE(IsValidOrUnspecifiedAdCurrencyCode("ABCD")); +TEST(AdAuctionCurrenciesTest, VerifyAdCurrencyCode) { + EXPECT_FALSE( + VerifyAdCurrencyCode(AdCurrency::From("ABC"), AdCurrency::From("CBA"))); EXPECT_TRUE( - IsValidOrUnspecifiedAdCurrencyCode(blink::kUnspecifiedAdCurrency)); - EXPECT_TRUE(IsValidOrUnspecifiedAdCurrencyCode("ABC")); - EXPECT_FALSE(IsValidOrUnspecifiedAdCurrencyCode("aBC")); - EXPECT_FALSE(IsValidOrUnspecifiedAdCurrencyCode("AbC")); - EXPECT_FALSE(IsValidOrUnspecifiedAdCurrencyCode("ABc")); + VerifyAdCurrencyCode(AdCurrency::From("ABC"), AdCurrency::From("ABC"))); + EXPECT_TRUE(VerifyAdCurrencyCode(AdCurrency::From("ABC"), absl::nullopt)); + EXPECT_TRUE(VerifyAdCurrencyCode(absl::nullopt, AdCurrency::From("ABC"))); + EXPECT_TRUE(VerifyAdCurrencyCode(absl::nullopt, absl::nullopt)); } -TEST(AdAuctionCurrenciesTest, VerifyAdCurrencyCode) { - EXPECT_FALSE(VerifyAdCurrencyCode("ABC", "CBA")); - EXPECT_TRUE(VerifyAdCurrencyCode("ABC", "ABC")); - EXPECT_TRUE(VerifyAdCurrencyCode("ABC", blink::kUnspecifiedAdCurrency)); - EXPECT_TRUE(VerifyAdCurrencyCode(blink::kUnspecifiedAdCurrency, "ABC")); - EXPECT_TRUE(VerifyAdCurrencyCode(blink::kUnspecifiedAdCurrency, - blink::kUnspecifiedAdCurrency)); +TEST(AdAuctionCurrenciesTest, PrintableAdCurrency) { + EXPECT_EQ(kUnspecifiedAdCurrency, PrintableAdCurrency(absl::nullopt)); + EXPECT_EQ("USD", PrintableAdCurrency(AdCurrency::From("USD"))); } } // namespace blink
diff --git a/third_party/blink/common/interest_group/auction_config_mojom_traits.cc b/third_party/blink/common/interest_group/auction_config_mojom_traits.cc index b854c85..ea6a0ae 100644 --- a/third_party/blink/common/interest_group/auction_config_mojom_traits.cc +++ b/third_party/blink/common/interest_group/auction_config_mojom_traits.cc
@@ -112,6 +112,20 @@ return true; } +bool StructTraits<blink::mojom::AdCurrencyDataView, blink::AdCurrency>::Read( + blink::mojom::AdCurrencyDataView data, + blink::AdCurrency* out) { + std::string currency_code; + if (!data.ReadCurrencyCode(¤cy_code)) { + return false; + } + if (!blink::IsValidAdCurrencyCode(currency_code)) { + return false; + } + *out = blink::AdCurrency::From(currency_code); + return true; +} + bool StructTraits<blink::mojom::AuctionAdConfigBuyerCurrenciesDataView, blink::AuctionConfig::BuyerCurrencies>:: Read(blink::mojom::AuctionAdConfigBuyerCurrenciesDataView data,
diff --git a/third_party/blink/common/interest_group/auction_config_mojom_traits_test.cc b/third_party/blink/common/interest_group/auction_config_mojom_traits_test.cc index 98942bc..2db1139 100644 --- a/third_party/blink/common/interest_group/auction_config_mojom_traits_test.cc +++ b/third_party/blink/common/interest_group/auction_config_mojom_traits_test.cc
@@ -43,6 +43,10 @@ std::tie(b.all_buyers_timeout, b.per_buyer_timeouts); } +bool operator==(const AdCurrency& a, const AdCurrency& b) { + return a.currency_code() == b.currency_code(); +} + bool operator==(const AuctionConfig::BuyerCurrencies& a, const AuctionConfig::BuyerCurrencies& b) { return std::tie(a.all_buyers_currency, a.per_buyer_currencies) == @@ -151,13 +155,13 @@ AuctionConfig::BuyerCurrencies buyer_currencies; buyer_currencies.per_buyer_currencies.emplace(); - (*buyer_currencies.per_buyer_currencies)[buyer] = "CAD"; - buyer_currencies.all_buyers_currency = "USD"; + (*buyer_currencies.per_buyer_currencies)[buyer] = AdCurrency::From("CAD"); + buyer_currencies.all_buyers_currency = AdCurrency::From("USD"); non_shared_params.buyer_currencies = AuctionConfig::MaybePromiseBuyerCurrencies::FromValue( std::move(buyer_currencies)); - non_shared_params.seller_currency = "EUR"; + non_shared_params.seller_currency = AdCurrency::From("EUR"); AuctionConfig::BuyerTimeouts buyer_cumulative_timeouts; buyer_cumulative_timeouts.per_buyer_timeouts.emplace(); @@ -267,6 +271,16 @@ return success; } +bool SerializeAndDeserialize(const AdCurrency& in) { + AdCurrency out; + bool success = + mojo::test::SerializeAndDeserialize<blink::mojom::AdCurrency>(in, out); + if (success) { + EXPECT_EQ(in.currency_code(), out.currency_code()); + } + return success; +} + TEST(AuctionConfigMojomTraitsTest, Empty) { AuctionConfig auction_config; EXPECT_FALSE(SerializeAndDeserialize(auction_config)); @@ -550,12 +564,14 @@ TEST(AuctionConfigMojomTraitsTest, BuyerCurrencies) { { AuctionConfig::BuyerCurrencies value; - value.all_buyers_currency.emplace("EUR"); + value.all_buyers_currency = blink::AdCurrency::From("EUR"); value.per_buyer_currencies.emplace(); value.per_buyer_currencies->emplace( - url::Origin::Create(GURL("https://example.co.uk")), "GBP"); + url::Origin::Create(GURL("https://example.co.uk")), + blink::AdCurrency::From("GBP")); value.per_buyer_currencies->emplace( - url::Origin::Create(GURL("https://example.ca")), "CAD"); + url::Origin::Create(GURL("https://example.ca")), + blink::AdCurrency::From("CAD")); EXPECT_TRUE(SerializeAndDeserialize(value)); } { @@ -564,6 +580,23 @@ } } +TEST(AuctionConfigMojomTraitsTest, AdCurrency) { + { + AdCurrency value = AdCurrency::From("EUR"); + EXPECT_TRUE(SerializeAndDeserialize(value)); + } + { + AdCurrency value; + value.SetCurrencyCodeForTesting("eur"); + EXPECT_FALSE(SerializeAndDeserialize(value)); + } + { + AdCurrency value; + value.SetCurrencyCodeForTesting("EURO"); + EXPECT_FALSE(SerializeAndDeserialize(value)); + } +} + TEST(AuctionConfigMojomTraitsTest, MaybePromiseDirectFromSellerSignals) { { AuctionConfig::MaybePromiseDirectFromSellerSignals signals =
diff --git a/third_party/blink/common/messaging/accelerated_static_bitmap_image_mojom_traits.cc b/third_party/blink/common/messaging/accelerated_static_bitmap_image_mojom_traits.cc new file mode 100644 index 0000000..fd66a20 --- /dev/null +++ b/third_party/blink/common/messaging/accelerated_static_bitmap_image_mojom_traits.cc
@@ -0,0 +1,81 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/public/common/messaging/accelerated_static_bitmap_image_mojom_traits.h" + +#include "mojo/public/cpp/bindings/remote.h" +#include "mojo/public/cpp/bindings/self_owned_receiver.h" + +namespace { + +using Callback = base::OnceCallback<void(const gpu::SyncToken&)>; + +// Implements mojom::ImageReleaseCallback. +// The passed in callback will be destroyed once the mojo pipe +// is destroyed or the callback is invoked via the Release interface +// call. +// It is required that desruction of the passed callback is enough to +// release the image. E.g. if the reference is bound to it. +class ReleaseCallbackImpl : public blink::mojom::ImageReleaseCallback { + public: + explicit ReleaseCallbackImpl(Callback callback) + : callback_(std::move(callback)) {} + + void Release(const gpu::SyncToken& sync_token) override { + std::move(callback_).Run(sync_token); + } + + private: + Callback callback_; +}; + +void Release( + mojo::PendingRemote<blink::mojom::ImageReleaseCallback> pending_remote, + const gpu::SyncToken& sync_token) { + mojo::Remote<blink::mojom::ImageReleaseCallback> remote( + std::move(pending_remote)); + remote->Release(sync_token); +} + +} // namespace + +namespace mojo { + +// static +mojo::PendingRemote<blink::mojom::ImageReleaseCallback> StructTraits< + blink::mojom::AcceleratedStaticBitmapImage::DataView, + blink::AcceleratedImageInfo>::release_callback(blink::AcceleratedImageInfo& + input) { + mojo::PendingRemote<blink::mojom::ImageReleaseCallback> callback; + MakeSelfOwnedReceiver( + std::make_unique<ReleaseCallbackImpl>(std::move(input.release_callback)), + callback.InitWithNewPipeAndPassReceiver()); + return callback; +} + +bool StructTraits<blink::mojom::AcceleratedStaticBitmapImage::DataView, + blink::AcceleratedImageInfo>:: + Read(blink::mojom::AcceleratedStaticBitmapImage::DataView data, + blink::AcceleratedImageInfo* out) { + if (!data.ReadMailboxHolder(&out->mailbox_holder) || + !data.ReadImageInfo(&out->image_info)) { + return false; + } + + out->usage = data.usage(); + out->is_origin_top_left = data.is_origin_top_left(); + out->supports_display_compositing = data.supports_display_compositing(); + out->is_overlay_candidate = data.is_overlay_candidate(); + + auto callback = data.TakeReleaseCallback< + mojo::PendingRemote<blink::mojom::ImageReleaseCallback>>(); + if (!callback) { + return false; + } + out->release_callback = base::BindOnce(&Release, std::move(callback)); + + return true; +} + +} // namespace mojo
diff --git a/third_party/blink/public/common/BUILD.gn b/third_party/blink/public/common/BUILD.gn index aaec90a..c79efe1 100644 --- a/third_party/blink/public/common/BUILD.gn +++ b/third_party/blink/public/common/BUILD.gn
@@ -236,6 +236,8 @@ "mediastream/media_stream_controls.h", "mediastream/media_stream_mojom_traits.h", "mediastream/media_stream_request.h", + "messaging/accelerated_image_info.h", + "messaging/accelerated_static_bitmap_image_mojom_traits.h", "messaging/cloneable_message.h", "messaging/cloneable_message_mojom_traits.h", "messaging/message_port_channel.h", @@ -357,6 +359,7 @@ "//cc", "//components/shared_highlighting/core/common", "//components/viz/common", + "//gpu/command_buffer/common", "//mojo/public/cpp/bindings", "//mojo/public/cpp/system", "//mojo/public/mojom/base",
diff --git a/third_party/blink/public/common/DEPS b/third_party/blink/public/common/DEPS index 74484c759..fbd7e3b9 100644 --- a/third_party/blink/public/common/DEPS +++ b/third_party/blink/public/common/DEPS
@@ -12,6 +12,7 @@ "+cc/trees/browser_controls_params.h", "+components/viz/common/surfaces/local_surface_id.h", "+components/viz/common/view_transition_element_resource_id.h", + "+gpu/command_buffer/common/mailbox_holder.h", "+net", "+media", "+mojo",
diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h index 496d8918..f1d5784 100644 --- a/third_party/blink/public/common/features.h +++ b/third_party/blink/public/common/features.h
@@ -320,6 +320,12 @@ // blocking. BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(kInputTargetClientHighPriority); +// Enables passing of mailbox backed Accelerated bitmap images to be passed +// cross-process as mailbox references instead of serialized bitmaps in +// shared memory. +BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE( + kAcceleratedStaticBitmapImageSerialization); + // Enables resampling GestureScroll events on compositor thread. // Uses the kPredictorName* values in ui_base_features.h as the 'predictor' // feature param.
diff --git a/third_party/blink/public/common/interest_group/ad_auction_currencies.h b/third_party/blink/public/common/interest_group/ad_auction_currencies.h index 56253be..76c2113 100644 --- a/third_party/blink/public/common/interest_group/ad_auction_currencies.h +++ b/third_party/blink/public/common/interest_group/ad_auction_currencies.h
@@ -7,6 +7,8 @@ #include <string> +#include "base/check.h" +#include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/public/common/common_export.h" namespace blink { @@ -15,21 +17,45 @@ // Does not accept kUnspecifiedAdCurrency. BLINK_COMMON_EXPORT bool IsValidAdCurrencyCode(const std::string& input); -// True if the input is a currency code in format that FLEDGE expects or -// kUnspecifiedAdCurrency. -BLINK_COMMON_EXPORT bool IsValidOrUnspecifiedAdCurrencyCode( - const std::string& input); +// A wrapper type for currency codes used in FLEDGE auctions. +class BLINK_COMMON_EXPORT AdCurrency { + public: + // Precondiiton: `IsValidAdCurrencyCode(currency_code)`. + static AdCurrency From(const std::string& currency_code) { + DCHECK(IsValidAdCurrencyCode(currency_code)) << currency_code; + AdCurrency result; + result.currency_code_ = currency_code; + return result; + } + + // This is either a valid currency code or an empty string, unless + // SetCurrencyCodeForTesting is used. + const std::string& currency_code() const { return currency_code_; } + + // Lets one set invalid values to cover mojo checking. + void SetCurrencyCodeForTesting(const std::string& in) { currency_code_ = in; } + + private: + std::string currency_code_; +}; // Returns true if `actual` currency should be accepted under expectation // `expected; this can happen if they match or if any of them is unspecified. -BLINK_COMMON_EXPORT bool VerifyAdCurrencyCode(const std::string& expected, - const std::string& actual); +BLINK_COMMON_EXPORT bool VerifyAdCurrencyCode( + const absl::optional<AdCurrency>& expected, + const absl::optional<AdCurrency>& actual); // Magical value to denote that a party in the auction didn't specify // currency value or expectation. It can't be provided directly, but it's meant // to be human-readable. BLINK_COMMON_EXPORT extern const char* const kUnspecifiedAdCurrency; +// Converts a maybe-unspecified ad currency into a form suitable for JS strings +// or error messages --- e.g. unspecified value gets expanded out to +// kUnspecifiedAdCurrency for readability. +BLINK_COMMON_EXPORT std::string PrintableAdCurrency( + const absl::optional<AdCurrency>& currency); + } // namespace blink #endif // THIRD_PARTY_BLINK_PUBLIC_COMMON_INTEREST_GROUP_AD_AUCTION_CURRENCIES_H_
diff --git a/third_party/blink/public/common/interest_group/auction_config.h b/third_party/blink/public/common/interest_group/auction_config.h index fd1aa2e..a456c67 100644 --- a/third_party/blink/public/common/interest_group/auction_config.h +++ b/third_party/blink/public/common/interest_group/auction_config.h
@@ -18,6 +18,7 @@ #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/abseil-cpp/absl/types/variant.h" #include "third_party/blink/public/common/common_export.h" +#include "third_party/blink/public/common/interest_group/ad_auction_currencies.h" #include "third_party/blink/public/common/interest_group/seller_capabilities.h" #include "third_party/blink/public/mojom/interest_group/interest_group_types.mojom-shared.h" #include "url/gurl.h" @@ -141,10 +142,10 @@ // Typemapped to blink::mojom::AuctionAdConfigBuyerCurrencies struct BuyerCurrencies { // Fallback value used for buyers not in `per_buyer_currencies`. - absl::optional<std::string> all_buyers_currency; + absl::optional<AdCurrency> all_buyers_currency; // Currency expectations for buyer per their origin. - absl::optional<base::flat_map<url::Origin, std::string>> + absl::optional<base::flat_map<url::Origin, AdCurrency>> per_buyer_currencies; }; @@ -216,7 +217,7 @@ // Expectation of currency seller worklet in this auction will provide when // modified bids or converting them for reporting. - absl::optional<std::string> seller_currency; + absl::optional<AdCurrency> seller_currency; // Expectation of currency for bids made by various participating buyers. MaybePromiseBuyerCurrencies buyer_currencies;
diff --git a/third_party/blink/public/common/interest_group/auction_config_mojom_traits.h b/third_party/blink/public/common/interest_group/auction_config_mojom_traits.h index dfd5a2c..4ce7bb8 100644 --- a/third_party/blink/public/common/interest_group/auction_config_mojom_traits.h +++ b/third_party/blink/public/common/interest_group/auction_config_mojom_traits.h
@@ -13,6 +13,7 @@ #include "third_party/abseil-cpp/absl/numeric/int128.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/public/common/common_export.h" +#include "third_party/blink/public/common/interest_group/ad_auction_currencies.h" #include "third_party/blink/public/common/interest_group/auction_config.h" #include "third_party/blink/public/mojom/interest_group/interest_group_types.mojom-shared.h" @@ -149,14 +150,25 @@ template <> struct BLINK_COMMON_EXPORT + StructTraits<blink::mojom::AdCurrencyDataView, blink::AdCurrency> { + static const std::string& currency_code(const blink::AdCurrency& params) { + return params.currency_code(); + } + + static bool Read(blink::mojom::AdCurrencyDataView data, + blink::AdCurrency* out); +}; + +template <> +struct BLINK_COMMON_EXPORT StructTraits<blink::mojom::AuctionAdConfigBuyerCurrenciesDataView, blink::AuctionConfig::BuyerCurrencies> { - static const absl::optional<base::flat_map<url::Origin, std::string>>& + static const absl::optional<base::flat_map<url::Origin, blink::AdCurrency>>& per_buyer_currencies(const blink::AuctionConfig::BuyerCurrencies& params) { return params.per_buyer_currencies; } - static const absl::optional<std::string>& all_buyers_currency( + static const absl::optional<blink::AdCurrency>& all_buyers_currency( const blink::AuctionConfig::BuyerCurrencies& params) { return params.all_buyers_currency; } @@ -237,7 +249,7 @@ return params.buyer_timeouts; } - static const absl::optional<std::string>& seller_currency( + static const absl::optional<blink::AdCurrency>& seller_currency( const blink::AuctionConfig::NonSharedParams& params) { return params.seller_currency; }
diff --git a/third_party/blink/public/common/messaging/accelerated_image_info.h b/third_party/blink/public/common/messaging/accelerated_image_info.h new file mode 100644 index 0000000..0164136d --- /dev/null +++ b/third_party/blink/public/common/messaging/accelerated_image_info.h
@@ -0,0 +1,32 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_PUBLIC_COMMON_MESSAGING_ACCELERATED_IMAGE_INFO_H_ +#define THIRD_PARTY_BLINK_PUBLIC_COMMON_MESSAGING_ACCELERATED_IMAGE_INFO_H_ + +#include "base/functional/callback.h" +#include "gpu/command_buffer/common/mailbox_holder.h" +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "third_party/blink/public/common/common_export.h" +#include "third_party/skia/include/core/SkImage.h" + +namespace blink { + +// This struct represents all the information needed to create an +// AcceleratedStaticImageBitmap in the receiving process. +// See third_party/blink/public/mojom/messaging/static_bitmap_image.mojom +// for details. +struct BLINK_COMMON_EXPORT AcceleratedImageInfo { + gpu::MailboxHolder mailbox_holder; + uint32_t usage; + SkImageInfo image_info; + bool is_origin_top_left; + bool supports_display_compositing; + bool is_overlay_candidate; + base::OnceCallback<void(const gpu::SyncToken& sync_token)> release_callback; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_PUBLIC_COMMON_MESSAGING_ACCELERATED_IMAGE_INFO_H_
diff --git a/third_party/blink/public/common/messaging/accelerated_static_bitmap_image_mojom_traits.h b/third_party/blink/public/common/messaging/accelerated_static_bitmap_image_mojom_traits.h new file mode 100644 index 0000000..eaf2a12 --- /dev/null +++ b/third_party/blink/public/common/messaging/accelerated_static_bitmap_image_mojom_traits.h
@@ -0,0 +1,52 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_PUBLIC_COMMON_MESSAGING_ACCELERATED_STATIC_BITMAP_IMAGE_MOJOM_TRAITS_H_ +#define THIRD_PARTY_BLINK_PUBLIC_COMMON_MESSAGING_ACCELERATED_STATIC_BITMAP_IMAGE_MOJOM_TRAITS_H_ + +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "third_party/blink/public/common/messaging/accelerated_image_info.h" +#include "third_party/blink/public/mojom/messaging/static_bitmap_image.mojom.h" + +namespace mojo { + +template <> +struct BLINK_COMMON_EXPORT + StructTraits<blink::mojom::AcceleratedStaticBitmapImage::DataView, + blink::AcceleratedImageInfo> { + static const gpu::MailboxHolder& mailbox_holder( + const blink::AcceleratedImageInfo& input) { + return input.mailbox_holder; + } + + static uint32_t usage(const blink::AcceleratedImageInfo& input) { + return input.usage; + } + + static SkImageInfo image_info(const blink::AcceleratedImageInfo& input) { + return input.image_info; + } + + static bool is_origin_top_left(const blink::AcceleratedImageInfo& input) { + return input.is_origin_top_left; + } + + static bool supports_display_compositing( + const blink::AcceleratedImageInfo& input) { + return input.supports_display_compositing; + } + + static bool is_overlay_candidate(const blink::AcceleratedImageInfo& input) { + return input.is_overlay_candidate; + } + + static mojo::PendingRemote<blink::mojom::ImageReleaseCallback> + release_callback(blink::AcceleratedImageInfo& input); + + static bool Read(blink::mojom::AcceleratedStaticBitmapImage::DataView data, + blink::AcceleratedImageInfo* out); +}; +} // namespace mojo + +#endif // THIRD_PARTY_BLINK_PUBLIC_COMMON_MESSAGING_TRANSFERABLE_MESSAGE_MOJOM_TRAITS_H_
diff --git a/third_party/blink/public/common/messaging/transferable_message.h b/third_party/blink/public/common/messaging/transferable_message.h index 235894d5..ed818e79 100644 --- a/third_party/blink/public/common/messaging/transferable_message.h +++ b/third_party/blink/public/common/messaging/transferable_message.h
@@ -14,6 +14,7 @@ #include "third_party/blink/public/mojom/array_buffer/array_buffer_contents.mojom.h" #include "third_party/blink/public/mojom/blob/blob.mojom.h" #include "third_party/blink/public/mojom/messaging/delegated_capability.mojom-shared.h" +#include "third_party/blink/public/mojom/messaging/static_bitmap_image.mojom.h" #include "third_party/blink/public/mojom/messaging/task_attribution_id.mojom.h" #include "third_party/blink/public/mojom/messaging/user_activation_snapshot.mojom.h" #include "third_party/skia/include/core/SkBitmap.h" @@ -36,7 +37,8 @@ std::vector<mojom::SerializedArrayBufferContentsPtr> array_buffer_contents_array; // The contents of any ImageBitmaps being transferred as part of this message. - std::vector<SkBitmap> image_bitmap_contents_array; + std::vector<mojom::SerializedStaticBitmapImagePtr> + image_bitmap_contents_array; // The state of user activation. mojom::UserActivationSnapshotPtr user_activation;
diff --git a/third_party/blink/public/common/messaging/transferable_message_mojom_traits.h b/third_party/blink/public/common/messaging/transferable_message_mojom_traits.h index c21ae51..9d8b92d 100644 --- a/third_party/blink/public/common/messaging/transferable_message_mojom_traits.h +++ b/third_party/blink/public/common/messaging/transferable_message_mojom_traits.h
@@ -6,6 +6,7 @@ #define THIRD_PARTY_BLINK_PUBLIC_COMMON_MESSAGING_TRANSFERABLE_MESSAGE_MOJOM_TRAITS_H_ #include "skia/public/mojom/bitmap_skbitmap_mojom_traits.h" +#include "third_party/blink/public/common/messaging/accelerated_static_bitmap_image_mojom_traits.h" #include "third_party/blink/public/common/messaging/cloneable_message_mojom_traits.h" #include "third_party/blink/public/common/messaging/message_port_descriptor_mojom_traits.h" #include "third_party/blink/public/common/messaging/task_attribution_id_mojom_traits.h" @@ -39,9 +40,9 @@ return std::move(input.array_buffer_contents_array); } - static const std::vector<SkBitmap>& image_bitmap_contents_array( - blink::TransferableMessage& input) { - return input.image_bitmap_contents_array; + static std::vector<blink::mojom::SerializedStaticBitmapImagePtr> + image_bitmap_contents_array(blink::TransferableMessage& input) { + return std::move(input.image_bitmap_contents_array); } static const blink::mojom::UserActivationSnapshotPtr& user_activation(
diff --git a/third_party/blink/public/mojom/BUILD.gn b/third_party/blink/public/mojom/BUILD.gn index 56442cb..b1145a98 100644 --- a/third_party/blink/public/mojom/BUILD.gn +++ b/third_party/blink/public/mojom/BUILD.gn
@@ -646,6 +646,16 @@ [ "//third_party/blink/public/common/url_pattern_mojom_traits.h" ] traits_public_deps = [ "//third_party/blink/public/common:headers" ] }, + { + types = [ + { + mojom = "blink.mojom.AdCurrency" + cpp = "::blink::AdCurrency" + }, + ] + traits_headers = [ "//third_party/blink/public/common/interest_group/auction_config_mojom_traits.h" ] + traits_public_deps = [ "//url/mojom:mojom_traits" ] + }, ] cpp_typemaps = [ { @@ -1241,6 +1251,7 @@ "messaging/cloneable_message.mojom", "messaging/delegated_capability.mojom", "messaging/message_port_descriptor.mojom", + "messaging/static_bitmap_image.mojom", "messaging/task_attribution_id.mojom", "messaging/transferable_message.mojom", "messaging/user_activation_snapshot.mojom", @@ -1284,6 +1295,7 @@ ":web_feature_mojo_bindings", "//cc/mojom", "//components/payments/mojom", + "//gpu/ipc/common:interfaces", "//mojo/public/mojom/base", "//services/network/public/mojom", "//services/service_manager/public/mojom", @@ -1344,6 +1356,20 @@ ] traits_private_headers = [ "//third_party/blink/public/common/messaging/task_attribution_id_mojom_traits.h" ] }, + { + types = [ + { + mojom = "blink.mojom.AcceleratedStaticBitmapImage" + cpp = "::blink::AcceleratedImageInfo" + move_only = true + }, + ] + traits_headers = [ + "//third_party/blink/public/common/messaging/accelerated_image_info.h", + ] + traits_private_headers = [ "//third_party/blink/public/common/messaging/accelerated_static_bitmap_image_mojom_traits.h" ] + traits_deps = [ "//gpu/ipc/common" ] + }, ] cpp_typemaps = [
diff --git a/third_party/blink/public/mojom/interest_group/interest_group_types.mojom b/third_party/blink/public/mojom/interest_group/interest_group_types.mojom index 77636c4..0132932 100644 --- a/third_party/blink/public/mojom/interest_group/interest_group_types.mojom +++ b/third_party/blink/public/mojom/interest_group/interest_group_types.mojom
@@ -229,14 +229,19 @@ AuctionAdConfigBuyerTimeouts value; }; +struct AdCurrency { + // Must meet blink::IsValidAdCurrencyCode + string currency_code; +}; + // See blink::AuctionConfig::BuyerCurrencies struct AuctionAdConfigBuyerCurrencies { // Requirement for bid currency that, if specified, will apply to all bids // made by buyers not specified in `per_buyer_currencies`. - string? all_buyers_currency; + AdCurrency? all_buyers_currency; // Can provide a requirement for bid currency for buyers by origin. - map<url.mojom.Origin, string>? per_buyer_currencies; + map<url.mojom.Origin, AdCurrency>? per_buyer_currencies; }; // See blink::AuctionConfig::MaybePromiseBuyerCurrencies @@ -313,7 +318,7 @@ // Expectations for currency provided by seller when modifying bids for // parent auctions or to help with mixed-currency reporting. If this is set, // any currency annotation from seller will be checked against it. - string? seller_currency; + AdCurrency? seller_currency; // Expectations for currencies used by buyers to bid. If a currency is // specified for a buyer here, and they annotate their bid with a currency,
diff --git a/third_party/blink/public/mojom/messaging/static_bitmap_image.mojom b/third_party/blink/public/mojom/messaging/static_bitmap_image.mojom new file mode 100644 index 0000000..7a3f66e --- /dev/null +++ b/third_party/blink/public/mojom/messaging/static_bitmap_image.mojom
@@ -0,0 +1,55 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +module blink.mojom; + +import "skia/public/mojom/bitmap.mojom"; +import "gpu/ipc/common/mailbox_holder.mojom"; +import "gpu/ipc/common/sync_token.mojom"; +import "skia/public/mojom/image_info.mojom"; + +// This interface is used to manage the lifetime of the +// AcceleratedStaticBitmapImage transferred in the TranferableMessage. +// While the message pipe is open, the sender will keep the reference +// alive. +// The only interface method is used to update the source image sync token +// so that reference management in the receiver process and the destruction +// in the sender process are ordered correctly in the GPU command buffer. +// It is also fine to simply destroy the Remote without calling the method. +// In that case the image will be released without any updates to the SyncToken. +interface ImageReleaseCallback { + // Updates the sync token on the associated AcceleratedStaticBitmapImage + // and releases it. + Release(gpu.mojom.SyncToken token); +}; + +// Holds all information, necessary to recreate the accelerated image. +struct AcceleratedStaticBitmapImage { + // Mailbox holder contains SharedImage reference: + // mailbox, sync token and texture target. + gpu.mojom.MailboxHolder mailbox_holder; + // Shared image usage: a bitmask identifying which API(s) + // the SharedImage may be used with. + // See gpu/command_buffer/common/shared_image_usage.h + uint32 usage; + // Common image metadata. + skia.mojom.ImageInfo image_info; + // Indicates the orientation of the image. + bool is_origin_top_left; + // Indicates if the display compositing may be used with this image. + bool supports_display_compositing; + // Indicates if the image is an overlay candidate. + bool is_overlay_candidate; + // Resource lifetime management callback. Until this pending remote is + // destroyed or the callback is called the sender shall keep the + // resource alive. + pending_remote<ImageReleaseCallback> release_callback; +}; + +// StaticBitmapImage may be sent as a software SkBitmap or +// as a GPU backed texture reference. +union SerializedStaticBitmapImage { + skia.mojom.BitmapN32 bitmap; + AcceleratedStaticBitmapImage accelerated_image; +};
diff --git a/third_party/blink/public/mojom/messaging/transferable_message.mojom b/third_party/blink/public/mojom/messaging/transferable_message.mojom index ad6316b2..92948ee 100644 --- a/third_party/blink/public/mojom/messaging/transferable_message.mojom +++ b/third_party/blink/public/mojom/messaging/transferable_message.mojom
@@ -4,7 +4,6 @@ module blink.mojom; -import "skia/public/mojom/bitmap.mojom"; import "third_party/blink/public/mojom/array_buffer/array_buffer_contents.mojom"; import "third_party/blink/public/mojom/blob/serialized_blob.mojom"; import "third_party/blink/public/mojom/messaging/cloneable_message.mojom"; @@ -12,6 +11,7 @@ import "third_party/blink/public/mojom/messaging/message_port_descriptor.mojom"; import "third_party/blink/public/mojom/messaging/user_activation_snapshot.mojom"; import "third_party/blink/public/mojom/messaging/task_attribution_id.mojom"; +import "third_party/blink/public/mojom/messaging/static_bitmap_image.mojom"; // A MessagePort is represented as a raw mojo message pipe, as such no interface // definition exists for it here. Messages on this pipe are serialized versions @@ -32,7 +32,7 @@ // Any ArrayBuffers being transferred as part of this message. array<SerializedArrayBufferContents> array_buffer_contents_array; // Any ImageBitmaps being transferred as part of this message. - array<skia.mojom.BitmapN32> image_bitmap_contents_array; + array<SerializedStaticBitmapImage> image_bitmap_contents_array; // The user activation state, null if the frame isn't providing it. UserActivationSnapshot? user_activation; // What capability, if any, is delegated to the destination frame.
diff --git a/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom b/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom index e89e62a..da2ce88 100644 --- a/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom +++ b/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom
@@ -3885,6 +3885,7 @@ kTextWrapBalance = 4544, kTextWrapBalanceFail = 4545, kAttributionReportingCrossAppWeb = 4546, + kSecurePaymentConfirmationActivationlessShow = 4547, // Add new features immediately above this line. Don't change assigned // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/blink/public/platform/web_vector.h b/third_party/blink/public/platform/web_vector.h index 2ffc12d..1d0900bb 100644 --- a/third_party/blink/public/platform/web_vector.h +++ b/third_party/blink/public/platform/web_vector.h
@@ -95,7 +95,9 @@ WebVector(const WebVector<T>& other) : data_(other.data_) {} - template <typename C> + template <typename C, + typename = decltype(std::declval<C>().begin()), + typename = decltype(std::declval<C>().end())> WebVector(const C& other) : data_(other.begin(), other.end()) {} WebVector(WebVector<T>&& other) noexcept { Swap(other); }
diff --git a/third_party/blink/public/web/web_shared_storage_worklet_thread.h b/third_party/blink/public/web/web_shared_storage_worklet_thread.h index 5831369..d3b7bdc 100644 --- a/third_party/blink/public/web/web_shared_storage_worklet_thread.h +++ b/third_party/blink/public/web/web_shared_storage_worklet_thread.h
@@ -7,8 +7,8 @@ #include "base/memory/scoped_refptr.h" #include "base/task/single_thread_task_runner.h" -#include "mojo/public/cpp/bindings/pending_receiver.h" #include "third_party/blink/public/mojom/shared_storage/shared_storage_worklet_service.mojom-forward.h" +#include "third_party/blink/public/platform/cross_variant_mojo_util.h" #include "third_party/blink/public/platform/web_common.h" namespace blink { @@ -18,7 +18,8 @@ public: static void Start( scoped_refptr<base::SingleThreadTaskRunner> main_thread_runner, - mojo::PendingReceiver<mojom::SharedStorageWorkletService> receiver); + CrossVariantMojoReceiver<mojom::SharedStorageWorkletServiceInterfaceBase> + receiver); virtual ~WebSharedStorageWorkletThread() = default; };
diff --git a/third_party/blink/renderer/core/css/css_properties.json5 b/third_party/blink/renderer/core/css/css_properties.json5 index 64077e481..b4d1ee9 100644 --- a/third_party/blink/renderer/core/css/css_properties.json5 +++ b/third_party/blink/renderer/core/css/css_properties.json5
@@ -6560,24 +6560,6 @@ is_property: false, }, { - name: "source", - is_descriptor: true, - is_property: false, - runtime_flag: "CSSScrollTimeline", - }, - { - name: "start", - is_descriptor: true, - is_property: false, - runtime_flag: "CSSScrollTimeline", - }, - { - name: "end", - is_descriptor: true, - is_property: false, - runtime_flag: "CSSScrollTimeline", - }, - { name: "ascent-override", is_descriptor: true, is_property: false,
diff --git a/third_party/blink/renderer/core/css/css_property_equality.cc b/third_party/blink/renderer/core/css/css_property_equality.cc index c0a3df5..9f9b955b 100644 --- a/third_party/blink/renderer/core/css/css_property_equality.cc +++ b/third_party/blink/renderer/core/css/css_property_equality.cc
@@ -1244,7 +1244,6 @@ case CSSPropertyID::kAscentOverride: case CSSPropertyID::kBasePalette: case CSSPropertyID::kDescentOverride: - case CSSPropertyID::kEnd: case CSSPropertyID::kInvalid: case CSSPropertyID::kFallback: case CSSPropertyID::kFontDisplay: @@ -1257,10 +1256,8 @@ case CSSPropertyID::kPrefix: case CSSPropertyID::kRange: case CSSPropertyID::kSize: - case CSSPropertyID::kSource: case CSSPropertyID::kSpeakAs: case CSSPropertyID::kSrc: - case CSSPropertyID::kStart: case CSSPropertyID::kSuffix: case CSSPropertyID::kSymbols: case CSSPropertyID::kSyntax:
diff --git a/third_party/blink/renderer/core/css/parser/at_rule_names.json5 b/third_party/blink/renderer/core/css/parser/at_rule_names.json5 index 2f04975..6672a805 100644 --- a/third_party/blink/renderer/core/css/parser/at_rule_names.json5 +++ b/third_party/blink/renderer/core/css/parser/at_rule_names.json5
@@ -27,9 +27,6 @@ name: "descent-override", }, { - name: "end", - }, - { name: "font-display", }, { @@ -82,18 +79,12 @@ name: "size-adjust", }, { - name: "source", - }, - { name: "speak-as", }, { name: "src", }, { - name: "start", - }, - { name: "suffix", }, {
diff --git a/third_party/blink/renderer/core/css/parser/css_at_rule_id.cc b/third_party/blink/renderer/core/css/parser/css_at_rule_id.cc index da1a5eb..2d19761 100644 --- a/third_party/blink/renderer/core/css/parser/css_at_rule_id.cc +++ b/third_party/blink/renderer/core/css/parser/css_at_rule_id.cc
@@ -97,12 +97,6 @@ if (EqualIgnoringASCIICase(name, "counter-style")) { return CSSAtRuleID::kCSSAtRuleCounterStyle; } - if (EqualIgnoringASCIICase(name, "scroll-timeline")) { - if (RuntimeEnabledFeatures::CSSScrollTimelineEnabled()) { - return CSSAtRuleID::kCSSAtRuleScrollTimeline; - } - return CSSAtRuleID::kCSSAtRuleInvalid; - } if (EqualIgnoringASCIICase(name, "scope")) { if (RuntimeEnabledFeatures::CSSScopeEnabled()) { return CSSAtRuleID::kCSSAtRuleScope; @@ -176,8 +170,6 @@ return WebFeature::kCSSAtRuleStylistic; case CSSAtRuleID::kCSSAtRuleSwash: return WebFeature::kCSSAtRuleSwash; - case CSSAtRuleID::kCSSAtRuleScrollTimeline: - return WebFeature::kCSSAtRuleScrollTimeline; case CSSAtRuleID::kCSSAtRuleSupports: return WebFeature::kCSSAtRuleSupports; case CSSAtRuleID::kCSSAtRulePositionFallback:
diff --git a/third_party/blink/renderer/core/css/parser/css_at_rule_id.h b/third_party/blink/renderer/core/css/parser/css_at_rule_id.h index 01877be..dbf1f14 100644 --- a/third_party/blink/renderer/core/css/parser/css_at_rule_id.h +++ b/third_party/blink/renderer/core/css/parser/css_at_rule_id.h
@@ -28,7 +28,6 @@ kCSSAtRuleContainer, kCSSAtRuleCounterStyle, kCSSAtRuleScope, - kCSSAtRuleScrollTimeline, kCSSAtRuleSupports, kCSSAtRuleTry, kCSSAtRuleWebkitKeyframes,
diff --git a/third_party/blink/renderer/core/css/parser/css_parser_impl.cc b/third_party/blink/renderer/core/css/parser/css_parser_impl.cc index 6ed2cca..892db43 100644 --- a/third_party/blink/renderer/core/css/parser/css_parser_impl.cc +++ b/third_party/blink/renderer/core/css/parser/css_parser_impl.cc
@@ -772,7 +772,6 @@ case CSSAtRuleID::kCSSAtRuleCharset: case CSSAtRuleID::kCSSAtRuleImport: case CSSAtRuleID::kCSSAtRuleNamespace: - case CSSAtRuleID::kCSSAtRuleScrollTimeline: case CSSAtRuleID::kCSSAtRuleTry: case CSSAtRuleID::kCSSAtRuleStylistic: case CSSAtRuleID::kCSSAtRuleStyleset:
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc index eb6bf82..c78c484 100644 --- a/third_party/blink/renderer/core/dom/document.cc +++ b/third_party/blink/renderer/core/dom/document.cc
@@ -4513,6 +4513,7 @@ UpdateBaseURL(); } + AtomicString old_base_target = base_target_; if (target) { if (target->Contains('\n') || target->Contains('\r')) UseCounter::Count(*this, WebFeature::kBaseWithNewlinesInTarget); @@ -4522,6 +4523,11 @@ } else { base_target_ = g_null_atom; } + if (old_base_target != base_target_) { + if (auto* document_rules = DocumentSpeculationRules::FromIfExists(*this)) { + document_rules->DocumentBaseTargetChanged(); + } + } } void Document::DidAddPendingParserBlockingStylesheet() {
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.cc b/third_party/blink/renderer/core/frame/local_dom_window.cc index fcff767..83a6e60 100644 --- a/third_party/blink/renderer/core/frame/local_dom_window.cc +++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
@@ -2521,4 +2521,12 @@ has_storage_access_ = true; } +bool LocalDOMWindow::HadActivationlessPaymentRequest() const { + return had_activationless_payment_request_; +} + +void LocalDOMWindow::SetHadActivationlessPaymentRequest() { + had_activationless_payment_request_ = true; +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.h b/third_party/blink/renderer/core/frame/local_dom_window.h index 931e213..eccc9caa 100644 --- a/third_party/blink/renderer/core/frame/local_dom_window.h +++ b/third_party/blink/renderer/core/frame/local_dom_window.h
@@ -523,6 +523,9 @@ // given window, it cannot be taken away. void SetHasStorageAccess(); + bool HadActivationlessPaymentRequest() const; + void SetHadActivationlessPaymentRequest(); + protected: // EventTarget overrides. void AddedEventListener(const AtomicString& event_type, @@ -667,6 +670,12 @@ // Records whether this window has obtained storage access. It cannot be // revoked once set to true. bool has_storage_access_ = false; + + // Tracks whether this window has shown a payment request without a user + // activation. It cannot be revoked once set to true. + // TODO(crbug.com/1439565): Move this bit to a new payments-specific + // per-LocalDOMWindow class in the payments module. + bool had_activationless_payment_request_ = false; }; template <>
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc index a4df7dca..42199b9 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view.cc +++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -1203,23 +1203,27 @@ SetNeedsPaintPropertyUpdate(); } +static bool BackgroundAttachmentFixedNeedsRepaintOnScroll( + const LayoutObject& object) { + // We should not add such object in the background_attachment_fixed_objects_. + DCHECK(!To<LayoutBoxModelObject>(object).BackgroundTransfersToView()); + // The background doesn't need repaint if it's the viewport background and it + // paints onto the border box space only. + if (IsA<LayoutView>(object) && + object.GetBackgroundPaintLocation() == kBackgroundPaintInBorderBoxSpace) { + return false; + } + return !object.CanCompositeBackgroundAttachmentFixed(); +} + bool LocalFrameView::RequiresMainThreadScrollingForBackgroundAttachmentFixed() const { - if (background_attachment_fixed_objects_.empty()) - return false; - if (background_attachment_fixed_objects_.size() > 1) - return true; - - const auto* object = To<LayoutBoxModelObject>( - background_attachment_fixed_objects_.begin()->Get()); - // We should not add such object in the set. - DCHECK(!object->BackgroundTransfersToView()); - // If the background is viewport background and it paints onto the border box - // space only, then it doesn't need main thread scrolling. - if (IsA<LayoutView>(object) && - object->GetBackgroundPaintLocation() == kBackgroundPaintInBorderBoxSpace) - return false; - return true; + for (const auto& object : background_attachment_fixed_objects_) { + if (BackgroundAttachmentFixedNeedsRepaintOnScroll(*object)) { + return true; + } + } + return false; } void LocalFrameView::AddFixedPositionObject(LayoutObject& object) { @@ -1317,19 +1321,15 @@ } void LocalFrameView::InvalidateBackgroundAttachmentFixedDescendantsOnScroll( - const LayoutObject& scrolled_object) { + const LayoutBox& scroller) { for (const auto& layout_object : background_attachment_fixed_objects_) { - if (scrolled_object != GetLayoutView() && - !layout_object->IsDescendantOf(&scrolled_object)) + if (scroller != GetLayoutView() && + !layout_object->IsDescendantOf(&scroller)) { continue; - // An object needs to repaint the background on scroll when it has - // background-attachment:fixed unless the object is the LayoutView and the - // background is not painted on the scrolling contents. - if (layout_object == GetLayoutView() && - !(GetLayoutView()->GetBackgroundPaintLocation() & - kBackgroundPaintInContentsSpace)) - continue; - layout_object->SetBackgroundNeedsFullPaintInvalidation(); + } + if (BackgroundAttachmentFixedNeedsRepaintOnScroll(*layout_object)) { + layout_object->SetBackgroundNeedsFullPaintInvalidation(); + } } }
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.h b/third_party/blink/renderer/core/frame/local_frame_view.h index 260e78f..9714b1f 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view.h +++ b/third_party/blink/renderer/core/frame/local_frame_view.h
@@ -322,7 +322,7 @@ return background_attachment_fixed_objects_; } void InvalidateBackgroundAttachmentFixedDescendantsOnScroll( - const LayoutObject& scrolled_object); + const LayoutBox& scroller); void HandleLoadCompleted();
diff --git a/third_party/blink/renderer/core/html/fenced_frame/html_fenced_frame_element.cc b/third_party/blink/renderer/core/html/fenced_frame/html_fenced_frame_element.cc index e985360..59a1654 100644 --- a/third_party/blink/renderer/core/html/fenced_frame/html_fenced_frame_element.cc +++ b/third_party/blink/renderer/core/html/fenced_frame/html_fenced_frame_element.cc
@@ -415,26 +415,7 @@ void HTMLFencedFrameElement::ParseAttribute( const AttributeModificationParams& params) { - if (params.name == html_names::kSrcAttr) { - if (RuntimeEnabledFeatures::FencedFramesAPIChangesEnabled( - GetExecutionContext())) { - // Temporarily allow `src` to be set in a fenced frame if API changes is - // disabled. This functionality will be removed by fenced frames launch. - return; - } - if (config_) { - DCHECK(config_->url()); - GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>( - mojom::blink::ConsoleMessageSource::kJavaScript, - mojom::blink::ConsoleMessageLevel::kWarning, - "Changing the `src` attribute on a fenced frame has no effect after " - "it has already been installed a config with a specified url.")); - return; - } - - KURL url = GetNonEmptyURLAttribute(html_names::kSrcAttr); - Navigate(url); - } else if (params.name == html_names::kSandboxAttr) { + if (params.name == html_names::kSandboxAttr) { sandbox_->DidUpdateAttributeValue(params.old_value, params.new_value); network::mojom::blink::WebSandboxFlags current_flags = @@ -473,10 +454,6 @@ } } -bool HTMLFencedFrameElement::IsURLAttribute(const Attribute& attribute) const { - return attribute.GetName() == html_names::kSrcAttr; -} - bool HTMLFencedFrameElement::IsPresentationAttribute( const QualifiedName& name) const { if (name == html_names::kWidthAttr || name == html_names::kHeightAttr) @@ -666,9 +643,6 @@ if (config_) { NavigateToConfig(); - } else if (!RuntimeEnabledFeatures::FencedFramesAPIChangesEnabled( - GetExecutionContext())) { - Navigate(GetNonEmptyURLAttribute(html_names::kSrcAttr)); } }
diff --git a/third_party/blink/renderer/core/html/fenced_frame/html_fenced_frame_element.h b/third_party/blink/renderer/core/html/fenced_frame/html_fenced_frame_element.h index 887a7a4..2873889 100644 --- a/third_party/blink/renderer/core/html/fenced_frame/html_fenced_frame_element.h +++ b/third_party/blink/renderer/core/html/fenced_frame/html_fenced_frame_element.h
@@ -144,7 +144,6 @@ // Element overrides. void ParseAttribute(const AttributeModificationParams&) override; - bool IsURLAttribute(const Attribute&) const override; bool IsPresentationAttribute(const QualifiedName&) const override; void CollectStyleForPresentationAttribute( const QualifiedName&,
diff --git a/third_party/blink/renderer/core/html/fenced_frame/html_fenced_frame_element.idl b/third_party/blink/renderer/core/html/fenced_frame/html_fenced_frame_element.idl index 9b493b4..a931f4a 100644 --- a/third_party/blink/renderer/core/html/fenced_frame/html_fenced_frame_element.idl +++ b/third_party/blink/renderer/core/html/fenced_frame/html_fenced_frame_element.idl
@@ -6,7 +6,6 @@ [Exposed=Window, HTMLConstructor, RuntimeEnabled=FencedFrames] interface HTMLFencedFrameElement : HTMLElement { - [CEReactions, Reflect, URL] attribute USVString src; [CEReactions, RuntimeEnabled=FencedFramesAPIChanges, MeasureAs=FencedFrameConfigAttribute] attribute FencedFrameConfig? config; [CEReactions, Reflect] attribute DOMString width; [CEReactions, Reflect] attribute DOMString height;
diff --git a/third_party/blink/renderer/core/html/html_anchor_element.cc b/third_party/blink/renderer/core/html/html_anchor_element.cc index 0ccff99..e4432ac 100644 --- a/third_party/blink/renderer/core/html/html_anchor_element.cc +++ b/third_party/blink/renderer/core/html/html_anchor_element.cc
@@ -275,6 +275,13 @@ document_rules->ReferrerPolicyAttributeChanged(this); } } + } else if (params.name == html_names::kTargetAttr) { + if (isConnected() && IsLink()) { + if (auto* document_rules = + DocumentSpeculationRules::FromIfExists(GetDocument())) { + document_rules->TargetAttributeChanged(this); + } + } } else { HTMLElement::ParseAttribute(params); }
diff --git a/third_party/blink/renderer/core/html/html_base_element.h b/third_party/blink/renderer/core/html/html_base_element.h index e79523a..3d8aba33 100644 --- a/third_party/blink/renderer/core/html/html_base_element.h +++ b/third_party/blink/renderer/core/html/html_base_element.h
@@ -23,11 +23,12 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_HTML_BASE_ELEMENT_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_HTML_BASE_ELEMENT_H_ +#include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/html/html_element.h" namespace blink { -class HTMLBaseElement final : public HTMLElement { +class CORE_EXPORT HTMLBaseElement final : public HTMLElement { DEFINE_WRAPPERTYPEINFO(); public:
diff --git a/third_party/blink/renderer/core/layout/layout_box.cc b/third_party/blink/renderer/core/layout/layout_box.cc index 873168e7..567038b 100644 --- a/third_party/blink/renderer/core/layout/layout_box.cc +++ b/third_party/blink/renderer/core/layout/layout_box.cc
@@ -773,6 +773,12 @@ old_style->Direction() != new_style.Direction()) { SetNeedsCollectInlines(); } + + if (CanCompositeBackgroundAttachmentFixed() && + new_style.BackgroundLayers().Clip() != + old_style->BackgroundLayers().Clip()) { + SetNeedsPaintPropertyUpdate(); + } } if (LocalFrameView* frame_view = View()->GetFrameView()) { @@ -6275,6 +6281,41 @@ return paint_location; } +bool LayoutBox::ComputeCanCompositeBackgroundAttachmentFixed() const { + NOT_DESTROYED(); + DCHECK(IsBackgroundAttachmentFixedObject()); + if (!RuntimeEnabledFeatures::CompositeBackgroundAttachmentFixedEnabled()) { + return false; + } + if (GetDocument().GetSettings()->GetLCDTextPreference() == + LCDTextPreference::kStronglyPreferred) { + return false; + } + // The fixed attachment background must be the only background layer. + if (StyleRef().BackgroundLayers().Next() || + StyleRef().BackgroundLayers().Clip() == EFillBox::kText) { + return false; + } + // To support box shadow, we'll need to paint the outset and inset box + // shadows in separate display items in case there are outset box shadow, + // background, inset box shadow and border in paint order. + if (StyleRef().BoxShadow()) { + return false; + } + // The theme may paint the background differently for an appearance. + if (StyleRef().HasEffectiveAppearance()) { + return false; + } + // For now the BackgroundClip paint property node doesn't support rounded + // corners. If we want to support this, we need to ensure + // - there is no obvious bleeding issues, and + // - both the fast path and the slow path of composited rounded clip work. + if (StyleRef().HasBorderRadius()) { + return false; + } + return true; +} + bool LayoutBox::IsFixedToView( const LayoutObject* container_for_fixed_position) const { if (!IsFixedPositioned())
diff --git a/third_party/blink/renderer/core/layout/layout_box.h b/third_party/blink/renderer/core/layout/layout_box.h index 9358939..de25da75 100644 --- a/third_party/blink/renderer/core/layout/layout_box.h +++ b/third_party/blink/renderer/core/layout/layout_box.h
@@ -1787,6 +1787,7 @@ const PhysicalRect& local_rect, unsigned max_depth_to_test) const; virtual bool ComputeBackgroundIsKnownToBeObscured() const; + bool ComputeCanCompositeBackgroundAttachmentFixed() const override; LayoutUnit ComputeIntrinsicLogicalContentHeightUsing( SizeType height_type,
diff --git a/third_party/blink/renderer/core/layout/layout_box_model_object.cc b/third_party/blink/renderer/core/layout/layout_box_model_object.cc index d092c35..0eecf1c 100644 --- a/third_party/blink/renderer/core/layout/layout_box_model_object.cc +++ b/third_party/blink/renderer/core/layout/layout_box_model_object.cc
@@ -350,10 +350,6 @@ else element->RemoveAnchorScrollData(); } - - SetIsBackgroundAttachmentFixedObject( - !BackgroundTransfersToView() && - StyleRef().HasFixedAttachmentBackgroundImage()); } void LayoutBoxModelObject::CreateLayerAfterStyleChange() { @@ -480,6 +476,14 @@ SetCanContainAbsolutePositionObjects( ComputeIsAbsoluteContainer(&style_to_use)); SetCanContainFixedPositionObjects(ComputeIsFixedContainer(&style_to_use)); + + bool is_background_attachment_fixed_object = + !BackgroundTransfersToView() && + StyleRef().HasFixedAttachmentBackgroundImage(); + SetIsBackgroundAttachmentFixedObject(is_background_attachment_fixed_object); + SetCanCompositeBackgroundAttachmentFixed( + is_background_attachment_fixed_object && + ComputeCanCompositeBackgroundAttachmentFixed()); } PhysicalRect LayoutBoxModelObject::PhysicalVisualOverflowRectIncludingFilters()
diff --git a/third_party/blink/renderer/core/layout/layout_box_model_object.h b/third_party/blink/renderer/core/layout/layout_box_model_object.h index d3d03c4..c740da4 100644 --- a/third_party/blink/renderer/core/layout/layout_box_model_object.h +++ b/third_party/blink/renderer/core/layout/layout_box_model_object.h
@@ -470,6 +470,10 @@ void StyleWillChange(StyleDifference, const ComputedStyle& new_style) override; void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override; + virtual bool ComputeCanCompositeBackgroundAttachmentFixed() const { + NOT_DESTROYED(); + return false; + } public: // These functions are only used internally to manipulate the layout tree
diff --git a/third_party/blink/renderer/core/layout/layout_object.cc b/third_party/blink/renderer/core/layout/layout_object.cc index 95bb07b..0444fd0 100644 --- a/third_party/blink/renderer/core/layout/layout_object.cc +++ b/third_party/blink/renderer/core/layout/layout_object.cc
@@ -4691,6 +4691,14 @@ GetFrameView()->RemoveBackgroundAttachmentFixedObject(this); } +void LayoutObject::SetCanCompositeBackgroundAttachmentFixed( + bool can_fast_scroll) { + if (can_fast_scroll != bitfields_.CanCompositeBackgroundAttachmentFixed()) { + bitfields_.SetCanCompositeBackgroundAttachmentFixed(can_fast_scroll); + SetNeedsPaintPropertyUpdate(); + } +} + PhysicalRect LayoutObject::DebugRect() const { NOT_DESTROYED(); return PhysicalRect();
diff --git a/third_party/blink/renderer/core/layout/layout_object.h b/third_party/blink/renderer/core/layout/layout_object.h index fb0fbc3..6420433 100644 --- a/third_party/blink/renderer/core/layout/layout_object.h +++ b/third_party/blink/renderer/core/layout/layout_object.h
@@ -3343,6 +3343,10 @@ NOT_DESTROYED(); return bitfields_.IsBackgroundAttachmentFixedObject(); } + bool CanCompositeBackgroundAttachmentFixed() const { + NOT_DESTROYED(); + return bitfields_.CanCompositeBackgroundAttachmentFixed(); + } bool BackgroundNeedsFullPaintInvalidation() const { NOT_DESTROYED(); @@ -3635,6 +3639,7 @@ virtual void ClearPaintFlags(); void SetIsBackgroundAttachmentFixedObject(bool); + void SetCanCompositeBackgroundAttachmentFixed(bool); void SetEverHadLayout() { NOT_DESTROYED(); @@ -3900,6 +3905,7 @@ always_create_line_boxes_for_layout_inline_(false), background_is_known_to_be_obscured_(false), is_background_attachment_fixed_object_(false), + can_composite_background_attachment_fixed_(false), is_scroll_anchor_object_(false), scroll_anchor_disabling_style_changed_(false), has_box_decoration_background_(false), @@ -4124,6 +4130,8 @@ ADD_BOOLEAN_BITFIELD(is_background_attachment_fixed_object_, IsBackgroundAttachmentFixedObject); + ADD_BOOLEAN_BITFIELD(can_composite_background_attachment_fixed_, + CanCompositeBackgroundAttachmentFixed); ADD_BOOLEAN_BITFIELD(is_scroll_anchor_object_, IsScrollAnchorObject); // Whether changes in this LayoutObject's CSS properties since the last
diff --git a/third_party/blink/renderer/core/layout/layout_view.h b/third_party/blink/renderer/core/layout/layout_view.h index c271309..1e54b8c 100644 --- a/third_party/blink/renderer/core/layout/layout_view.h +++ b/third_party/blink/renderer/core/layout/layout_view.h
@@ -344,6 +344,13 @@ bool CanHaveChildren() const override; void UpdateFromStyle() override; + // The CompositeBackgroundAttachmentFixed optimization doesn't apply to + // LayoutView which paints background specially. + bool ComputeCanCompositeBackgroundAttachmentFixed() const override { + NOT_DESTROYED(); + return false; + } + Member<LocalFrameView> frame_view_; // The page size.
diff --git a/third_party/blink/renderer/core/messaging/blink_transferable_message.cc b/third_party/blink/renderer/core/messaging/blink_transferable_message.cc index aef9c9c1..bfede95 100644 --- a/third_party/blink/renderer/core/messaging/blink_transferable_message.cc +++ b/third_party/blink/renderer/core/messaging/blink_transferable_message.cc
@@ -12,6 +12,7 @@ #include "third_party/blink/renderer/core/frame/user_activation.h" #include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h" #include "third_party/blink/renderer/platform/blob/blob_data.h" +#include "third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h" #include "third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h" #include "third_party/skia/include/core/SkImage.h" @@ -86,12 +87,23 @@ base::checked_cast<wtf_size_t>( message.image_bitmap_contents_array.size())); - for (auto& sk_bitmap : message.image_bitmap_contents_array) { - const scoped_refptr<StaticBitmapImage> bitmap_contents = - ToStaticBitmapImage(sk_bitmap); - if (!bitmap_contents) - continue; - image_bitmap_contents_array.push_back(bitmap_contents); + for (auto& image : message.image_bitmap_contents_array) { + if (image->is_bitmap()) { + const scoped_refptr<StaticBitmapImage> bitmap_contents = + ToStaticBitmapImage(image->get_bitmap()); + if (!bitmap_contents) { + continue; + } + image_bitmap_contents_array.push_back(bitmap_contents); + } else if (image->is_accelerated_image()) { + const scoped_refptr<StaticBitmapImage> accelerated_image = + WrapAcceleratedBitmapImage( + std::move(image->get_accelerated_image())); + if (!accelerated_image) { + continue; + } + image_bitmap_contents_array.push_back(accelerated_image); + } } result.message->SetImageBitmapContentsArray( std::move(image_bitmap_contents_array)); @@ -123,4 +135,11 @@ return UnacceleratedStaticBitmapImage::Create(std::move(image)); } +scoped_refptr<StaticBitmapImage> WrapAcceleratedBitmapImage( + AcceleratedImageInfo image) { + return AcceleratedStaticBitmapImage::CreateFromExternalMailbox( + image.mailbox_holder, image.usage, image.image_info, + image.is_origin_top_left, image.supports_display_compositing, + image.is_overlay_candidate, std::move(image.release_callback)); +} } // namespace blink
diff --git a/third_party/blink/renderer/core/messaging/blink_transferable_message.h b/third_party/blink/renderer/core/messaging/blink_transferable_message.h index d26e378..24b5afe 100644 --- a/third_party/blink/renderer/core/messaging/blink_transferable_message.h +++ b/third_party/blink/renderer/core/messaging/blink_transferable_message.h
@@ -6,10 +6,12 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_MESSAGING_BLINK_TRANSFERABLE_MESSAGE_H_ #include "third_party/abseil-cpp/absl/types/optional.h" +#include "third_party/blink/public/common/messaging/accelerated_image_info.h" #include "third_party/blink/public/common/messaging/message_port_channel.h" #include "third_party/blink/public/common/messaging/transferable_message.h" #include "third_party/blink/public/common/scheduler/task_attribution_id.h" #include "third_party/blink/public/mojom/messaging/delegated_capability.mojom-blink.h" +#include "third_party/blink/public/mojom/messaging/static_bitmap_image.mojom-blink.h" #include "third_party/blink/public/mojom/messaging/user_activation_snapshot.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h" #include "third_party/blink/renderer/core/core_export.h" @@ -44,6 +46,9 @@ CORE_EXPORT scoped_refptr<blink::StaticBitmapImage> ToStaticBitmapImage( const SkBitmap& sk_bitmap); +CORE_EXPORT scoped_refptr<blink::StaticBitmapImage> WrapAcceleratedBitmapImage( + AcceleratedImageInfo image); + } // namespace blink namespace WTF {
diff --git a/third_party/blink/renderer/core/messaging/blink_transferable_message_mojom_traits.cc b/third_party/blink/renderer/core/messaging/blink_transferable_message_mojom_traits.cc index fd3750bb..252c9de 100644 --- a/third_party/blink/renderer/core/messaging/blink_transferable_message_mojom_traits.cc +++ b/third_party/blink/renderer/core/messaging/blink_transferable_message_mojom_traits.cc
@@ -6,6 +6,8 @@ #include "mojo/public/cpp/base/big_buffer_mojom_traits.h" #include "skia/ext/skia_utils_base.h" +#include "third_party/blink/public/common/features.h" +#include "third_party/blink/public/mojom/messaging/static_bitmap_image.mojom-blink.h" #include "third_party/blink/public/mojom/messaging/transferable_message.mojom-blink.h" #include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h" #include "third_party/skia/include/core/SkBitmap.h" @@ -35,23 +37,55 @@ return sk_bitmap_n32; } +blink::mojom::blink::SerializedStaticBitmapImagePtr +ToSerializedAcceleratedImage( + scoped_refptr<blink::StaticBitmapImage> static_bitmap_image) { + static_bitmap_image->EnsureSyncTokenVerified(); + + auto image_info = static_bitmap_image->GetSkImageInfo(); + + auto result = + blink::mojom::blink::SerializedStaticBitmapImage::NewAcceleratedImage( + blink::AcceleratedImageInfo{ + static_bitmap_image->GetMailboxHolder(), + static_bitmap_image->GetUsage(), image_info, + static_bitmap_image->IsOriginTopLeft(), + static_bitmap_image->SupportsDisplayCompositing(), + static_bitmap_image->IsOverlayCandidate(), + WTF::BindOnce(&blink::StaticBitmapImage::UpdateSyncToken, + static_bitmap_image)}); + return result; +} + } // namespace -Vector<SkBitmap> +Vector<blink::mojom::blink::SerializedStaticBitmapImagePtr> StructTraits<blink::mojom::blink::TransferableMessage::DataView, blink::BlinkTransferableMessage>:: image_bitmap_contents_array(const blink::BlinkCloneableMessage& input) { - Vector<SkBitmap> out; + Vector<blink::mojom::blink::SerializedStaticBitmapImagePtr> out; out.ReserveInitialCapacity( input.message->GetImageBitmapContentsArray().size()); for (auto& bitmap_contents : input.message->GetImageBitmapContentsArray()) { - // TransferableMessage::image_bitmap_contents_array is an array of - // skia.mojom.BitmapN32, so SkBitmap should be in N32 format. - auto bitmap_n32 = ToSkBitmapN32(bitmap_contents); - if (!bitmap_n32) { - return Vector<SkBitmap>(); + if (!bitmap_contents->IsTextureBacked() || + !base::FeatureList::IsEnabled( + blink::features::kAcceleratedStaticBitmapImageSerialization)) { + // Software images are passed as skia.mojom.BitmapN32, + // so SkBitmap should be in N32 format. + auto bitmap_n32 = ToSkBitmapN32(bitmap_contents); + if (!bitmap_n32) { + return Vector<blink::mojom::blink::SerializedStaticBitmapImagePtr>(); + } + out.push_back(blink::mojom::blink::SerializedStaticBitmapImage::NewBitmap( + bitmap_n32.value())); + } else { + blink::mojom::blink::SerializedStaticBitmapImagePtr serialized_image = + ToSerializedAcceleratedImage(bitmap_contents); + if (!serialized_image) { + return Vector<blink::mojom::blink::SerializedStaticBitmapImagePtr>(); + } + out.push_back(std::move(serialized_image)); } - out.push_back(std::move(bitmap_n32.value())); } return out; } @@ -64,11 +98,11 @@ Vector<blink::MessagePortDescriptor> stream_channels; blink::SerializedScriptValue::ArrayBufferContentsArray array_buffer_contents_array; - Vector<SkBitmap> sk_bitmaps; + Vector<blink::mojom::blink::SerializedStaticBitmapImagePtr> images; if (!data.ReadMessage(static_cast<blink::BlinkCloneableMessage*>(out)) || !data.ReadArrayBufferContentsArray(&array_buffer_contents_array) || - !data.ReadImageBitmapContentsArray(&sk_bitmaps) || - !data.ReadPorts(&ports) || !data.ReadStreamChannels(&stream_channels) || + !data.ReadImageBitmapContentsArray(&images) || !data.ReadPorts(&ports) || + !data.ReadStreamChannels(&stream_channels) || !data.ReadUserActivation(&out->user_activation)) { return false; } @@ -92,13 +126,25 @@ // the SkBitmaps need to be converted to StaticBitmapImages. blink::SerializedScriptValue::ImageBitmapContentsArray image_bitmap_contents_array; - for (auto& sk_bitmap : sk_bitmaps) { - const scoped_refptr<blink::StaticBitmapImage> bitmap_contents = - blink::ToStaticBitmapImage(sk_bitmap); - if (!bitmap_contents) { + for (auto& image : images) { + if (image->is_bitmap()) { + scoped_refptr<blink::StaticBitmapImage> bitmap_contents = + blink::ToStaticBitmapImage(image->get_bitmap()); + if (!bitmap_contents) { + return false; + } + image_bitmap_contents_array.push_back(std::move(bitmap_contents)); + } else if (image->is_accelerated_image()) { + scoped_refptr<blink::StaticBitmapImage> accelerated_image = + blink::WrapAcceleratedBitmapImage( + std::move(image->get_accelerated_image())); + if (!accelerated_image) { + return false; + } + image_bitmap_contents_array.push_back(std::move(accelerated_image)); + } else { return false; } - image_bitmap_contents_array.push_back(bitmap_contents); } out->message->SetImageBitmapContentsArray(image_bitmap_contents_array); return true;
diff --git a/third_party/blink/renderer/core/messaging/blink_transferable_message_mojom_traits.h b/third_party/blink/renderer/core/messaging/blink_transferable_message_mojom_traits.h index 2d43c2fb..e942766 100644 --- a/third_party/blink/renderer/core/messaging/blink_transferable_message_mojom_traits.h +++ b/third_party/blink/renderer/core/messaging/blink_transferable_message_mojom_traits.h
@@ -7,6 +7,7 @@ #include "mojo/public/cpp/bindings/array_traits_wtf_vector.h" #include "skia/public/mojom/bitmap_skbitmap_mojom_traits.h" +#include "third_party/blink/public/common/messaging/accelerated_static_bitmap_image_mojom_traits.h" #include "third_party/blink/public/common/messaging/message_port_channel.h" #include "third_party/blink/public/common/messaging/message_port_descriptor.h" #include "third_party/blink/public/common/messaging/message_port_descriptor_mojom_traits.h" @@ -53,8 +54,8 @@ return input.message->GetArrayBufferContentsArray(); } - static Vector<SkBitmap> image_bitmap_contents_array( - const blink::BlinkCloneableMessage& input); + static Vector<blink::mojom::blink::SerializedStaticBitmapImagePtr> + image_bitmap_contents_array(const blink::BlinkCloneableMessage& input); static const blink::mojom::blink::UserActivationSnapshotPtr& user_activation( const blink::BlinkTransferableMessage& input) {
diff --git a/third_party/blink/renderer/core/messaging/blink_transferable_message_mojom_traits_test.cc b/third_party/blink/renderer/core/messaging/blink_transferable_message_mojom_traits_test.cc index cc76344..7627b16 100644 --- a/third_party/blink/renderer/core/messaging/blink_transferable_message_mojom_traits_test.cc +++ b/third_party/blink/renderer/core/messaging/blink_transferable_message_mojom_traits_test.cc
@@ -5,6 +5,9 @@ #include "third_party/blink/renderer/core/messaging/blink_transferable_message_mojom_traits.h" #include "base/memory/scoped_refptr.h" +#include "base/run_loop.h" +#include "base/test/bind.h" +#include "base/test/null_task_runner.h" #include "mojo/public/cpp/base/big_buffer_mojom_traits.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/messaging/message_port_channel.h" @@ -15,17 +18,25 @@ #include "third_party/blink/renderer/bindings/core/v8/to_v8_traits.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h" #include "third_party/blink/renderer/bindings/core/v8/v8_image_bitmap.h" +#include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h" #include "third_party/blink/renderer/core/messaging/blink_transferable_message.h" #include "third_party/blink/renderer/core/messaging/message_port.h" #include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" +#include "third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h" +#include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h" +#include "third_party/blink/renderer/platform/graphics/test/fake_web_graphics_context_3d_provider.h" +#include "third_party/blink/renderer/platform/graphics/test/gpu_test_utils.h" #include "third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkSurface.h" +using testing::_; +using testing::Test; + namespace blink { scoped_refptr<SerializedScriptValue> BuildSerializedScriptValue( @@ -201,4 +212,143 @@ ASSERT_TRUE(original_bitmap->IsNeutered()); } +class BlinkTransferableMessageStructTraitsWithFakeGpuTest : public Test { + public: + void SetUp() override { + auto sii = std::make_unique<viz::TestSharedImageInterface>(); + sii_ = sii.get(); + context_provider_ = viz::TestContextProvider::Create(std::move(sii)); + InitializeSharedGpuContext(context_provider_.get()); + } + + void TearDown() override { + sii_ = nullptr; + SharedGpuContext::ResetForTesting(); + } + + gpu::SyncToken GenTestSyncToken(GLbyte id) { + gpu::SyncToken token; + token.Set(gpu::CommandBufferNamespace::GPU_IO, + gpu::CommandBufferId::FromUnsafeValue(64), id); + token.SetVerifyFlush(); + return token; + } + + ImageBitmap* CreateAcceleratedStaticImageBitmap() { + auto mailbox = gpu::Mailbox::GenerateForSharedImage(); + + return MakeGarbageCollected<ImageBitmap>( + AcceleratedStaticBitmapImage::CreateFromCanvasMailbox( + mailbox, GenTestSyncToken(100), 0, + SkImageInfo::MakeN32Premul(100, 100), GL_TEXTURE_2D, true, + SharedGpuContext::ContextProviderWrapper(), + base::PlatformThread::CurrentRef(), + base::MakeRefCounted<base::NullTaskRunner>(), + WTF::BindOnce(&BlinkTransferableMessageStructTraitsWithFakeGpuTest:: + OnImageDestroyed, + WTF::Unretained(this)), + /*supports_display_compositing=*/true, + /*is_overlay_candidate=*/true)); + } + + void OnImageDestroyed(const gpu::SyncToken&, bool) { + image_destroyed_ = true; + } + + protected: + viz::TestSharedImageInterface* sii_; + scoped_refptr<viz::TestContextProvider> context_provider_; + + bool image_destroyed_ = false; +}; + +TEST_F(BlinkTransferableMessageStructTraitsWithFakeGpuTest, + AcceleratedImageTransferSuccess) { + V8TestingScope scope; + scope.GetExecutionContext() + ->GetTaskRunner(TaskType::kInternalTest) + ->PostTask( + FROM_HERE, base::BindLambdaForTesting([&]() { + ImageBitmap* image_bitmap = CreateAcceleratedStaticImageBitmap(); + v8::Local<v8::Value> wrapper = + ToV8Traits<ImageBitmap>::ToV8(scope.GetScriptState(), + image_bitmap) + .ToLocalChecked(); + Transferables transferables; + transferables.image_bitmaps.push_back(image_bitmap); + BlinkTransferableMessage msg; + msg.sender_origin = SecurityOrigin::CreateUniqueOpaque(); + msg.sender_agent_cluster_id = base::UnguessableToken::Create(); + msg.message = BuildSerializedScriptValue(scope.GetIsolate(), + wrapper, transferables); + mojo::Message mojo_message = + mojom::blink::TransferableMessage::SerializeAsMessage(&msg); + + // Without this, deserialization of a PendingRemote in the message + // always fails with VALIDATION_ERROR_ILLEGAL_HANDLE. + mojo::ScopedMessageHandle handle = mojo_message.TakeMojoMessage(); + mojo_message = mojo::Message::CreateFromMessageHandle(&handle); + + // The original bitmap must be held alive until the transfer + // completes. + EXPECT_FALSE(image_destroyed_); + BlinkTransferableMessage out; + ASSERT_TRUE( + mojom::blink::TransferableMessage::DeserializeFromMessage( + std::move(mojo_message), &out)); + ASSERT_EQ(out.message->GetImageBitmapContentsArray().size(), 1U); + })); + base::RunLoop().RunUntilIdle(); + + // The original bitmap shouldn't be held anywhere after deserialization has + // completed. Because release callbacks are posted over mojo, check the + // completion in a new task. + scope.GetExecutionContext() + ->GetTaskRunner(TaskType::kInternalTest) + ->PostTask(FROM_HERE, base::BindLambdaForTesting( + [&]() { EXPECT_TRUE(image_destroyed_); })); + base::RunLoop().RunUntilIdle(); +} + +TEST_F(BlinkTransferableMessageStructTraitsWithFakeGpuTest, + AcceleratedImageTransferReceiverCrash) { + V8TestingScope scope; + scope.GetExecutionContext() + ->GetTaskRunner(TaskType::kInternalTest) + ->PostTask( + FROM_HERE, base::BindLambdaForTesting([&]() { + ImageBitmap* image_bitmap = CreateAcceleratedStaticImageBitmap(); + + v8::Local<v8::Value> wrapper = + ToV8Traits<ImageBitmap>::ToV8(scope.GetScriptState(), + image_bitmap) + .ToLocalChecked(); + Transferables transferables; + transferables.image_bitmaps.push_back(image_bitmap); + BlinkTransferableMessage msg; + msg.sender_origin = SecurityOrigin::CreateUniqueOpaque(); + msg.sender_agent_cluster_id = base::UnguessableToken::Create(); + msg.message = BuildSerializedScriptValue(scope.GetIsolate(), + wrapper, transferables); + mojo::Message mojo_message = + mojom::blink::TransferableMessage::SerializeAsMessage(&msg); + // The original bitmap must be held alive before the transfer + // completes. + EXPECT_FALSE(image_destroyed_); + + // The mojo message is destroyed without deserialization to simulate + // the receiver process crash. + })); + base::RunLoop().RunUntilIdle(); + + // The original bitmap shouldn't be held anywhere after the mojo message is + // lost. Because release callbacks are posted over mojo, check the completion + // in a new task. + scope.GetExecutionContext() + ->GetTaskRunner(TaskType::kInternalTest) + ->PostTask(FROM_HERE, base::BindLambdaForTesting( + [&]() { EXPECT_TRUE(image_destroyed_); })); + base::RunLoop().RunUntilIdle(); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/paint/background_image_geometry.cc b/third_party/blink/renderer/core/paint/background_image_geometry.cc index 2d5f6a3..9a0571cc 100644 --- a/third_party/blink/renderer/core/paint/background_image_geometry.cc +++ b/third_party/blink/renderer/core/paint/background_image_geometry.cc
@@ -5,6 +5,7 @@ #include "third_party/blink/renderer/core/paint/background_image_geometry.h" #include "third_party/blink/renderer/core/frame/local_frame_view.h" +#include "third_party/blink/renderer/core/frame/settings.h" #include "third_party/blink/renderer/core/layout/layout_box.h" #include "third_party/blink/renderer/core/layout/layout_box_model_object.h" #include "third_party/blink/renderer/core/layout/layout_view.h" @@ -223,26 +224,36 @@ fill_layer.Attachment() == EFillAttachment::kFixed; } -namespace { +bool BackgroundImageGeometry::CanCompositeBackgroundAttachmentFixed() const { + return !painting_view_ && has_background_fixed_to_viewport_ && + positioning_box_->CanCompositeBackgroundAttachmentFixed(); +} -PhysicalRect FixedAttachmentPositioningArea(const PaintInfo& paint_info, - const LayoutBoxModelObject& obj) { - DCHECK(obj.View()); +PhysicalRect BackgroundImageGeometry::FixedAttachmentPositioningArea( + const PaintInfo& paint_info) const { + const ScrollableArea* layout_viewport = + box_->GetFrameView()->LayoutViewport(); + DCHECK(layout_viewport); + PhysicalSize size(layout_viewport->VisibleContentRect().size()); + if (CanCompositeBackgroundAttachmentFixed()) { + // The caller should have adjusted paint chunk properties to be in the + // viewport space. + return PhysicalRect(PhysicalOffset(), size); + } gfx::PointF viewport_origin_in_local_space = GeometryMapper::SourceToDestinationProjection( - obj.View()->FirstFragment().LocalBorderBoxProperties().Transform(), + box_->View()->FirstFragment().LocalBorderBoxProperties().Transform(), paint_info.context.GetPaintController() .CurrentPaintChunkProperties() .Transform()) .MapPoint(gfx::PointF()); - DCHECK(obj.GetFrameView()); - const ScrollableArea* layout_viewport = obj.GetFrameView()->LayoutViewport(); - DCHECK(layout_viewport); return PhysicalRect( PhysicalOffset::FromPointFRound(viewport_origin_in_local_space), PhysicalSize(layout_viewport->VisibleContentRect().size())); } +namespace { + // Computes the stitched table-grid rect relative to the current fragment. PhysicalRect ComputeStitchedTableGridRect( const NGPhysicalBoxFragment& fragment) { @@ -282,8 +293,7 @@ const LayoutView& view, const PhysicalOffset& element_positioning_area_offset) : box_(&view), positioning_box_(&view.RootBox()) { - has_background_fixed_to_viewport_ = - view.StyleRef().HasFixedAttachmentBackgroundImage(); + has_background_fixed_to_viewport_ = view.IsBackgroundAttachmentFixedObject(); painting_view_ = true; // The background of the box generated by the root element covers the // entire canvas and will be painted by the view object, but the we should @@ -334,31 +344,38 @@ BackgroundImageGeometry::BackgroundImageGeometry( const LayoutBoxModelObject* box, const LayoutBoxModelObject* positioning_box) - : box_(box), positioning_box_(positioning_box) { + : box_(box), + positioning_box_(positioning_box), + has_background_fixed_to_viewport_( + HasBackgroundFixedToViewport(*positioning_box)) { // Specialized constructor should be used for LayoutView. DCHECK(!IsA<LayoutView>(box)); DCHECK(box); DCHECK(positioning_box); - if (positioning_box->StyleRef().HasFixedAttachmentBackgroundImage()) { - has_background_fixed_to_viewport_ = true; - // https://www.w3.org/TR/css-transforms-1/#transform-rendering - // Fixed backgrounds on the root element are affected by any transform - // specified for that element. For all other elements that are effected - // by a transform, a value of fixed for the background-attachment property - // is treated as if it had a value of scroll. - for (const PaintLayer* layer = box->EnclosingLayer(); - layer && !layer->IsRootLayer(); layer = layer->Parent()) { - // Check LayoutObject::HasTransformRelatedProperty() first to exclude - // non-applicable transforms and will-change: transform. - LayoutObject& object = layer->GetLayoutObject(); - if (object.HasTransformRelatedProperty() && - (layer->Transform() || - object.StyleRef().HasWillChangeHintForAnyTransformProperty())) { - has_background_fixed_to_viewport_ = false; - break; - } +} + +bool BackgroundImageGeometry::HasBackgroundFixedToViewport( + const LayoutBoxModelObject& object) { + if (!object.IsBackgroundAttachmentFixedObject()) { + return false; + } + // https://www.w3.org/TR/css-transforms-1/#transform-rendering + // Fixed backgrounds on the root element are affected by any transform + // specified for that element. For all other elements that are effected + // by a transform, a value of fixed for the background-attachment property + // is treated as if it had a value of scroll. + for (const PaintLayer* layer = object.EnclosingLayer(); + layer && !layer->IsRootLayer(); layer = layer->Parent()) { + // Check LayoutObject::HasTransformRelatedProperty() first to exclude + // non-applicable transforms and will-change: transform. + LayoutObject& ancestor = layer->GetLayoutObject(); + if (ancestor.HasTransformRelatedProperty() && + (layer->Transform() || + ancestor.StyleRef().HasWillChangeHintForAnyTransformProperty())) { + return false; } } + return true; } void BackgroundImageGeometry::ComputeDestRectAdjustments( @@ -520,8 +537,7 @@ PhysicalOffset& snapped_box_offset) { if (ShouldUseFixedAttachment(fill_layer)) { // No snapping for fixed attachment. - unsnapped_positioning_area = - FixedAttachmentPositioningArea(paint_info, *box_); + unsnapped_positioning_area = FixedAttachmentPositioningArea(paint_info); unsnapped_dest_rect_ = snapped_dest_rect_ = snapped_positioning_area = unsnapped_positioning_area; } else { @@ -591,8 +607,7 @@ unsnapped_positioning_area.Contract(unsnapped_box_outset); unsnapped_positioning_area.size.ClampNegativeToZero(); - // Offset of the positioning area from the corner of the - // positioning_box_-> + // Offset of the positioning area from the corner of positioning_box_. unsnapped_box_offset = PhysicalOffset(unsnapped_box_outset.left - unsnapped_dest_adjust.left, unsnapped_box_outset.top - unsnapped_dest_adjust.top);
diff --git a/third_party/blink/renderer/core/paint/background_image_geometry.h b/third_party/blink/renderer/core/paint/background_image_geometry.h index e63283e..cbc0d4f 100644 --- a/third_party/blink/renderer/core/paint/background_image_geometry.h +++ b/third_party/blink/renderer/core/paint/background_image_geometry.h
@@ -93,6 +93,10 @@ const ComputedStyle& ImageStyle(const ComputedStyle& fragment_style) const; InterpolationQuality ImageInterpolationQuality() const; + bool CanCompositeBackgroundAttachmentFixed() const; + + static bool HasBackgroundFixedToViewport(const LayoutBoxModelObject&); + private: BackgroundImageGeometry(const LayoutBoxModelObject* box, const LayoutBoxModelObject* positioning_box); @@ -120,6 +124,7 @@ void SetSpaceX(LayoutUnit space, LayoutUnit extra_offset); void SetSpaceY(LayoutUnit space, LayoutUnit extra_offset); + PhysicalRect FixedAttachmentPositioningArea(const PaintInfo&) const; void UseFixedAttachment(const PhysicalOffset& attachment_point); // Compute adjustments for the destination rects. Adjustments @@ -155,15 +160,23 @@ // The offset of the background image within the background positioning area. PhysicalOffset OffsetInBackground(const FillLayer&) const; - // |box_| is the source for the Document. In most cases it also provides the - // background properties (see |positioning_box_| for exceptions.) It's also - // the image client unless painting the view background. + // In most cases this is the same as positioning_box_. They are different + // when we are painting: + // 1. the view background (box_ is the LayoutView, and positioning_box_ is + // the LayoutView's RootBox()), or + // 2. a table cell using its row/column's background (box_ is the table cell, + // and positioning_box_ is the row/column). + // When they are different: + // - ImageDocument() uses box_; + // - ImageClient() uses box_ if painting view, otherwise positioning_box_; + // - ImageStyle() uses positioning_box_; + // - ImageInterpolationQuality() uses box_; + // - FillLayers come from box_ if painting view, otherwise positioning_box_. const LayoutBoxModelObject* const box_; // The positioning box is the source of geometric information for positioning - // and sizing the background. It also provides the background properties if - // painting the view background or a table-cell using its container's - // (row's/column's) background. + // and sizing the background. It also provides the information listed in the + // comment for box_. const LayoutBoxModelObject* const positioning_box_; // When painting table cells or the view, the positioning area
diff --git a/third_party/blink/renderer/core/paint/box_decoration_data.h b/third_party/blink/renderer/core/paint/box_decoration_data.h index 7d8cc26..8bc42fc 100644 --- a/third_party/blink/renderer/core/paint/box_decoration_data.h +++ b/third_party/blink/renderer/core/paint/box_decoration_data.h
@@ -40,6 +40,17 @@ const NGPhysicalFragment& fragment) : BoxDecorationData(paint_info, fragment, fragment.Style()) {} + BoxDecorationData BackgroundOnly() const { + DCHECK(should_paint_background_); + return BoxDecorationData(*this, /*should_paint_background=*/true, + /*should_paint_border=*/false); + } + BoxDecorationData BorderOnly() const { + DCHECK(should_paint_border_); + return BoxDecorationData(*this, /*should_paint_background=*/false, + /*should_paint_border=*/true); + } + bool IsPaintingBackgroundInContentsSpace() const { return paint_info_.IsPaintingBackgroundInContentsSpace(); } @@ -78,6 +89,21 @@ ComputeShouldPaintBorder(has_non_collapsed_border_decoration)), should_paint_shadow_(ComputeShouldPaintShadow()) {} + // For BackgroundOnly() and BorderOnly(). + BoxDecorationData(const BoxDecorationData& data, + bool should_paint_background, + bool should_paint_border) + : paint_info_(data.paint_info_), + layout_box_(data.layout_box_), + style_(data.style_), + has_appearance_(false), + should_paint_background_(should_paint_background), + should_paint_border_(should_paint_border), + should_paint_shadow_(false) { + DCHECK(!data.has_appearance_); + DCHECK(!data.should_paint_shadow_); + } + bool ComputeShouldPaintBackground() const { return style_.HasBackground() && !layout_box_.BackgroundTransfersToView() && !paint_info_.ShouldSkipBackground();
diff --git a/third_party/blink/renderer/core/paint/box_painter_base.cc b/third_party/blink/renderer/core/paint/box_painter_base.cc index d068865b..91d3a15 100644 --- a/third_party/blink/renderer/core/paint/box_painter_base.cc +++ b/third_party/blink/renderer/core/paint/box_painter_base.cc
@@ -1109,41 +1109,48 @@ } absl::optional<RoundedInnerRectClipper> clip_to_border; - if (fill_layer_info.is_rounded_fill) + if (fill_layer_info.is_rounded_fill) { + DCHECK(!geometry.CanCompositeBackgroundAttachmentFixed()); clip_to_border.emplace(context, rect, border_rect); + } if (bg_layer.Clip() == EFillBox::kText) { + DCHECK(!geometry.CanCompositeBackgroundAttachmentFixed()); PaintFillLayerTextFillBox(paint_info, fill_layer_info, image.get(), composite_op, geometry, rect, scrolled_paint_rect, object_has_multiple_boxes); return; } - GraphicsContextStateSaver background_clip_state_saver(context, false); - switch (bg_layer.Clip()) { - case EFillBox::kPadding: - case EFillBox::kContent: { - if (fill_layer_info.is_rounded_fill) - break; + // We use BackgroundClip paint property when CanFastScrollFixedAttachment(). + absl::optional<GraphicsContextStateSaver> background_clip_state_saver; + if (!geometry.CanCompositeBackgroundAttachmentFixed()) { + switch (bg_layer.Clip()) { + case EFillBox::kPadding: + case EFillBox::kContent: { + if (fill_layer_info.is_rounded_fill) { + break; + } - // Clip to the padding or content boxes as necessary. - PhysicalRect clip_rect = scrolled_paint_rect; - clip_rect.Contract( - AdjustOutsetsForEdgeInclusion(border, fill_layer_info)); - if (bg_layer.Clip() == EFillBox::kContent) { + // Clip to the padding or content boxes as necessary. + PhysicalRect clip_rect = scrolled_paint_rect; clip_rect.Contract( - AdjustOutsetsForEdgeInclusion(padding, fill_layer_info)); + AdjustOutsetsForEdgeInclusion(border, fill_layer_info)); + if (bg_layer.Clip() == EFillBox::kContent) { + clip_rect.Contract( + AdjustOutsetsForEdgeInclusion(padding, fill_layer_info)); + } + background_clip_state_saver.emplace(context); + context.Clip(ToPixelSnappedRect(clip_rect)); + break; } - background_clip_state_saver.Save(); - context.Clip(ToPixelSnappedRect(clip_rect)); - break; + case EFillBox::kBorder: + break; + case EFillBox::kText: // fall through + default: + NOTREACHED(); + break; } - case EFillBox::kBorder: - break; - case EFillBox::kText: // fall through - default: - NOTREACHED(); - break; } PaintFillLayerBackground(document_, context, fill_layer_info, node_, style_,
diff --git a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc index bf4dfe7..4615481 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc +++ b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc
@@ -1102,20 +1102,81 @@ return; } + const auto& box = To<LayoutBox>(*box_fragment_.GetLayoutObject()); absl::optional<DisplayItemCacheSkipper> cache_skipper; if (RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled() && - ShouldSkipPaintUnderInvalidationChecking( - To<LayoutBox>(*box_fragment_.GetLayoutObject()))) { + ShouldSkipPaintUnderInvalidationChecking(box)) { cache_skipper.emplace(paint_info.context); } - if (DrawingRecorder::UseCachedDrawingIfPossible( - paint_info.context, background_client, - DisplayItem::kBoxDecorationBackground)) + if (box.CanCompositeBackgroundAttachmentFixed() && + BackgroundImageGeometry::HasBackgroundFixedToViewport(box)) { + PaintCompositeBackgroundAttachmentFixed(paint_info, background_client, + box_decoration_data); + if (box_decoration_data.ShouldPaintBorder()) { + PaintBoxDecorationBackgroundWithDecorationData( + paint_info, visual_rect, paint_rect, background_client, + DisplayItem::kBoxDecorationBackground, + box_decoration_data.BorderOnly()); + } + } else { + PaintBoxDecorationBackgroundWithDecorationData( + paint_info, visual_rect, paint_rect, background_client, + DisplayItem::kBoxDecorationBackground, box_decoration_data); + } +} + +void NGBoxFragmentPainter::PaintCompositeBackgroundAttachmentFixed( + const PaintInfo& paint_info, + const DisplayItemClient& background_client, + const BoxDecorationData& box_decoration_data) { + const auto& box = To<LayoutBox>(*box_fragment_.GetLayoutObject()); + DCHECK(box.CanCompositeBackgroundAttachmentFixed()); + const FragmentData* fragment_data = box_fragment_.GetFragmentData(); + if (!fragment_data) { return; + } + + // Paint the background-attachment:fixed background in the view's transform + // space, clipped by BackgroundClip. + DCHECK(!box_decoration_data.IsPaintingBackgroundInContentsSpace()); + DCHECK(!box_decoration_data.HasAppearance()); + DCHECK(!box_decoration_data.ShouldPaintShadow()); + DCHECK(box_decoration_data.ShouldPaintBackground()); + DCHECK(fragment_data->PaintProperties()); + DCHECK(fragment_data->PaintProperties()->BackgroundClip()); + PropertyTreeStateOrAlias state( + box.View()->FirstFragment().LocalBorderBoxProperties().Transform(), + *fragment_data->PaintProperties()->BackgroundClip(), + paint_info.context.GetPaintController() + .CurrentPaintChunkProperties() + .Effect()); + const ScrollableArea* layout_viewport = box.GetFrameView()->LayoutViewport(); + DCHECK(layout_viewport); + gfx::Rect background_rect(layout_viewport->VisibleContentRect().size()); + ScopedPaintChunkProperties fixed_background_properties( + paint_info.context.GetPaintController(), state, background_client, + DisplayItem::kFixedAttachmentBackground); + PaintBoxDecorationBackgroundWithDecorationData( + paint_info, background_rect, PhysicalRect(background_rect), + background_client, DisplayItem::kFixedAttachmentBackground, + box_decoration_data.BackgroundOnly()); +} + +void NGBoxFragmentPainter::PaintBoxDecorationBackgroundWithDecorationData( + const PaintInfo& paint_info, + const gfx::Rect& visual_rect, + const PhysicalRect& paint_rect, + const DisplayItemClient& background_client, + DisplayItem::Type display_item_type, + const BoxDecorationData& box_decoration_data) { + if (DrawingRecorder::UseCachedDrawingIfPossible( + paint_info.context, background_client, display_item_type)) { + return; + } DrawingRecorder recorder(paint_info.context, background_client, - DisplayItem::kBoxDecorationBackground, visual_rect); + display_item_type, visual_rect); if (PhysicalFragment().IsFieldsetContainer()) { NGFieldsetPainter(box_fragment_)
diff --git a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h index 0118d28a..579fcd6d 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h +++ b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h
@@ -117,6 +117,16 @@ const gfx::Rect& visual_rect, const PhysicalRect& paint_rect, const DisplayItemClient&); + void PaintCompositeBackgroundAttachmentFixed(const PaintInfo&, + const DisplayItemClient&, + const BoxDecorationData&); + void PaintBoxDecorationBackgroundWithDecorationData( + const PaintInfo&, + const gfx::Rect& visual_rect, + const PhysicalRect& paint_rect, + const DisplayItemClient&, + DisplayItem::Type, + const BoxDecorationData&); void PaintBoxDecorationBackgroundForBlockInInline( NGInlineCursor* children,
diff --git a/third_party/blink/renderer/core/paint/object_paint_properties.h b/third_party/blink/renderer/core/paint/object_paint_properties.h index cd97d9f..98fa226 100644 --- a/third_party/blink/renderer/core/paint/object_paint_properties.h +++ b/third_party/blink/renderer/core/paint/object_paint_properties.h
@@ -253,6 +253,9 @@ // +-[ OverflowControlsClip ] // | Clip created by overflow clip to clip overflow controls // | (scrollbars, resizer, scroll corner) that would overflow the box. + // +-[ BackgroundClip ] + // | Clip created for CompositeBackgroundAttachmentFixed background + // | according to CSS background-clip. // +-[ PixelMovingFilterClipExpander ] // | Clip created by pixel-moving filter. Instead of intersecting with // | the current clip, this clip expands the current clip to include all @@ -283,6 +286,7 @@ ADD_CLIP(CssClip, css_clip_); ADD_CLIP(CssClipFixedPosition, css_clip_fixed_position_); ADD_CLIP(OverflowControlsClip, overflow_controls_clip_); + ADD_CLIP(BackgroundClip, background_clip_); ADD_CLIP(InnerBorderRadiusClip, inner_border_radius_clip_); ADD_CLIP(OverflowClip, overflow_clip_); ADD_ALIAS_NODE(Clip, ClipIsolationNode, clip_isolation_node_);
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc index 8d33f88..49a48c0a 100644 --- a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc +++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
@@ -282,6 +282,7 @@ ALWAYS_INLINE void UpdateLocalBorderBoxContext(); ALWAYS_INLINE bool NeedsOverflowControlsClip() const; ALWAYS_INLINE void UpdateOverflowControlsClip(); + ALWAYS_INLINE void UpdateBackgroundClip(); ALWAYS_INLINE void UpdateInnerBorderRadiusClip(); ALWAYS_INLINE void UpdateOverflowClip(); ALWAYS_INLINE void UpdatePerspective(); @@ -2062,6 +2063,44 @@ // LayoutObjects under custom scrollbars don't support paint properties. } +static bool NeedsBackgroundClip(const LayoutObject& object) { + return object.CanCompositeBackgroundAttachmentFixed(); +} + +void FragmentPaintPropertyTreeBuilder::UpdateBackgroundClip() { + DCHECK(properties_); + + if (!NeedsPaintPropertyUpdate()) { + return; + } + if (NeedsBackgroundClip(object_)) { + DCHECK(!object_.StyleRef().BackgroundLayers().Next()); + const auto& fragment = pre_paint_info_ + ? pre_paint_info_->box_fragment + : *To<LayoutBox>(object_).GetPhysicalFragment(0); + PhysicalRect clip_rect(context_.current.paint_offset, fragment.Size()); + auto clip = object_.StyleRef().BackgroundLayers().Clip(); + if (clip == EFillBox::kContent || clip == EFillBox::kPadding) { + NGPhysicalBoxStrut strut = fragment.Borders(); + if (clip == EFillBox::kContent) { + strut += fragment.Padding(); + } + strut.TruncateSides(fragment.SidesToInclude()); + clip_rect.Contract(strut); + } + OnUpdateClip(properties_->UpdateBackgroundClip( + *context_.current.clip, + ClipPaintPropertyNode::State(context_.current.transform, + gfx::RectF(clip_rect), + ToSnappedClipRect(clip_rect)))); + } else { + OnClearClip(properties_->ClearBackgroundClip()); + } + + // BackgroundClip doesn't have descendants, so it doesn't affect the + // context_.current.affect descendants.clip. +} + static void AdjustRoundedClipForOverflowClipMargin( const LayoutBox& box, gfx::RectF& layout_clip_rect, @@ -2743,6 +2782,13 @@ } } + // We could check the change of border-box, padding-box or content-box + // according to background-clip, but checking layout change is much simpler + // and good enough for the rare cases of NeedsBackgroundClip(). + if (NeedsBackgroundClip(box) && box.ShouldCheckLayoutForPaintInvalidation()) { + box.GetMutableForPainting().SetOnlyThisNeedsPaintPropertyUpdate(); + } + // If we reach FragmentPaintPropertyTreeBuilder for an object needing a // pending transform update, we need to go ahead and do a regular transform // update so that the context (e.g., @@ -2899,6 +2945,7 @@ UpdateCssClip(); UpdateFilter(); UpdateOverflowControlsClip(); + UpdateBackgroundClip(); } else if (!object_.IsAnonymous()) { // 3D rendering contexts follow the DOM ancestor chain, so // flattening should apply regardless of presence of transform. @@ -3098,8 +3145,9 @@ NeedsTransformForSVGChild(object_, context_.direct_compositing_reasons) || NeedsFilter(object_, context_) || NeedsCssClip(object_) || - NeedsInnerBorderRadiusClip(object_) || NeedsOverflowClip(object_) || - NeedsPerspective(object_) || NeedsReplacedContentTransform(object_) || + NeedsBackgroundClip(object_) || NeedsInnerBorderRadiusClip(object_) || + NeedsOverflowClip(object_) || NeedsPerspective(object_) || + NeedsReplacedContentTransform(object_) || NeedsScrollOrScrollTranslation(object_, context_.direct_compositing_reasons));
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 774495d..1449171 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
@@ -7083,4 +7083,140 @@ EXPECT_FALSE(effect_properties->Effect()->HasDirectCompositingReasons()); } +#define EXPECT_BACKGROUND_CLIP(properties, rect) \ + do { \ + ASSERT_TRUE(properties); \ + ASSERT_TRUE(properties->BackgroundClip()); \ + EXPECT_EQ(rect, properties->BackgroundClip()->PaintClipRect().Rect()); \ + EXPECT_EQ(rect, properties->BackgroundClip()->LayoutClipRect().Rect()); \ + } while (false) + +TEST_P(PaintPropertyTreeBuilderTest, BackgroundClip) { + ScopedCompositeBackgroundAttachmentFixedForTest enabled(true); + SetPreferCompositingToLCDText(true); + + SetBodyInnerHTML(R"HTML( + <style> + body { margin: 0; } + #target { + width: 300px; + height: 200px; + border: 20px solid black; + padding: 10px; + box-sizing: border-box; + background-image: linear-gradient(blue, red); + background-attachment: fixed; + } + </style> + <div id="target"></div> + )HTML"); + + auto* target = GetDocument().getElementById("target"); + EXPECT_BACKGROUND_CLIP(PaintPropertiesForElement("target"), + gfx::RectF(0, 0, 300, 200)); + + target->setAttribute(html_names::kStyleAttr, "background-clip: padding-box"); + UpdateAllLifecyclePhasesForTest(); + EXPECT_BACKGROUND_CLIP(PaintPropertiesForElement("target"), + gfx::RectF(20, 20, 260, 160)); + + target->setAttribute(html_names::kStyleAttr, + "background-clip: padding-box; border-top-width: 15px"); + UpdateAllLifecyclePhasesForTest(); + EXPECT_BACKGROUND_CLIP(PaintPropertiesForElement("target"), + gfx::RectF(20, 15, 260, 165)); + + target->setAttribute(html_names::kStyleAttr, "background-clip: content-box"); + UpdateAllLifecyclePhasesForTest(); + EXPECT_BACKGROUND_CLIP(PaintPropertiesForElement("target"), + gfx::RectF(30, 30, 240, 140)); + + target->setAttribute(html_names::kStyleAttr, + "background-clip: content-box; padding-left: 25px"); + UpdateAllLifecyclePhasesForTest(); + EXPECT_BACKGROUND_CLIP(PaintPropertiesForElement("target"), + gfx::RectF(45, 30, 225, 140)); + + target->setAttribute(html_names::kStyleAttr, ""); + UpdateAllLifecyclePhasesForTest(); + EXPECT_BACKGROUND_CLIP(PaintPropertiesForElement("target"), + gfx::RectF(0, 0, 300, 200)); + + target->setAttribute(html_names::kStyleAttr, "border-radius: 20px"); + UpdateAllLifecyclePhasesForTest(); + EXPECT_FALSE(PaintPropertiesForElement("target")); + + target->setAttribute(html_names::kStyleAttr, ""); + UpdateAllLifecyclePhasesForTest(); + EXPECT_BACKGROUND_CLIP(PaintPropertiesForElement("target"), + gfx::RectF(0, 0, 300, 200)); + + target->setAttribute(html_names::kStyleAttr, "box-shadow: 10px 20px blue"); + UpdateAllLifecyclePhasesForTest(); + EXPECT_FALSE(PaintPropertiesForElement("target")); + + target->setAttribute(html_names::kStyleAttr, ""); + UpdateAllLifecyclePhasesForTest(); + EXPECT_BACKGROUND_CLIP(PaintPropertiesForElement("target"), + gfx::RectF(0, 0, 300, 200)); + + target->setAttribute(html_names::kStyleAttr, "background-attachment: local"); + UpdateAllLifecyclePhasesForTest(); + EXPECT_FALSE(PaintPropertiesForElement("target")); +} + +TEST_P(PaintPropertyTreeBuilderTest, BackgroundClipFragmented) { + ScopedCompositeBackgroundAttachmentFixedForTest enabled(true); + SetPreferCompositingToLCDText(true); + + SetBodyInnerHTML(R"HTML( + <style> + body { margin: 0; } + #target { + height: 600px; + border: 20px solid black; + padding: 10px; + box-sizing: border-box; + background-image: linear-gradient(blue, red); + background-attachment: fixed; + background-clip: content-box; + } + </style> + <div style="width: 300px; height: 200px; columns: 3; column-gap: 0"> + <div id="target"></div> + </div> + )HTML"); + + auto* target = GetLayoutObjectByElementId("target"); + ASSERT_EQ(3u, NumFragments(target)); + EXPECT_BACKGROUND_CLIP(FragmentAt(target, 0).PaintProperties(), + gfx::RectF(30, 30, 40, 170)); + EXPECT_BACKGROUND_CLIP(FragmentAt(target, 1).PaintProperties(), + gfx::RectF(130, 0, 40, 200)); + EXPECT_BACKGROUND_CLIP(FragmentAt(target, 2).PaintProperties(), + gfx::RectF(230, 0, 40, 170)); + + GetDocument().getElementById("target")->setAttribute( + html_names::kStyleAttr, "background-clip: padding-box"); + UpdateAllLifecyclePhasesForTest(); + ASSERT_EQ(3u, NumFragments(target)); + EXPECT_BACKGROUND_CLIP(FragmentAt(target, 0).PaintProperties(), + gfx::RectF(20, 20, 60, 180)); + EXPECT_BACKGROUND_CLIP(FragmentAt(target, 1).PaintProperties(), + gfx::RectF(120, 0, 60, 200)); + EXPECT_BACKGROUND_CLIP(FragmentAt(target, 2).PaintProperties(), + gfx::RectF(220, 0, 60, 180)); + + GetDocument().getElementById("target")->setAttribute( + html_names::kStyleAttr, "background-clip: border-box"); + UpdateAllLifecyclePhasesForTest(); + ASSERT_EQ(3u, NumFragments(target)); + EXPECT_BACKGROUND_CLIP(FragmentAt(target, 0).PaintProperties(), + gfx::RectF(0, 0, 100, 200)); + EXPECT_BACKGROUND_CLIP(FragmentAt(target, 1).PaintProperties(), + gfx::RectF(100, 0, 100, 200)); + EXPECT_BACKGROUND_CLIP(FragmentAt(target, 2).PaintProperties(), + gfx::RectF(200, 0, 100, 200)); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_printer.cc b/third_party/blink/renderer/core/paint/paint_property_tree_printer.cc index f650d8be..c095e30ba 100644 --- a/third_party/blink/renderer/core/paint/paint_property_tree_printer.cc +++ b/third_party/blink/renderer/core/paint/paint_property_tree_printer.cc
@@ -120,6 +120,7 @@ printer.AddNode(properties.CssClipFixedPosition()); printer.AddNode(properties.PixelMovingFilterClipExpander()); printer.AddNode(properties.OverflowControlsClip()); + printer.AddNode(properties.BackgroundClip()); printer.AddNode(properties.InnerBorderRadiusClip()); printer.AddNode(properties.OverflowClip()); printer.AddNode(properties.ClipIsolationNode()); @@ -253,6 +254,7 @@ "PixelMovingFilterClip", object); SetDebugName(properties.OverflowControlsClip(), "OverflowControlsClip", object); + SetDebugName(properties.BackgroundClip(), "BackgroundClip", object); SetDebugName(properties.InnerBorderRadiusClip(), "InnerBorderRadiusClip", object); SetDebugName(properties.OverflowClip(), "OverflowClip", object);
diff --git a/third_party/blink/renderer/core/speculation_rules/document_speculation_rules.cc b/third_party/blink/renderer/core/speculation_rules/document_speculation_rules.cc index 4fb44ee..28c309a8 100644 --- a/third_party/blink/renderer/core/speculation_rules/document_speculation_rules.cc +++ b/third_party/blink/renderer/core/speculation_rules/document_speculation_rules.cc
@@ -254,31 +254,19 @@ void DocumentSpeculationRules::ReferrerPolicyAttributeChanged( HTMLAnchorElement* link) { - if (!initialized_) - return; - - DCHECK(link->isConnected()); - InvalidateLink(link); - - QueueUpdateSpeculationCandidates(); + LinkAttributeChanged(link); } void DocumentSpeculationRules::RelAttributeChanged(HTMLAnchorElement* link) { - if (!initialized_) - return; + LinkAttributeChanged(link); +} - DCHECK(link->isConnected()); - InvalidateLink(link); - - QueueUpdateSpeculationCandidates(); +void DocumentSpeculationRules::TargetAttributeChanged(HTMLAnchorElement* link) { + LinkAttributeChanged(link); } void DocumentSpeculationRules::DocumentReferrerPolicyChanged() { - if (!initialized_) - return; - - InvalidateAllLinks(); - QueueUpdateSpeculationCandidates(); + DocumentPropertyChanged(); } void DocumentSpeculationRules::DocumentBaseURLChanged() { @@ -298,6 +286,10 @@ QueueUpdateSpeculationCandidates(); } +void DocumentSpeculationRules::DocumentBaseTargetChanged() { + DocumentPropertyChanged(); +} + void DocumentSpeculationRules::LinkMatchedSelectorsUpdated( HTMLAnchorElement* link) { DCHECK(initialized_); @@ -502,6 +494,9 @@ rule->eagerness().value_or( mojom::blink::SpeculationEagerness::kEager); + CHECK(!rule->target_browsing_context_name_hint() || + action == mojom::blink::SpeculationAction::kPrerender); + candidates.push_back(MakeGarbageCollected<SpeculationCandidate>( url, action, referrer.value(), rule->requires_anonymous_client_ip_when_cross_origin(), @@ -644,15 +639,25 @@ rule->eagerness().value_or( mojom::blink::SpeculationEagerness::kConservative); - // TODO(crbug.com/1371522): We should be generating a target hint - // based on the link's target. + mojom::blink::SpeculationTargetHint target_hint = + mojom::blink::SpeculationTargetHint::kNoHint; + if (action == mojom::blink::SpeculationAction::kPrerender) { + if (rule->target_browsing_context_name_hint()) { + target_hint = rule->target_browsing_context_name_hint().value(); + } else { + // Obtain target hint from the link's target (if specified). + target_hint = + SpeculationRuleSet::SpeculationTargetHintFromString( + link->GetEffectiveTarget()); + } + } + SpeculationCandidate* candidate = MakeGarbageCollected<SpeculationCandidate>( link->HrefURL(), action, referrer.value(), rule->requires_anonymous_client_ip_when_cross_origin(), - rule->target_browsing_context_name_hint().value_or( - mojom::blink::SpeculationTargetHint::kNoHint), - eagerness, rule->no_vary_search_expected().Clone(), + target_hint, eagerness, + rule->no_vary_search_expected().Clone(), rule->injection_world(), rule_set, link); link_candidates->push_back(std::move(candidate)); } @@ -708,6 +713,23 @@ } } +void DocumentSpeculationRules::LinkAttributeChanged(HTMLAnchorElement* link) { + if (!initialized_) { + return; + } + DCHECK(link->isConnected()); + InvalidateLink(link); + QueueUpdateSpeculationCandidates(); +} + +void DocumentSpeculationRules::DocumentPropertyChanged() { + if (!initialized_) { + return; + } + InvalidateAllLinks(); + QueueUpdateSpeculationCandidates(); +} + void DocumentSpeculationRules::AddLink(HTMLAnchorElement* link) { DCHECK(initialized_); DCHECK(link->IsLink());
diff --git a/third_party/blink/renderer/core/speculation_rules/document_speculation_rules.h b/third_party/blink/renderer/core/speculation_rules/document_speculation_rules.h index cb8f0f84..2c8204b 100644 --- a/third_party/blink/renderer/core/speculation_rules/document_speculation_rules.h +++ b/third_party/blink/renderer/core/speculation_rules/document_speculation_rules.h
@@ -59,8 +59,10 @@ const AtomicString& new_value); void ReferrerPolicyAttributeChanged(HTMLAnchorElement* link); void RelAttributeChanged(HTMLAnchorElement* link); + void TargetAttributeChanged(HTMLAnchorElement* link); void DocumentReferrerPolicyChanged(); void DocumentBaseURLChanged(); + void DocumentBaseTargetChanged(); void LinkMatchedSelectorsUpdated(HTMLAnchorElement* link); void LinkGainedOrLostComputedStyle(HTMLAnchorElement* link); void DocumentStyleUpdated(); @@ -93,6 +95,11 @@ // through the document in shadow-including tree order. void InitializeIfNecessary(); + // Helper methods that are used to deal with link/document attribute changes + // that could invalidate the list of speculation candidates. + void LinkAttributeChanged(HTMLAnchorElement* link); + void DocumentPropertyChanged(); + // Helper methods to modify |link_map_|. void AddLink(HTMLAnchorElement* link); void RemoveLink(HTMLAnchorElement* link);
diff --git a/third_party/blink/renderer/core/speculation_rules/speculation_rule_set.cc b/third_party/blink/renderer/core/speculation_rules/speculation_rule_set.cc index 5d0a4f31..d1048262 100644 --- a/third_party/blink/renderer/core/speculation_rules/speculation_rule_set.cc +++ b/third_party/blink/renderer/core/speculation_rules/speculation_rule_set.cc
@@ -261,16 +261,8 @@ target_hint_str + "\"."); return nullptr; } - // Currently only "_blank" and "_self" are supported. - // TODO(https://crbug.com/1354049): Support more browsing context names and - // keywords. - if (EqualIgnoringASCIICase(target_hint_str, "_blank")) { - target_hint = mojom::blink::SpeculationTargetHint::kBlank; - } else if (EqualIgnoringASCIICase(target_hint_str, "_self")) { - target_hint = mojom::blink::SpeculationTargetHint::kSelf; - } else { - target_hint = mojom::blink::SpeculationTargetHint::kNoHint; - } + target_hint = + SpeculationRuleSet::SpeculationTargetHintFromString(target_hint_str); } // Let referrerPolicy be the empty string. @@ -531,6 +523,22 @@ } } +// static +mojom::blink::SpeculationTargetHint +SpeculationRuleSet::SpeculationTargetHintFromString( + const StringView& target_hint_str) { + // Currently only "_blank" and "_self" are supported. + // TODO(https://crbug.com/1354049): Support more browsing context names and + // keywords. + if (EqualIgnoringASCIICase(target_hint_str, "_blank")) { + return mojom::blink::SpeculationTargetHint::kBlank; + } else if (EqualIgnoringASCIICase(target_hint_str, "_self")) { + return mojom::blink::SpeculationTargetHint::kSelf; + } else { + return mojom::blink::SpeculationTargetHint::kNoHint; + } +} + void SpeculationRuleSet::Trace(Visitor* visitor) const { visitor->Trace(prefetch_rules_); visitor->Trace(prefetch_with_subresources_rules_);
diff --git a/third_party/blink/renderer/core/speculation_rules/speculation_rule_set.h b/third_party/blink/renderer/core/speculation_rules/speculation_rule_set.h index 70f2d83..56c88c8 100644 --- a/third_party/blink/renderer/core/speculation_rules/speculation_rule_set.h +++ b/third_party/blink/renderer/core/speculation_rules/speculation_rule_set.h
@@ -94,6 +94,9 @@ bool HasError() const; bool ShouldReportUMAForError() const; + static mojom::blink::SpeculationTargetHint SpeculationTargetHintFromString( + const StringView& target_hint_str); + void Trace(Visitor*) const; private:
diff --git a/third_party/blink/renderer/core/speculation_rules/speculation_rule_set_test.cc b/third_party/blink/renderer/core/speculation_rules/speculation_rule_set_test.cc index a1995bb..b5e4ae15 100644 --- a/third_party/blink/renderer/core/speculation_rules/speculation_rule_set_test.cc +++ b/third_party/blink/renderer/core/speculation_rules/speculation_rule_set_test.cc
@@ -25,6 +25,7 @@ #include "third_party/blink/renderer/core/frame/web_feature.h" #include "third_party/blink/renderer/core/html/html_anchor_element.h" #include "third_party/blink/renderer/core/html/html_area_element.h" +#include "third_party/blink/renderer/core/html/html_base_element.h" #include "third_party/blink/renderer/core/html/html_div_element.h" #include "third_party/blink/renderer/core/html/html_head_element.h" #include "third_party/blink/renderer/core/html/html_meta_element.h" @@ -1900,6 +1901,15 @@ "action", &mojom::blink::SpeculationCandidate::action, matcher)); } +// Matches a SpeculationCandidatePtr with a SpeculationTargetHint. +auto HasTargetHint( + ::testing::Matcher<mojom::blink::SpeculationTargetHint> matcher) { + return ::testing::Pointee(::testing::Field( + "target_hint", + &mojom::blink::SpeculationCandidate::target_browsing_context_name_hint, + matcher)); +} + // Matches a SpeculationCandidatePtr with a ReferrerPolicy. auto HasReferrerPolicy( ::testing::Matcher<network::mojom::ReferrerPolicy> matcher) { @@ -2600,6 +2610,97 @@ EXPECT_THAT(candidates, HasURLs("https://bar.com/bart")); } +TEST_F(DocumentRulesTest, TargetHintFromLink) { + DummyPageHolder page_holder; + StubSpeculationHost speculation_host; + Document& document = page_holder.GetDocument(); + + auto* anchor_1 = AddAnchor(*document.body(), "https://foo.com/bar"); + anchor_1->setAttribute(html_names::kTargetAttr, "_blank"); + auto* anchor_2 = AddAnchor(*document.body(), "https://fizz.com/buzz"); + anchor_2->setAttribute(html_names::kTargetAttr, "_self"); + AddAnchor(*document.body(), "https://hello.com/world"); + + String speculation_script = R"( + { + "prefetch": [{ + "source": "document", + "where": {"href_matches": "https://foo.com/bar"} + }], + "prerender": [{"source": "document"}] + } + )"; + PropagateRulesToStubSpeculationHost(page_holder, speculation_host, + speculation_script); + const auto& candidates = speculation_host.candidates(); + EXPECT_THAT( + candidates, + ::testing::UnorderedElementsAre( + ::testing::AllOf( + HasAction(mojom::blink::SpeculationAction::kPrefetch), + HasTargetHint(mojom::blink::SpeculationTargetHint::kNoHint)), + ::testing::AllOf( + HasURL(KURL("https://foo.com/bar")), + HasAction(mojom::blink::SpeculationAction::kPrerender), + HasTargetHint(mojom::blink::SpeculationTargetHint::kBlank)), + ::testing::AllOf( + HasURL(KURL("https://fizz.com/buzz")), + HasAction(mojom::blink::SpeculationAction::kPrerender), + HasTargetHint(mojom::blink::SpeculationTargetHint::kSelf)), + ::testing::AllOf( + HasURL(KURL("https://hello.com/world")), + HasAction(mojom::blink::SpeculationAction::kPrerender), + HasTargetHint(mojom::blink::SpeculationTargetHint::kNoHint)))); +} + +TEST_F(DocumentRulesTest, TargetHintFromSpeculationRuleOverridesLinkTarget) { + DummyPageHolder page_holder; + StubSpeculationHost speculation_host; + Document& document = page_holder.GetDocument(); + + auto* anchor = AddAnchor(*document.body(), "https://foo.com/bar"); + anchor->setAttribute(html_names::kTargetAttr, "_blank"); + + String speculation_script = R"( + {"prerender": [{"source": "document", "target_hint": "_self"}]} + )"; + PropagateRulesToStubSpeculationHost(page_holder, speculation_host, + speculation_script); + const auto& candidates = speculation_host.candidates(); + EXPECT_THAT(candidates, ::testing::ElementsAre(HasTargetHint( + mojom::blink::SpeculationTargetHint::kSelf))); +} + +TEST_F(DocumentRulesTest, TargetHintFromLinkDynamic) { + DummyPageHolder page_holder; + StubSpeculationHost speculation_host; + Document& document = page_holder.GetDocument(); + + auto* anchor = AddAnchor(*document.body(), "https://foo.com/bar"); + + String speculation_script = R"({"prerender": [{"source": "document"}]})"; + PropagateRulesToStubSpeculationHost(page_holder, speculation_host, + speculation_script); + const auto& candidates = speculation_host.candidates(); + EXPECT_THAT(candidates, ::testing::ElementsAre(HasTargetHint( + mojom::blink::SpeculationTargetHint::kNoHint))); + + HTMLBaseElement* base_element; + PropagateRulesToStubSpeculationHost(page_holder, speculation_host, [&]() { + base_element = MakeGarbageCollected<HTMLBaseElement>(document); + base_element->setAttribute(html_names::kTargetAttr, "_self"); + document.head()->appendChild(base_element); + }); + EXPECT_THAT(candidates, ::testing::ElementsAre(HasTargetHint( + mojom::blink::SpeculationTargetHint::kSelf))); + + PropagateRulesToStubSpeculationHost(page_holder, speculation_host, [&]() { + anchor->setAttribute(html_names::kTargetAttr, "_blank"); + }); + EXPECT_THAT(candidates, ::testing::ElementsAre(HasTargetHint( + mojom::blink::SpeculationTargetHint::kBlank))); +} + // Tests that "selector_matches" is not parsed without the RuntimeEnabledFeature // enabled. TEST_F(DocumentRulesTest, SelectorMatchesIsNotParsed) {
diff --git a/third_party/blink/renderer/core/style/basic_shapes.cc b/third_party/blink/renderer/core/style/basic_shapes.cc index 2133808..31edf3a2 100644 --- a/third_party/blink/renderer/core/style/basic_shapes.cc +++ b/third_party/blink/renderer/core/style/basic_shapes.cc
@@ -66,7 +66,7 @@ void BasicShapeCircle::GetPath(Path& path, const gfx::RectF& bounding_box, - float) { + float) const { DCHECK(path.IsEmpty()); gfx::PointF center = PointForCenterCoordinate(center_x_, center_y_, bounding_box.size()); @@ -99,7 +99,7 @@ void BasicShapeEllipse::GetPath(Path& path, const gfx::RectF& bounding_box, - float) { + float) const { DCHECK(path.IsEmpty()); gfx::PointF center = PointForCenterCoordinate(center_x_, center_y_, bounding_box.size()); @@ -112,7 +112,7 @@ void BasicShapePolygon::GetPath(Path& path, const gfx::RectF& bounding_box, - float) { + float) const { DCHECK(path.IsEmpty()); DCHECK(!(values_.size() % 2)); wtf_size_t length = values_.size(); @@ -154,7 +154,7 @@ void BasicShapeInset::GetPath(Path& path, const gfx::RectF& bounding_box, - float) { + float) const { DCHECK(path.IsEmpty()); float left = FloatValueForLength(left_, bounding_box.width()); float top = FloatValueForLength(top_, bounding_box.height()); @@ -180,7 +180,7 @@ void BasicShapeRect::GetPath(Path& path, const gfx::RectF& bounding_box, - float) { + float) const { DCHECK(path.IsEmpty()); // The following computes |left|, |right| as the inset from the left edge @@ -225,7 +225,7 @@ void BasicShapeXYWH::GetPath(Path& path, const gfx::RectF& bounding_box, - float) { + float) const { DCHECK(path.IsEmpty()); gfx::RectF rect(FloatValueForLength(x_, bounding_box.width()), FloatValueForLength(y_, bounding_box.height()),
diff --git a/third_party/blink/renderer/core/style/basic_shapes.h b/third_party/blink/renderer/core/style/basic_shapes.h index 10e7143..190513d 100644 --- a/third_party/blink/renderer/core/style/basic_shapes.h +++ b/third_party/blink/renderer/core/style/basic_shapes.h
@@ -70,7 +70,7 @@ return GetType() == other.GetType(); } - virtual void GetPath(Path&, const gfx::RectF&, float zoom) = 0; + virtual void GetPath(Path&, const gfx::RectF&, float zoom) const = 0; bool operator==(const BasicShape& o) const { return IsSameType(o) && IsEqualAssumingSameType(o); } @@ -153,7 +153,7 @@ void SetCenterY(BasicShapeCenterCoordinate center_y) { center_y_ = center_y; } void SetRadius(BasicShapeRadius radius) { radius_ = radius; } - void GetPath(Path&, const gfx::RectF&, float) override; + void GetPath(Path&, const gfx::RectF&, float) const override; ShapeType GetType() const override { return kBasicShapeCircleType; } @@ -194,7 +194,7 @@ void SetRadiusX(BasicShapeRadius radius_x) { radius_x_ = radius_x; } void SetRadiusY(BasicShapeRadius radius_y) { radius_y_ = radius_y; } - void GetPath(Path&, const gfx::RectF&, float) override; + void GetPath(Path&, const gfx::RectF&, float) const override; ShapeType GetType() const override { return kBasicShapeEllipseType; } @@ -231,7 +231,7 @@ values_.push_back(y); } - void GetPath(Path&, const gfx::RectF&, float) override; + void GetPath(Path&, const gfx::RectF&, float) const override; WindRule GetWindRule() const { return wind_rule_; } @@ -306,7 +306,7 @@ } ShapeType GetType() const override { return kBasicShapeInsetType; } - void GetPath(Path&, const gfx::RectF&, float) override; + void GetPath(Path&, const gfx::RectF&, float) const override; }; template <> @@ -323,7 +323,7 @@ } ShapeType GetType() const override { return kBasicShapeRectType; } - void GetPath(Path&, const gfx::RectF&, float) override; + void GetPath(Path&, const gfx::RectF&, float) const override; }; template <> @@ -373,7 +373,7 @@ bottom_left_radius_ = radius; } - void GetPath(Path&, const gfx::RectF&, float) override; + void GetPath(Path&, const gfx::RectF&, float) const override; ShapeType GetType() const override { return kBasicShapeXYWHType; } protected:
diff --git a/third_party/blink/renderer/core/style/style_path.cc b/third_party/blink/renderer/core/style/style_path.cc index 32b54867c..c9daf36 100644 --- a/third_party/blink/renderer/core/style/style_path.cc +++ b/third_party/blink/renderer/core/style/style_path.cc
@@ -69,7 +69,9 @@ return wind_rule_ == other.wind_rule_ && *byte_stream_ == *other.byte_stream_; } -void StylePath::GetPath(Path& path, const gfx::RectF& offset_rect, float zoom) { +void StylePath::GetPath(Path& path, + const gfx::RectF& offset_rect, + float zoom) const { path = GetPath(); path.Transform(AffineTransform::Translation(offset_rect.x(), offset_rect.y()) .Scale(zoom));
diff --git a/third_party/blink/renderer/core/style/style_path.h b/third_party/blink/renderer/core/style/style_path.h index 057ccb7..03ca68e 100644 --- a/third_party/blink/renderer/core/style/style_path.h +++ b/third_party/blink/renderer/core/style/style_path.h
@@ -32,7 +32,7 @@ CSSValue* ComputedCSSValue() const; - void GetPath(Path&, const gfx::RectF&, float zoom) override; + void GetPath(Path&, const gfx::RectF&, float zoom) const override; WindRule GetWindRule() const { return wind_rule_; } ShapeType GetType() const override { return kStylePathType; }
diff --git a/third_party/blink/renderer/core/style/style_ray.cc b/third_party/blink/renderer/core/style/style_ray.cc index 6004acc5..8047cc0c 100644 --- a/third_party/blink/renderer/core/style/style_ray.cc +++ b/third_party/blink/renderer/core/style/style_ray.cc
@@ -26,7 +26,7 @@ contain_ == other.contain_; } -void StyleRay::GetPath(Path&, const gfx::RectF&, float) { +void StyleRay::GetPath(Path&, const gfx::RectF&, float) const { // ComputedStyle::ApplyMotionPathTransform cannot call GetPath // for rays as they may have infinite length. NOTREACHED();
diff --git a/third_party/blink/renderer/core/style/style_ray.h b/third_party/blink/renderer/core/style/style_ray.h index cbe0e7d..10cb7ebd 100644 --- a/third_party/blink/renderer/core/style/style_ray.h +++ b/third_party/blink/renderer/core/style/style_ray.h
@@ -37,7 +37,7 @@ RaySize Size() const { return size_; } bool Contain() const { return contain_; } - void GetPath(Path&, const gfx::RectF&, float) override; + void GetPath(Path&, const gfx::RectF&, float) const override; ShapeType GetType() const override { return kStyleRayType; }
diff --git a/third_party/blink/renderer/modules/ad_auction/navigator_auction.cc b/third_party/blink/renderer/modules/ad_auction/navigator_auction.cc index f54bcd3..091bb41 100644 --- a/third_party/blink/renderer/modules/ad_auction/navigator_auction.cc +++ b/third_party/blink/renderer/modules/ad_auction/navigator_auction.cc
@@ -1501,7 +1501,8 @@ mojom::blink::AuctionAdConfigBuyerCurrencies::New(); buyer_currencies->per_buyer_currencies.emplace(); for (const auto& per_buyer_currency : decoded) { - if (!IsValidAdCurrencyCode(per_buyer_currency.second.Ascii())) { + std::string per_buyer_currency_str = per_buyer_currency.second.Ascii(); + if (!IsValidAdCurrencyCode(per_buyer_currency_str)) { exception_state.ThrowTypeError(ErrorInvalidAuctionConfigSeller( seller_name, "perBuyerCurrencies currency", per_buyer_currency.second, "must be a 3-letter uppercase currency code.")); @@ -1509,7 +1510,8 @@ } if (per_buyer_currency.first == "*") { - buyer_currencies->all_buyers_currency = per_buyer_currency.second; + buyer_currencies->all_buyers_currency = + blink::AdCurrency::From(per_buyer_currency_str); continue; } scoped_refptr<const SecurityOrigin> buyer = @@ -1520,8 +1522,8 @@ "must be \"*\" (wildcard) or a valid https origin.")); return nullptr; } - buyer_currencies->per_buyer_currencies->insert(buyer, - per_buyer_currency.second); + buyer_currencies->per_buyer_currencies->insert( + buyer, blink::AdCurrency::From(per_buyer_currency_str)); } return buyer_currencies; @@ -1847,14 +1849,15 @@ } if (config.hasSellerCurrency()) { - if (!IsValidAdCurrencyCode(config.sellerCurrency().Ascii())) { + std::string seller_currency_str = config.sellerCurrency().Ascii(); + if (!IsValidAdCurrencyCode(seller_currency_str)) { exception_state.ThrowTypeError(ErrorInvalidAuctionConfigSeller( config.seller(), "sellerCurrency", config.sellerCurrency(), "must be a 3-letter uppercase currency code.")); return mojom::blink::AuctionAdConfigPtr(); } mojo_config->auction_ad_config_non_shared_params->seller_currency = - config.sellerCurrency(); + blink::AdCurrency::From(seller_currency_str); } // Recursively handle component auctions, if there are any.
diff --git a/third_party/blink/renderer/modules/exported/web_shared_storage_worklet_thread_impl.cc b/third_party/blink/renderer/modules/exported/web_shared_storage_worklet_thread_impl.cc index fb9831c..509edb9 100644 --- a/third_party/blink/renderer/modules/exported/web_shared_storage_worklet_thread_impl.cc +++ b/third_party/blink/renderer/modules/exported/web_shared_storage_worklet_thread_impl.cc
@@ -4,7 +4,7 @@ #include "third_party/blink/renderer/modules/exported/web_shared_storage_worklet_thread_impl.h" -#include "third_party/blink/public/mojom/shared_storage/shared_storage_worklet_service.mojom.h" +#include "third_party/blink/public/mojom/shared_storage/shared_storage_worklet_service.mojom-blink.h" #include "third_party/blink/renderer/core/workers/threaded_worklet_object_proxy.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" @@ -13,14 +13,15 @@ // static void WebSharedStorageWorkletThread::Start( scoped_refptr<base::SingleThreadTaskRunner> main_thread_runner, - mojo::PendingReceiver<mojom::SharedStorageWorkletService> receiver) { + CrossVariantMojoReceiver< + mojom::blink::SharedStorageWorkletServiceInterfaceBase> receiver) { MakeGarbageCollected<WebSharedStorageWorkletThreadImpl>(main_thread_runner, std::move(receiver)); } WebSharedStorageWorkletThreadImpl::WebSharedStorageWorkletThreadImpl( scoped_refptr<base::SingleThreadTaskRunner> main_thread_runner, - mojo::PendingReceiver<mojom::SharedStorageWorkletService> receiver) + mojo::PendingReceiver<mojom::blink::SharedStorageWorkletService> receiver) : main_thread_runner_(std::move(main_thread_runner)) { DCHECK(main_thread_runner_->BelongsToCurrentThread());
diff --git a/third_party/blink/renderer/modules/exported/web_shared_storage_worklet_thread_impl.h b/third_party/blink/renderer/modules/exported/web_shared_storage_worklet_thread_impl.h index ce29098..ce38979 100644 --- a/third_party/blink/renderer/modules/exported/web_shared_storage_worklet_thread_impl.h +++ b/third_party/blink/renderer/modules/exported/web_shared_storage_worklet_thread_impl.h
@@ -5,7 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_EXPORTED_WEB_SHARED_STORAGE_WORKLET_THREAD_IMPL_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_EXPORTED_WEB_SHARED_STORAGE_WORKLET_THREAD_IMPL_H_ -#include "third_party/blink/public/mojom/shared_storage/shared_storage_worklet_service.mojom-forward.h" +#include "third_party/blink/public/mojom/shared_storage/shared_storage_worklet_service.mojom-blink-forward.h" #include "third_party/blink/public/web/web_shared_storage_worklet_thread.h" #include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_messaging_proxy.h" @@ -23,7 +23,8 @@ public: WebSharedStorageWorkletThreadImpl( scoped_refptr<base::SingleThreadTaskRunner> main_thread_runner, - mojo::PendingReceiver<mojom::SharedStorageWorkletService> receiver); + mojo::PendingReceiver<mojom::blink::SharedStorageWorkletService> + receiver); ~WebSharedStorageWorkletThreadImpl() override;
diff --git a/third_party/blink/renderer/modules/payments/payment_request.cc b/third_party/blink/renderer/modules/payments/payment_request.cc index 3bda1295..d2a5cad 100644 --- a/third_party/blink/renderer/modules/payments/payment_request.cc +++ b/third_party/blink/renderer/modules/payments/payment_request.cc
@@ -803,6 +803,32 @@ mojom::ConsoleMessageLevel::kWarning, error)); } +// Returns whether a Show() call may be allowed without a user activation, +// based on the request method and feature state. +bool ActivationlessShowEnabled(ExecutionContext* execution_context, + const HashSet<String>& method_names) { + if (method_names.size() == 1 && + method_names.Contains(kSecurePaymentConfirmationMethod)) { + return RuntimeEnabledFeatures:: + SecurePaymentConfirmationAllowOneActivationlessShowEnabled( + execution_context); + } + + // Activationless show is currently only possible for the Secure Payment + // Confirmation method. + return false; +} + +// Records metrics for an activationless Show() call based on the request +// method. +void RecordActivationlessShow(ExecutionContext* execution_context, + const HashSet<String>& method_names) { + DCHECK((method_names.size() == 1 && + method_names.Contains(kSecurePaymentConfirmationMethod))); + UseCounter::Count(execution_context, + WebFeature::kSecurePaymentConfirmationActivationlessShow); +} + } // namespace PaymentRequest* PaymentRequest::Create( @@ -860,21 +886,31 @@ bool has_transient_user_activation = LocalFrame::HasTransientUserActivation(local_frame); - bool payment_request_token_active = - DomWindow()->IsPaymentRequestTokenActive(); + bool has_delegated_activation = DomWindow()->IsPaymentRequestTokenActive(); if (!has_transient_user_activation) { UseCounter::Count(GetExecutionContext(), WebFeature::kPaymentRequestShowWithoutGesture); - if (!payment_request_token_active) { + if (!has_delegated_activation) { UseCounter::Count(GetExecutionContext(), WebFeature::kPaymentRequestShowWithoutGestureOrToken); } } - bool payment_request_allowed = - has_transient_user_activation || payment_request_token_active; + bool activationless_payment_request = + ActivationlessShowEnabled(GetExecutionContext(), method_names_) && + !has_transient_user_activation && !has_delegated_activation && + !DomWindow()->HadActivationlessPaymentRequest(); + + if (activationless_payment_request) { + DomWindow()->SetHadActivationlessPaymentRequest(); + RecordActivationlessShow(GetExecutionContext(), method_names_); + } + + bool payment_request_allowed = has_transient_user_activation || + has_delegated_activation || + activationless_payment_request; DomWindow()->ConsumePaymentRequestToken(); if (payment_request_allowed) {
diff --git a/third_party/blink/renderer/modules/payments/payment_request_test.cc b/third_party/blink/renderer/modules/payments/payment_request_test.cc index 93c409d..a6d2ea6 100644 --- a/third_party/blink/renderer/modules/payments/payment_request_test.cc +++ b/third_party/blink/renderer/modules/payments/payment_request_test.cc
@@ -686,5 +686,110 @@ /*stringified_details=*/"{}"); } +TEST(PaymentRequestTest, SPCActivationlessShowEnabled) { + ScopedSecurePaymentConfirmationAllowOneActivationlessShowForTest + scoped_activationless_show_enabled(true); + + PaymentRequestV8TestingScope scope; + MockFunctionScope funcs(scope.GetScriptState()); + + { + PaymentRequest* request = PaymentRequest::Create( + ExecutionContext::From(scope.GetScriptState()), + BuildSecurePaymentConfirmationMethodDataForTest(scope), + BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION); + + EXPECT_FALSE(scope.GetDocument().IsUseCounted( + WebFeature::kSecurePaymentConfirmationActivationlessShow)); + EXPECT_FALSE(scope.GetDocument().IsUseCounted( + WebFeature::kPaymentRequestShowWithoutGestureOrToken)); + request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION) + .Then(funcs.ExpectNoCall(), funcs.ExpectNoCall()); + EXPECT_FALSE(LocalFrame::HasTransientUserActivation(&(scope.GetFrame()))); + EXPECT_TRUE(scope.GetDocument().IsUseCounted( + WebFeature::kSecurePaymentConfirmationActivationlessShow)); + EXPECT_TRUE(scope.GetDocument().IsUseCounted( + WebFeature::kPaymentRequestShowWithoutGestureOrToken)); + } + + // After the first activationless SPC call is allowed, a second should fail. + { + PaymentRequest* request = PaymentRequest::Create( + ExecutionContext::From(scope.GetScriptState()), + BuildSecurePaymentConfirmationMethodDataForTest(scope), + BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION); + + request->show(scope.GetScriptState(), scope.GetExceptionState()); + EXPECT_EQ(scope.GetExceptionState().Code(), + ToExceptionCode(DOMExceptionCode::kSecurityError)); + } +} + +TEST(PaymentRequestTest, SPCActivationlessShowDisabled) { + ScopedSecurePaymentConfirmationAllowOneActivationlessShowForTest + scoped_activationless_show_enabled(false); + + PaymentRequestV8TestingScope scope; + MockFunctionScope funcs(scope.GetScriptState()); + PaymentRequest* request = PaymentRequest::Create( + ExecutionContext::From(scope.GetScriptState()), + BuildSecurePaymentConfirmationMethodDataForTest(scope), + BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION); + + EXPECT_FALSE(scope.GetDocument().IsUseCounted( + WebFeature::kSecurePaymentConfirmationActivationlessShow)); + EXPECT_FALSE(scope.GetDocument().IsUseCounted( + WebFeature::kPaymentRequestShowWithoutGestureOrToken)); + request->show(scope.GetScriptState(), scope.GetExceptionState()); + EXPECT_EQ(scope.GetExceptionState().Code(), + ToExceptionCode(DOMExceptionCode::kSecurityError)); + EXPECT_FALSE(scope.GetDocument().IsUseCounted( + WebFeature::kSecurePaymentConfirmationActivationlessShow)); + EXPECT_TRUE(scope.GetDocument().IsUseCounted( + WebFeature::kPaymentRequestShowWithoutGestureOrToken)); +} + +TEST(PaymentRequestTest, SPCActivationlessNotConsumedWithActivation) { + ScopedSecurePaymentConfirmationAllowOneActivationlessShowForTest + scoped_activationless_show_enabled(true); + + PaymentRequestV8TestingScope scope; + MockFunctionScope funcs(scope.GetScriptState()); + + // The first show call has an activation, so activationless SPC shouldn't be + // recorded or consumed. + { + PaymentRequest* request = PaymentRequest::Create( + ExecutionContext::From(scope.GetScriptState()), + BuildSecurePaymentConfirmationMethodDataForTest(scope), + BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION); + + LocalFrame::NotifyUserActivation( + &scope.GetFrame(), mojom::UserActivationNotificationType::kTest); + request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION) + .Then(funcs.ExpectNoCall(), funcs.ExpectNoCall()); + EXPECT_FALSE(scope.GetDocument().IsUseCounted( + WebFeature::kSecurePaymentConfirmationActivationlessShow)); + EXPECT_FALSE(scope.GetDocument().IsUseCounted( + WebFeature::kPaymentRequestShowWithoutGestureOrToken)); + } + + // A following activationless SPC show call should be allowed, since the first + // did not consume the one allowed activationless call. + { + PaymentRequest* request = PaymentRequest::Create( + ExecutionContext::From(scope.GetScriptState()), + BuildSecurePaymentConfirmationMethodDataForTest(scope), + BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION); + + request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION) + .Then(funcs.ExpectNoCall(), funcs.ExpectNoCall()); + EXPECT_TRUE(scope.GetDocument().IsUseCounted( + WebFeature::kSecurePaymentConfirmationActivationlessShow)); + EXPECT_TRUE(scope.GetDocument().IsUseCounted( + WebFeature::kPaymentRequestShowWithoutGestureOrToken)); + } +} + } // namespace } // namespace blink
diff --git a/third_party/blink/renderer/modules/payments/payment_test_helper.cc b/third_party/blink/renderer/modules/payments/payment_test_helper.cc index edb1108..7ccbf6f 100644 --- a/third_party/blink/renderer/modules/payments/payment_test_helper.cc +++ b/third_party/blink/renderer/modules/payments/payment_test_helper.cc
@@ -4,6 +4,9 @@ #include "third_party/blink/renderer/modules/payments/payment_test_helper.h" +#include "third_party/blink/renderer/bindings/core/v8/script_value.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_union_arraybuffer_arraybufferview.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_credential_instrument.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_payment_currency_amount.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_payment_details_modifier.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_payment_method_data.h" @@ -215,4 +218,53 @@ PaymentRequestV8TestingScope::PaymentRequestV8TestingScope() : V8TestingScope(KURL("https://www.example.com/")) {} +SecurePaymentConfirmationRequest* CreateSecurePaymentConfirmationRequest( + const V8TestingScope& scope, + const bool include_payee_name) { + SecurePaymentConfirmationRequest* request = + SecurePaymentConfirmationRequest::Create(scope.GetIsolate()); + + HeapVector<Member<V8UnionArrayBufferOrArrayBufferView>> credentialIds; + credentialIds.push_back( + MakeGarbageCollected<V8UnionArrayBufferOrArrayBufferView>( + DOMArrayBuffer::Create( + kSecurePaymentConfirmationCredentialId, + std::size(kSecurePaymentConfirmationCredentialId)))); + request->setCredentialIds(credentialIds); + + request->setChallenge( + MakeGarbageCollected<V8UnionArrayBufferOrArrayBufferView>( + DOMArrayBuffer::Create( + kSecurePaymentConfirmationChallenge, + std::size(kSecurePaymentConfirmationChallenge)))); + + PaymentCredentialInstrument* instrument = + PaymentCredentialInstrument::Create(scope.GetIsolate()); + instrument->setDisplayName("My Card"); + instrument->setIcon("https://bank.example/icon.png"); + request->setInstrument(instrument); + + request->setRpId("bank.example"); + + if (include_payee_name) { + request->setPayeeName("Merchant Shop"); + } + + return request; +} + +HeapVector<Member<PaymentMethodData>> +BuildSecurePaymentConfirmationMethodDataForTest(const V8TestingScope& scope) { + SecurePaymentConfirmationRequest* spc_request = + CreateSecurePaymentConfirmationRequest(scope); + + HeapVector<Member<PaymentMethodData>> method_data( + 1, PaymentMethodData::Create()); + method_data[0]->setSupportedMethod("secure-payment-confirmation"); + method_data[0]->setData(ScriptValue( + scope.GetIsolate(), spc_request->ToV8Value(scope.GetScriptState()))); + + return method_data; +} + } // namespace blink
diff --git a/third_party/blink/renderer/modules/payments/payment_test_helper.h b/third_party/blink/renderer/modules/payments/payment_test_helper.h index e18e57c..454f6b2 100644 --- a/third_party/blink/renderer/modules/payments/payment_test_helper.h +++ b/third_party/blink/renderer/modules/payments/payment_test_helper.h
@@ -14,6 +14,7 @@ #include "third_party/blink/renderer/bindings/modules/v8/v8_payment_details_update.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_payment_item.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_payment_shipping_option.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_secure_payment_confirmation_request.h" #include "third_party/blink/renderer/platform/heap/collection_support/heap_vector.h" #include "third_party/blink/renderer/platform/heap/persistent.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" @@ -93,6 +94,24 @@ PaymentRequestV8TestingScope(); }; +const uint8_t kSecurePaymentConfirmationCredentialId[] = { + 0x63, 0x72, 0x65, 0x64, 0x65, 0x6E, 0x74, 0x69, 0x61, 0x6C}; +const uint8_t kSecurePaymentConfirmationChallenge[] = { + 0x63, 0x68, 0x61, 0x6C, 0x6C, 0x65, 0x6E, 0x67, 0x65}; + +// Creates and returns a minimal SecurePaymentConfirmationRequest object with +// only required fields filled in to pass parsing. +// +// If include_payee_name is set to false, this function will not include the +// payeeName field which is not required by IDL (and thus not required for +// conversion to ScriptValue), but is required by the parsing code. +SecurePaymentConfirmationRequest* CreateSecurePaymentConfirmationRequest( + const V8TestingScope& scope, + const bool include_payee_name = true); + +HeapVector<Member<PaymentMethodData>> +BuildSecurePaymentConfirmationMethodDataForTest(const V8TestingScope& scope); + } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_PAYMENT_TEST_HELPER_H_
diff --git a/third_party/blink/renderer/modules/payments/secure_payment_confirmation_helper_test.cc b/third_party/blink/renderer/modules/payments/secure_payment_confirmation_helper_test.cc index a1751d9..0ab97451 100644 --- a/third_party/blink/renderer/modules/payments/secure_payment_confirmation_helper_test.cc +++ b/third_party/blink/renderer/modules/payments/secure_payment_confirmation_helper_test.cc
@@ -12,6 +12,7 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_union_arraybuffer_arraybufferview.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_payment_credential_instrument.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_secure_payment_confirmation_request.h" +#include "third_party/blink/renderer/modules/payments/payment_test_helper.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "testing/gtest/include/gtest/gtest.h" @@ -27,47 +28,6 @@ return vector; } -const uint8_t kCredentialId[] = {0x63, 0x72, 0x65, 0x64, 0x65, - 0x6E, 0x74, 0x69, 0x61, 0x6C}; -const uint8_t kChallenge[] = {0x63, 0x68, 0x61, 0x6C, 0x6C, - 0x65, 0x6E, 0x67, 0x65}; - -// Creates and returns a minimal SecurePaymentConfirmationRequest object with -// only required fields filled in to pass parsing. -// -// If include_payee_name is set to false, this function will not include the -// payeeName field which is not required by IDL (and thus not required for -// conversion to ScriptValue), but is required by the parsing code. -SecurePaymentConfirmationRequest* CreateSecurePaymentConfirmationRequest( - const V8TestingScope& scope, - const bool include_payee_name = true) { - SecurePaymentConfirmationRequest* request = - SecurePaymentConfirmationRequest::Create(scope.GetIsolate()); - - HeapVector<Member<V8UnionArrayBufferOrArrayBufferView>> credentialIds; - credentialIds.push_back( - MakeGarbageCollected<V8UnionArrayBufferOrArrayBufferView>( - DOMArrayBuffer::Create(kCredentialId, std::size(kCredentialId)))); - request->setCredentialIds(credentialIds); - - request->setChallenge( - MakeGarbageCollected<V8UnionArrayBufferOrArrayBufferView>( - DOMArrayBuffer::Create(kChallenge, std::size(kChallenge)))); - - PaymentCredentialInstrument* instrument = - PaymentCredentialInstrument::Create(scope.GetIsolate()); - instrument->setDisplayName("My Card"); - instrument->setIcon("https://bank.example/icon.png"); - request->setInstrument(instrument); - - request->setRpId("bank.example"); - - if (include_payee_name) { - request->setPayeeName("Merchant Shop"); - } - - return request; -} } // namespace // Test that parsing a valid SecurePaymentConfirmationRequest succeeds and @@ -87,9 +47,11 @@ ASSERT_EQ(parsed_request->credential_ids.size(), 1u); EXPECT_EQ(parsed_request->credential_ids[0], - CreateVector(kCredentialId, std::size(kCredentialId))); + CreateVector(kSecurePaymentConfirmationCredentialId, + std::size(kSecurePaymentConfirmationCredentialId))); EXPECT_EQ(parsed_request->challenge, - CreateVector(kChallenge, std::size(kChallenge))); + CreateVector(kSecurePaymentConfirmationChallenge, + std::size(kSecurePaymentConfirmationChallenge))); EXPECT_EQ(parsed_request->instrument->display_name, "My Card"); EXPECT_EQ(parsed_request->instrument->icon.GetString(), "https://bank.example/icon.png"); @@ -151,7 +113,9 @@ HeapVector<Member<V8UnionArrayBufferOrArrayBufferView>> credentialIds; credentialIds.push_back( MakeGarbageCollected<V8UnionArrayBufferOrArrayBufferView>( - DOMArrayBuffer::Create(kCredentialId, std::size(kCredentialId)))); + DOMArrayBuffer::Create( + kSecurePaymentConfirmationCredentialId, + std::size(kSecurePaymentConfirmationCredentialId)))); const size_t num_elements = 0; const size_t byte_length = 0; credentialIds.push_back(
diff --git a/third_party/blink/renderer/modules/shared_storage/private_aggregation.cc b/third_party/blink/renderer/modules/shared_storage/private_aggregation.cc index 8e31267..d7a1c4e 100644 --- a/third_party/blink/renderer/modules/shared_storage/private_aggregation.cc +++ b/third_party/blink/renderer/modules/shared_storage/private_aggregation.cc
@@ -15,7 +15,6 @@ #include "third_party/abseil-cpp/absl/numeric/int128.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/public/common/features.h" -#include "third_party/blink/public/mojom/private_aggregation/private_aggregation_host.mojom-blink.h" #include "third_party/blink/public/mojom/shared_storage/shared_storage_worklet_service.mojom-blink.h" #include "third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom-blink.h" #include "third_party/blink/public/platform/cross_variant_mojo_util.h" @@ -164,14 +163,13 @@ void PrivateAggregation::OnOperationStarted( int64_t operation_id, - mojo::PendingRemote<mojom::PrivateAggregationHost> + mojo::PendingRemote<mojom::blink::PrivateAggregationHost> private_aggregation_host) { CHECK(!operation_states_.Contains(operation_id)); auto map_it = operation_states_.insert( operation_id, MakeGarbageCollected<OperationState>(global_scope_)); map_it.stored_value->value->private_aggregation_host.Bind( - CrossVariantMojoRemote<mojom::blink::PrivateAggregationHostInterfaceBase>( - std::move(private_aggregation_host)), + std::move(private_aggregation_host), global_scope_->GetTaskRunner(blink::TaskType::kMiscPlatformAPI)); }
diff --git a/third_party/blink/renderer/modules/shared_storage/private_aggregation.h b/third_party/blink/renderer/modules/shared_storage/private_aggregation.h index 0d3d5933..28cecee1 100644 --- a/third_party/blink/renderer/modules/shared_storage/private_aggregation.h +++ b/third_party/blink/renderer/modules/shared_storage/private_aggregation.h
@@ -10,7 +10,6 @@ #include "mojo/public/cpp/bindings/pending_remote.h" #include "third_party/blink/public/mojom/private_aggregation/aggregatable_report.mojom-blink.h" #include "third_party/blink/public/mojom/private_aggregation/private_aggregation_host.mojom-blink.h" -#include "third_party/blink/public/mojom/private_aggregation/private_aggregation_host.mojom-forward.h" #include "third_party/blink/public/mojom/shared_storage/shared_storage_worklet_service.mojom-blink-forward.h" #include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" @@ -68,9 +67,10 @@ const PrivateAggregationDebugModeOptions*, ExceptionState&); - void OnOperationStarted(int64_t operation_id, - mojo::PendingRemote<mojom::PrivateAggregationHost> - private_aggregation_host); + void OnOperationStarted( + int64_t operation_id, + mojo::PendingRemote<mojom::blink::PrivateAggregationHost> + private_aggregation_host); void OnOperationFinished(int64_t operation_id); void OnWorkletDestroyed();
diff --git a/third_party/blink/renderer/modules/shared_storage/shared_storage.cc b/third_party/blink/renderer/modules/shared_storage/shared_storage.cc index 49a8a4c..d4be054 100644 --- a/third_party/blink/renderer/modules/shared_storage/shared_storage.cc +++ b/third_party/blink/renderer/modules/shared_storage/shared_storage.cc
@@ -584,7 +584,7 @@ return ScriptValue(); } - const absl::optional<String>& embedder_context = + const String& embedder_context = To<SharedStorageWorkletGlobalScope>(execution_context) ->embedder_context(); @@ -596,7 +596,7 @@ base::UmaHistogramBoolean("Storage.SharedStorage.Worklet.Context.IsDefined", true); - return ScriptValue::From(script_state, embedder_context.value()); + return ScriptValue::From(script_state, embedder_context); } // This C++ overload is called by JavaScript:
diff --git a/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_global_scope.cc b/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_global_scope.cc index aeda80d..3918ed9 100644 --- a/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_global_scope.cc +++ b/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_global_scope.cc
@@ -15,9 +15,12 @@ #include "gin/converter.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/remote.h" +#include "services/network/public/mojom/url_loader_factory.mojom-blink.h" +#include "services/network/public/mojom/url_loader_factory.mojom.h" #include "third_party/blink/public/common/features.h" #include "third_party/blink/public/common/shared_storage/module_script_downloader.h" #include "third_party/blink/public/common/shared_storage/shared_storage_utils.h" +#include "third_party/blink/public/mojom/private_aggregation/private_aggregation_host.mojom-blink.h" #include "third_party/blink/public/platform/cross_variant_mojo_util.h" #include "third_party/blink/renderer/bindings/core/v8/idl_types.h" #include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h" @@ -47,7 +50,7 @@ namespace { ScriptValue Deserialize(ScriptState* script_state, - const std::vector<uint8_t>& serialized_data) { + const Vector<uint8_t>& serialized_data) { v8::Isolate* isolate = script_state->GetIsolate(); v8::Local<v8::Context> context = script_state->GetContext(); @@ -68,8 +71,8 @@ // We try to use .stack property so that the error message contains a stack // trace, but otherwise fallback to .toString(). -std::string ExceptionToString(ScriptState* script_state, - v8::Local<v8::Value> exception) { +String ExceptionToString(ScriptState* script_state, + v8::Local<v8::Value> exception) { v8::Isolate* isolate = script_state->GetIsolate(); if (!exception.IsEmpty()) { @@ -78,7 +81,7 @@ v8::TryCatch::StackTrace(context, exception).FromMaybe(exception); v8::Local<v8::String> value_string; if (value->ToString(context).ToLocal(&value_string)) { - return gin::V8ToString(isolate, value_string); + return String(gin::V8ToString(isolate, value_string)); } } @@ -88,7 +91,7 @@ struct UnresolvedSelectURLRequest final : public GarbageCollected<UnresolvedSelectURLRequest> { UnresolvedSelectURLRequest(size_t urls_size, - blink::mojom::SharedStorageWorkletService:: + blink::mojom::blink::SharedStorageWorkletService:: RunURLSelectionOperationCallback callback) : urls_size(urls_size), callback(std::move(callback)) {} ~UnresolvedSelectURLRequest() = default; @@ -96,20 +99,22 @@ void Trace(Visitor* visitor) const {} size_t urls_size; - blink::mojom::SharedStorageWorkletService::RunURLSelectionOperationCallback - callback; + blink::mojom::blink::SharedStorageWorkletService:: + RunURLSelectionOperationCallback callback; }; struct UnresolvedRunRequest final : public GarbageCollected<UnresolvedRunRequest> { explicit UnresolvedRunRequest( - blink::mojom::SharedStorageWorkletService::RunOperationCallback callback) + blink::mojom::blink::SharedStorageWorkletService::RunOperationCallback + callback) : callback(std::move(callback)) {} ~UnresolvedRunRequest() = default; void Trace(Visitor* visitor) const {} - blink::mojom::SharedStorageWorkletService::RunOperationCallback callback; + blink::mojom::blink::SharedStorageWorkletService::RunOperationCallback + callback; }; class SelectURLResolutionSuccessCallback final @@ -148,7 +153,7 @@ } else { std::move(request_->callback) .Run(/*success=*/true, - /*error_message=*/{}, result_index); + /*error_message=*/g_empty_string, result_index); } } @@ -200,7 +205,7 @@ ScriptValue Call(ScriptState* script_state, ScriptValue value) override { std::move(request_->callback) .Run(/*success=*/true, - /*error_message=*/{}); + /*error_message=*/g_empty_string); return value; } @@ -250,7 +255,7 @@ SharedStorageWorkletGlobalScope::~SharedStorageWorkletGlobalScope() = default; void SharedStorageWorkletGlobalScope::BindSharedStorageWorkletService( - mojo::PendingReceiver<mojom::SharedStorageWorkletService> receiver, + mojo::PendingReceiver<mojom::blink::SharedStorageWorkletService> receiver, base::OnceClosure disconnect_handler) { receiver_.Bind(std::move(receiver), GetTaskRunner(blink::TaskType::kMiscPlatformAPI)); @@ -344,45 +349,43 @@ } void SharedStorageWorkletGlobalScope::Initialize( - mojo::PendingAssociatedRemote<mojom::SharedStorageWorkletServiceClient> - client, + mojo::PendingAssociatedRemote< + mojom::blink::SharedStorageWorkletServiceClient> client, bool private_aggregation_permissions_policy_allowed, - const absl::optional<std::u16string>& embedder_context) { - client_.Bind( - CrossVariantMojoAssociatedRemote< - mojom::blink::SharedStorageWorkletServiceClientInterfaceBase>( - std::move(client)), - GetTaskRunner(blink::TaskType::kMiscPlatformAPI)); + const String& embedder_context) { + client_.Bind(std::move(client), + GetTaskRunner(blink::TaskType::kMiscPlatformAPI)); + private_aggregation_permissions_policy_allowed_ = private_aggregation_permissions_policy_allowed; - if (embedder_context) { - embedder_context_ = WTF::String(embedder_context->c_str()); - } + embedder_context_ = embedder_context; } void SharedStorageWorkletGlobalScope::AddModule( - mojo::PendingRemote<network::mojom::URLLoaderFactory> + mojo::PendingRemote<network::mojom::blink::URLLoaderFactory> pending_url_loader_factory, - const GURL& script_source_url, + const KURL& script_source_url, AddModuleCallback callback) { mojo::Remote<network::mojom::URLLoaderFactory> url_loader_factory( - std::move(pending_url_loader_factory)); + CrossVariantMojoRemote<network::mojom::URLLoaderFactoryInterfaceBase>( + std::move(pending_url_loader_factory))); module_script_downloader_ = std::make_unique<ModuleScriptDownloader>( - url_loader_factory.get(), script_source_url, + url_loader_factory.get(), GURL(script_source_url), WTF::BindOnce(&SharedStorageWorkletGlobalScope::OnModuleScriptDownloaded, WrapWeakPersistent(this), script_source_url, std::move(callback))); } void SharedStorageWorkletGlobalScope::RunURLSelectionOperation( - const std::string& name, - const std::vector<GURL>& urls, - const std::vector<uint8_t>& serialized_data, - mojo::PendingRemote<mojom::PrivateAggregationHost> private_aggregation_host, + const String& name, + const Vector<KURL>& urls, + const Vector<uint8_t>& serialized_data, + mojo::PendingRemote<mojom::blink::PrivateAggregationHost> + private_aggregation_host, RunURLSelectionOperationCallback callback) { - std::string error_message; + String error_message; SharedStorageOperationDefinition* operation_definition = nullptr; if (!PerformCommonOperationChecks(name, error_message, operation_definition)) { @@ -394,9 +397,8 @@ base::OnceClosure operation_completion_cb = StartOperation(std::move(private_aggregation_host)); - mojom::SharedStorageWorkletService::RunURLSelectionOperationCallback - combined_operation_completion_cb = - std::move(callback).Then(std::move(operation_completion_cb)); + RunURLSelectionOperationCallback combined_operation_completion_cb = + std::move(callback).Then(std::move(operation_completion_cb)); DCHECK(operation_definition); @@ -412,15 +414,14 @@ V8RunFunctionForSharedStorageSelectURLOperation* registered_run_function = operation_definition->GetRunFunctionForSharedStorageSelectURLOperation(); - Vector<String> blink_urls; - base::ranges::transform( - urls, std::back_inserter(blink_urls), - [](const GURL& url) { return String(url.spec().c_str()); }); + Vector<String> urls_param; + base::ranges::transform(urls, std::back_inserter(urls_param), + [](const KURL& url) { return url.GetString(); }); - ScriptValue blink_data = Deserialize(script_state, serialized_data); + ScriptValue data_param = Deserialize(script_state, serialized_data); v8::Maybe<ScriptPromise> result = registered_run_function->Invoke( - instance.Get(isolate), blink_urls, blink_data); + instance.Get(isolate), urls_param, data_param); if (try_catch.HasCaught()) { v8::Local<v8::Value> exception = try_catch.Exception(); @@ -453,11 +454,12 @@ } void SharedStorageWorkletGlobalScope::RunOperation( - const std::string& name, - const std::vector<uint8_t>& serialized_data, - mojo::PendingRemote<mojom::PrivateAggregationHost> private_aggregation_host, + const String& name, + const Vector<uint8_t>& serialized_data, + mojo::PendingRemote<mojom::blink::PrivateAggregationHost> + private_aggregation_host, RunOperationCallback callback) { - std::string error_message; + String error_message; SharedStorageOperationDefinition* operation_definition = nullptr; if (!PerformCommonOperationChecks(name, error_message, operation_definition)) { @@ -468,7 +470,7 @@ base::OnceClosure operation_completion_cb = StartOperation(std::move(private_aggregation_host)); - mojom::SharedStorageWorkletService::RunOperationCallback + mojom::blink::SharedStorageWorkletService::RunOperationCallback combined_operation_completion_cb = std::move(callback).Then(std::move(operation_completion_cb)); @@ -486,10 +488,10 @@ V8RunFunctionForSharedStorageRunOperation* registered_run_function = operation_definition->GetRunFunctionForSharedStorageRunOperation(); - ScriptValue blink_data = Deserialize(script_state, serialized_data); + ScriptValue data_param = Deserialize(script_state, serialized_data); v8::Maybe<ScriptPromise> result = - registered_run_function->Invoke(instance.Get(isolate), blink_data); + registered_run_function->Invoke(instance.Get(isolate), data_param); if (try_catch.HasCaught()) { v8::Local<v8::Value> exception = try_catch.Exception(); @@ -583,20 +585,20 @@ } void SharedStorageWorkletGlobalScope::OnModuleScriptDownloaded( - const GURL& script_source_url, - mojom::SharedStorageWorkletService::AddModuleCallback callback, + const KURL& script_source_url, + mojom::blink::SharedStorageWorkletService::AddModuleCallback callback, std::unique_ptr<std::string> response_body, std::string error_message) { module_script_downloader_.reset(); - mojom::SharedStorageWorkletService::AddModuleCallback + mojom::blink::SharedStorageWorkletService::AddModuleCallback add_module_finished_callback = std::move(callback).Then(WTF::BindOnce( &SharedStorageWorkletGlobalScope::RecordAddModuleFinished, WrapPersistent(this))); if (!response_body) { std::move(add_module_finished_callback) - .Run(false, std::string(error_message)); + .Run(false, String(error_message.c_str())); return; } @@ -608,10 +610,10 @@ // TODO(crbug.com/1419253): Using a classic script with the custom script // loader is tentative. Eventually, this should migrate to the blink-worklet's // script loading infrastructure. - ClassicScript* worker_script = ClassicScript::Create( - String(*response_body), - /*source_url=*/KURL(String(script_source_url.spec().c_str())), - /*base_url=*/KURL(), ScriptFetchOptions()); + ClassicScript* worker_script = + ClassicScript::Create(String(*response_body), + /*source_url=*/script_source_url, + /*base_url=*/KURL(), ScriptFetchOptions()); v8::HandleScope handle_scope(script_state->GetIsolate()); ScriptEvaluationResult result = @@ -632,7 +634,8 @@ return; } - std::move(add_module_finished_callback).Run(true, /*error_message=*/{}); + std::move(add_module_finished_callback) + .Run(true, /*error_message=*/g_empty_string); } void SharedStorageWorkletGlobalScope::RecordAddModuleFinished() { @@ -640,8 +643,8 @@ } bool SharedStorageWorkletGlobalScope::PerformCommonOperationChecks( - const std::string& operation_name, - std::string& error_message, + const String& operation_name, + String& error_message, SharedStorageOperationDefinition*& operation_definition) { DCHECK(error_message.empty()); DCHECK_EQ(operation_definition, nullptr); @@ -654,7 +657,7 @@ return false; } - auto it = operation_definition_map_.find(String(operation_name.c_str())); + auto it = operation_definition_map_.find(operation_name); if (it == operation_definition_map_.end()) { error_message = "Cannot find operation name."; return false; @@ -677,7 +680,7 @@ } base::OnceClosure SharedStorageWorkletGlobalScope::StartOperation( - mojo::PendingRemote<mojom::PrivateAggregationHost> + mojo::PendingRemote<mojom::blink::PrivateAggregationHost> private_aggregation_host) { CHECK(add_module_finished_); CHECK_EQ(!!private_aggregation_host,
diff --git a/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_global_scope.h b/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_global_scope.h index 40d6d4e..23e3f6d 100644 --- a/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_global_scope.h +++ b/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_global_scope.h
@@ -15,12 +15,11 @@ #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h" -#include "services/network/public/mojom/url_loader_factory.mojom.h" +#include "services/network/public/mojom/url_loader_factory.mojom-blink-forward.h" #include "third_party/abseil-cpp/absl/numeric/int128.h" #include "third_party/blink/public/common/tokens/tokens.h" -#include "third_party/blink/public/mojom/private_aggregation/private_aggregation_host.mojom.h" +#include "third_party/blink/public/mojom/private_aggregation/private_aggregation_host.mojom-blink-forward.h" #include "third_party/blink/public/mojom/shared_storage/shared_storage_worklet_service.mojom-blink.h" -#include "third_party/blink/public/mojom/shared_storage/shared_storage_worklet_service.mojom.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/workers/worklet_global_scope.h" #include "third_party/blink/renderer/modules/modules_export.h" @@ -44,12 +43,12 @@ class PrivateAggregation; class Crypto; -// mojom::SharedStorageWorkletService implementation. Responsible for +// mojom::blink::SharedStorageWorkletService implementation. Responsible for // handling worklet operations. This object lives on the worklet thread. class MODULES_EXPORT SharedStorageWorkletGlobalScope final : public WorkletGlobalScope, public Supplementable<SharedStorageWorkletGlobalScope>, - public mojom::SharedStorageWorkletService { + public mojom::blink::SharedStorageWorkletService { DEFINE_WRAPPERTYPEINFO(); public: @@ -59,7 +58,7 @@ ~SharedStorageWorkletGlobalScope() override; void BindSharedStorageWorkletService( - mojo::PendingReceiver<mojom::SharedStorageWorkletService> receiver, + mojo::PendingReceiver<mojom::blink::SharedStorageWorkletService> receiver, base::OnceClosure disconnect_handler); // SharedStorageWorkletGlobalScope IDL @@ -99,26 +98,25 @@ void Trace(Visitor*) const override; - // mojom::SharedStorageWorkletService implementation: - void Initialize( - mojo::PendingAssociatedRemote<mojom::SharedStorageWorkletServiceClient> - client, - bool private_aggregation_permissions_policy_allowed, - const absl::optional<std::u16string>& embedder_context) override; - void AddModule(mojo::PendingRemote<network::mojom::URLLoaderFactory> + // mojom::blink::SharedStorageWorkletService implementation: + void Initialize(mojo::PendingAssociatedRemote< + mojom::blink::SharedStorageWorkletServiceClient> client, + bool private_aggregation_permissions_policy_allowed, + const String& embedder_context) override; + void AddModule(mojo::PendingRemote<network::mojom::blink::URLLoaderFactory> pending_url_loader_factory, - const GURL& script_source_url, + const KURL& script_source_url, AddModuleCallback callback) override; void RunURLSelectionOperation( - const std::string& name, - const std::vector<GURL>& urls, - const std::vector<uint8_t>& serialized_data, - mojo::PendingRemote<mojom::PrivateAggregationHost> + const String& name, + const Vector<KURL>& urls, + const Vector<uint8_t>& serialized_data, + mojo::PendingRemote<mojom::blink::PrivateAggregationHost> private_aggregation_host, RunURLSelectionOperationCallback callback) override; - void RunOperation(const std::string& name, - const std::vector<uint8_t>& serialized_data, - mojo::PendingRemote<mojom::PrivateAggregationHost> + void RunOperation(const String& name, + const Vector<uint8_t>& serialized_data, + mojo::PendingRemote<mojom::blink::PrivateAggregationHost> private_aggregation_host, RunOperationCallback callback) override; @@ -135,9 +133,7 @@ return client_.get(); } - const absl::optional<String>& embedder_context() const { - return embedder_context_; - } + const String& embedder_context() const { return embedder_context_; } bool private_aggregation_permissions_policy_allowed() const { return private_aggregation_permissions_policy_allowed_; @@ -145,8 +141,8 @@ private: void OnModuleScriptDownloaded( - const GURL& script_source_url, - mojom::SharedStorageWorkletService::AddModuleCallback callback, + const KURL& script_source_url, + mojom::blink::SharedStorageWorkletService::AddModuleCallback callback, std::unique_ptr<std::string> response_body, std::string error_message); @@ -156,8 +152,8 @@ // `RunOperation`. On success, sets `operation_definition` to the registered // operation. On failure, sets `error_message` to the error to be returned. bool PerformCommonOperationChecks( - const std::string& operation_name, - std::string& error_message, + const String& operation_name, + String& error_message, SharedStorageOperationDefinition*& operation_definition); network::mojom::RequestDestination GetDestination() const override { @@ -175,7 +171,7 @@ // particular operation invocation later, even after asynchronous operations. // Returns a closure that should be run when the operation finishes. base::OnceClosure StartOperation( - mojo::PendingRemote<mojom::PrivateAggregationHost> + mojo::PendingRemote<mojom::blink::PrivateAggregationHost> private_aggregation_host); // Notifies the `private_aggregation_` that the operation with the given ID @@ -195,7 +191,7 @@ // ensure that the worklet thread object and this service are not leaked, // `receiver_` must be cut off from the remote side when the worklet is // supposed to be destroyed. - HeapMojoReceiver<mojom::SharedStorageWorkletService, + HeapMojoReceiver<mojom::blink::SharedStorageWorkletService, SharedStorageWorkletGlobalScope> receiver_{this, this}; @@ -203,7 +199,7 @@ // `embedder_context_` represents any contextual information written to the // frame's `blink::FencedFrameConfig` by the embedder before navigation to the // config. `embedder_context_` is passed to the worklet upon initialization. - absl::optional<String> embedder_context_; + String embedder_context_; // The per-global-scope shared storage object. Created on the first access of // `sharedStorage`.
diff --git a/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_messaging_proxy.cc b/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_messaging_proxy.cc index 103516f..d13971a 100644 --- a/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_messaging_proxy.cc +++ b/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_messaging_proxy.cc
@@ -8,7 +8,7 @@ #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/remote.h" -#include "third_party/blink/public/mojom/shared_storage/shared_storage_worklet_service.mojom.h" +#include "third_party/blink/public/mojom/shared_storage/shared_storage_worklet_service.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h" #include "third_party/blink/renderer/core/workers/threaded_worklet_object_proxy.h" #include "third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_thread.h" @@ -22,7 +22,7 @@ SharedStorageWorkletMessagingProxy::SharedStorageWorkletMessagingProxy( scoped_refptr<base::SingleThreadTaskRunner> main_thread_runner, - mojo::PendingReceiver<mojom::SharedStorageWorkletService> receiver, + mojo::PendingReceiver<mojom::blink::SharedStorageWorkletService> receiver, base::OnceClosure worklet_terminated_callback) : ThreadedWorkletMessagingProxy( /*execution_context=*/nullptr, @@ -45,7 +45,8 @@ void SharedStorageWorkletMessagingProxy:: InitializeSharedStorageWorkletServiceOnWorkletThread( WorkerThread* worker_thread, - mojo::PendingReceiver<mojom::SharedStorageWorkletService> receiver) { + mojo::PendingReceiver<mojom::blink::SharedStorageWorkletService> + receiver) { DCHECK(worker_thread->IsCurrentThread()); auto disconnect_handler = WTF::BindOnce(
diff --git a/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_messaging_proxy.h b/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_messaging_proxy.h index a0e4b060..d97d790 100644 --- a/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_messaging_proxy.h +++ b/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_messaging_proxy.h
@@ -8,7 +8,7 @@ #include <memory> #include "third_party/blink/public/common/browser_interface_broker_proxy.h" -#include "third_party/blink/public/mojom/shared_storage/shared_storage_worklet_service.mojom-forward.h" +#include "third_party/blink/public/mojom/shared_storage/shared_storage_worklet_service.mojom-blink-forward.h" #include "third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.h" #include "third_party/blink/renderer/modules/modules_export.h" @@ -30,7 +30,7 @@ public: SharedStorageWorkletMessagingProxy( scoped_refptr<base::SingleThreadTaskRunner> main_thread_runner, - mojo::PendingReceiver<mojom::SharedStorageWorkletService> receiver, + mojo::PendingReceiver<mojom::blink::SharedStorageWorkletService> receiver, base::OnceClosure worklet_terminated_callback); void WorkerThreadTerminated() override; @@ -42,7 +42,8 @@ void InitializeSharedStorageWorkletServiceOnWorkletThread( WorkerThread* worker_thread, - mojo::PendingReceiver<mojom::SharedStorageWorkletService> receiver); + mojo::PendingReceiver<mojom::blink::SharedStorageWorkletService> + receiver); void OnSharedStorageWorkletServiceDisconnectedOnWorkletThread();
diff --git a/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_thread.cc b/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_thread.cc index c5650995..5a1fcfa 100644 --- a/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_thread.cc +++ b/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_thread.cc
@@ -4,7 +4,7 @@ #include "third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_thread.h" -#include "third_party/blink/public/mojom/shared_storage/shared_storage_worklet_service.mojom.h" +#include "third_party/blink/public/mojom/shared_storage/shared_storage_worklet_service.mojom-blink.h" #include "third_party/blink/renderer/core/workers/global_scope_creation_params.h" #include "third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_global_scope.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" @@ -60,7 +60,7 @@ } void SharedStorageWorkletThread::InitializeSharedStorageWorkletService( - mojo::PendingReceiver<mojom::SharedStorageWorkletService> receiver, + mojo::PendingReceiver<mojom::blink::SharedStorageWorkletService> receiver, base::OnceClosure disconnect_handler) { DCHECK(!IsMainThread()); SharedStorageWorkletGlobalScope* global_scope =
diff --git a/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_thread.h b/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_thread.h index 4f84bfd..48530b5 100644 --- a/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_thread.h +++ b/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_thread.h
@@ -6,7 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_SHARED_STORAGE_SHARED_STORAGE_WORKLET_THREAD_H_ #include "mojo/public/cpp/bindings/pending_remote.h" -#include "third_party/blink/public/mojom/shared_storage/shared_storage_worklet_service.mojom-forward.h" +#include "third_party/blink/public/mojom/shared_storage/shared_storage_worklet_service.mojom-blink-forward.h" #include "third_party/blink/renderer/core/workers/worker_thread.h" #include "third_party/blink/renderer/core/workers/worklet_thread_holder.h" #include "third_party/blink/renderer/modules/modules_export.h" @@ -34,7 +34,7 @@ static void ClearSharedBackingThread(); void InitializeSharedStorageWorkletService( - mojo::PendingReceiver<mojom::SharedStorageWorkletService> receiver, + mojo::PendingReceiver<mojom::blink::SharedStorageWorkletService> receiver, base::OnceClosure disconnect_handler); private:
diff --git a/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_unittest.cc b/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_unittest.cc index fe901db..e8dd60b 100644 --- a/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_unittest.cc +++ b/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_unittest.cc
@@ -419,7 +419,10 @@ shared_storage_worklet_service_.BindNewPipeAndPassReceiver(); messaging_proxy_ = MakeGarbageCollected<SharedStorageWorkletMessagingProxy>( - base::SingleThreadTaskRunner::GetCurrentDefault(), std::move(receiver), + base::SingleThreadTaskRunner::GetCurrentDefault(), + CrossVariantMojoReceiver< + mojom::blink::SharedStorageWorkletServiceInterfaceBase>( + std::move(receiver)), worklet_terminated_future_.GetCallback()); mojo::PendingAssociatedRemote<mojom::SharedStorageWorkletServiceClient>
diff --git a/third_party/blink/renderer/modules/webaudio/delay_processor.cc b/third_party/blink/renderer/modules/webaudio/delay_processor.cc index 89e3cdb..28427ea 100644 --- a/third_party/blink/renderer/modules/webaudio/delay_processor.cc +++ b/third_party/blink/renderer/modules/webaudio/delay_processor.cc
@@ -34,40 +34,30 @@ namespace { -class DelayDSPKernel final : public AudioDelayDSPKernel { +class DelayDSPKernel final : public AudioDSPKernel { public: explicit DelayDSPKernel(DelayProcessor* processor) - : AudioDelayDSPKernel(processor, processor->RenderQuantumFrames()) { + : AudioDSPKernel(processor), + delay_(processor->MaxDelayTime(), + processor->SampleRate(), + processor->RenderQuantumFrames()) { DCHECK(processor); DCHECK_GT(processor->SampleRate(), 0); - - max_delay_time_ = processor->MaxDelayTime(); - DCHECK_GE(max_delay_time_, 0); - DCHECK(!std::isnan(max_delay_time_)); - - buffer_.Allocate(BufferLengthForDelay(max_delay_time_, - processor->SampleRate(), - processor->RenderQuantumFrames())); - buffer_.Zero(); } - protected: - bool HasSampleAccurateValues() override { - return GetDelayProcessor()->DelayTime().HasSampleAccurateValues(); - } - - void CalculateSampleAccurateValues(float* delay_times, - uint32_t frames_to_process) override { - GetDelayProcessor()->DelayTime().CalculateSampleAccurateValues( - delay_times, frames_to_process); - } - - double DelayTime(float sample_rate) override { - return GetDelayProcessor()->DelayTime().FinalValue(); - } - - bool IsAudioRate() override { - return GetDelayProcessor()->DelayTime().IsAudioRate(); + // Process the delay. Basically dispatches to either ProcessKRate or + // ProcessARate. + void Process(const float* source, + float* destination, + uint32_t frames_to_process) override { + if (HasSampleAccurateValues() && IsAudioRate()) { + GetDelayProcessor()->DelayTime().CalculateSampleAccurateValues( + delay_.DelayTimes(), frames_to_process); + delay_.ProcessARate(source, destination, frames_to_process); + } else { + delay_.SetDelayTime(GetDelayProcessor()->DelayTime().FinalValue()); + delay_.ProcessKRate(source, destination, frames_to_process); + } } void ProcessOnlyAudioParams(uint32_t frames_to_process) override { @@ -79,10 +69,37 @@ values, frames_to_process); } + void Reset() override { delay_.Reset(); } + + double TailTime() const override { + // Account for worst case delay. + // Don't try to track actual delay time which can change dynamically. + return delay_.MaxDelayTime(); + } + + double LatencyTime() const override { return 0; } + + bool RequiresTailProcessing() const override { + // Always return true even if the tail time and latency might both + // be zero. This is for simplicity; most interesting delay nodes + // have non-zero delay times anyway. And it's ok to return true. It + // just means the node lives a little longer than strictly + // necessary. + return true; + } + private: + bool HasSampleAccurateValues() { + return GetDelayProcessor()->DelayTime().HasSampleAccurateValues(); + } + + bool IsAudioRate() { return GetDelayProcessor()->DelayTime().IsAudioRate(); } + DelayProcessor* GetDelayProcessor() { return static_cast<DelayProcessor*>(Processor()); } + + AudioDelayDSPKernel delay_; }; } // namespace
diff --git a/third_party/blink/renderer/platform/audio/audio_delay_dsp_kernel.cc b/third_party/blink/renderer/platform/audio/audio_delay_dsp_kernel.cc index c1da61832..47328c7 100644 --- a/third_party/blink/renderer/platform/audio/audio_delay_dsp_kernel.cc +++ b/third_party/blink/renderer/platform/audio/audio_delay_dsp_kernel.cc
@@ -35,25 +35,43 @@ namespace blink { -// Delay nodes have a max allowed delay time of this many seconds. -const float kMaxDelayTimeSeconds = 30; +namespace { -AudioDelayDSPKernel::AudioDelayDSPKernel(AudioDSPKernelProcessor* processor, - size_t processing_size_in_frames) - : AudioDSPKernel(processor), - write_index_(0), - delay_times_(processing_size_in_frames), - temp_buffer_(processing_size_in_frames) {} +void CopyToCircularBuffer(float* buffer, + int write_index, + int buffer_length, + const float* source, + uint32_t frames_to_process) { + // The algorithm below depends on this being true because we don't expect to + // have to fill the entire buffer more than once. + DCHECK_GE(static_cast<uint32_t>(buffer_length), frames_to_process); + + // Copy `frames_to_process` values from `source` to the circular buffer that + // starts at `buffer` of length `buffer_length`. The copy starts at index + // `write_index` into the buffer. + float* write_pointer = &buffer[write_index]; + int remainder = buffer_length - write_index; + + // Copy the sames over, carefully handling the case where we need to wrap + // around to the beginning of the buffer. + memcpy(write_pointer, source, + sizeof(*write_pointer) * + std::min(static_cast<int>(frames_to_process), remainder)); + memcpy(buffer, source + remainder, + sizeof(*write_pointer) * + std::max(0, static_cast<int>(frames_to_process) - remainder)); +} + +} // namespace AudioDelayDSPKernel::AudioDelayDSPKernel(double max_delay_time, float sample_rate, unsigned render_quantum_frames) - : AudioDSPKernel(sample_rate, render_quantum_frames), - max_delay_time_(max_delay_time), - write_index_(0), - temp_buffer_(render_quantum_frames) { + : max_delay_time_(max_delay_time), + delay_times_(render_quantum_frames), + temp_buffer_(render_quantum_frames), + sample_rate_(sample_rate) { DCHECK_GT(max_delay_time_, 0.0); - DCHECK_LE(max_delay_time_, kMaxDelayTimeSeconds); DCHECK(std::isfinite(max_delay_time_)); size_t buffer_length = @@ -69,7 +87,7 @@ double sample_rate, unsigned render_quantum_frames) const { // Compute the length of the buffer needed to handle a max delay of - // |maxDelayTime|. Add an additional render quantum frame size so we can + // `maxDelayTime`. Add an additional render quantum frame size so we can // vectorize the delay processing. The extra space is needed so that writes // to the buffer won't overlap reads from the buffer. return render_quantum_frames + @@ -77,47 +95,10 @@ audio_utilities::kRoundUp); } -bool AudioDelayDSPKernel::HasSampleAccurateValues() { - return false; -} - -void AudioDelayDSPKernel::CalculateSampleAccurateValues(float*, uint32_t) { - NOTREACHED(); -} - -bool AudioDelayDSPKernel::IsAudioRate() { - return true; -} - double AudioDelayDSPKernel::DelayTime(float sample_rate) { return desired_delay_frames_ / sample_rate; } -static void CopyToCircularBuffer(float* buffer, - int write_index, - int buffer_length, - const float* source, - uint32_t frames_to_process) { - // The algorithm below depends on this being true because we don't expect to - // have to fill the entire buffer more than once. - DCHECK_GE(static_cast<uint32_t>(buffer_length), frames_to_process); - - // Copy |frames_to_process| values from |source| to the circular buffer that - // starts at |buffer| of length |buffer_length|. The copy starts at index - // |write_index| into the buffer. - float* write_pointer = &buffer[write_index]; - int remainder = buffer_length - write_index; - - // Copy the sames over, carefully handling the case where we need to wrap - // around to the beginning of the buffer. - memcpy(write_pointer, source, - sizeof(*write_pointer) * - std::min(static_cast<int>(frames_to_process), remainder)); - memcpy(buffer, source + remainder, - sizeof(*write_pointer) * - std::max(0, static_cast<int>(frames_to_process) - remainder)); -} - #if !(defined(ARCH_CPU_X86_FAMILY) || defined(CPU_ARM_NEON)) // Default scalar versions if simd/neon are not available. std::tuple<unsigned, int> AudioDelayDSPKernel::ProcessARateVector( @@ -150,7 +131,7 @@ DCHECK_GE(write_index_, 0); DCHECK_LT(write_index_, buffer_length); - float sample_rate = SampleRate(); + float sample_rate = sample_rate_; const float* delay_times = delay_times_.Data(); for (unsigned i = start; i < frames_to_process; ++i) { @@ -202,7 +183,6 @@ DCHECK_LT(write_index_, buffer_length); float* delay_times = delay_times_.Data(); - CalculateSampleAccurateValues(delay_times, frames_to_process); // Any NaN's get converted to max time // TODO(crbug.com/1013345): Don't need this if that bug is fixed @@ -234,18 +214,11 @@ DCHECK_GE(write_index_, 0); DCHECK_LT(write_index_, buffer_length); - float sample_rate = SampleRate(); + float sample_rate = sample_rate_; double max_time = MaxDelayTime(); // This is basically the same as above, but optimized for the case where the // delay time is constant for the current render. - // - // TODO(crbug.com/1012198): There are still some further optimizations that - // could be done. |interpolation_factor| could be a float to eliminate - // several conversions between floats and doubles. It might be possible to - // get rid of the wrapping if the buffer were longer. This may also allow - // |write_index_| to be different from |read_index1| or |read_index2| which - // simplifies the loop a bit. double delay_time = DelayTime(sample_rate); // Make sure the delay time is in a valid range. @@ -258,8 +231,8 @@ read_position -= buffer_length; } - // Linearly interpolate in-between delay times. |read_index1| and - // |read_index2| are the indices of the frames to be used for + // Linearly interpolate in-between delay times. `read_index1` and + // `read_index2` are the indices of the frames to be used for // interpolation. int read_index1 = static_cast<int>(read_position); float interpolation_factor = read_position - read_index1; @@ -325,37 +298,8 @@ } } -void AudioDelayDSPKernel::Process(const float* source, - float* destination, - uint32_t frames_to_process) { - if (HasSampleAccurateValues() && IsAudioRate()) { - ProcessARate(source, destination, frames_to_process); - } else { - ProcessKRate(source, destination, frames_to_process); - } -} - void AudioDelayDSPKernel::Reset() { buffer_.Zero(); } -bool AudioDelayDSPKernel::RequiresTailProcessing() const { - // Always return true even if the tail time and latency might both - // be zero. This is for simplicity; most interesting delay nodes - // have non-zero delay times anyway. And it's ok to return true. It - // just means the node lives a little longer than strictly - // necessary. - return true; -} - -double AudioDelayDSPKernel::TailTime() const { - // Account for worst case delay. - // Don't try to track actual delay time which can change dynamically. - return max_delay_time_; -} - -double AudioDelayDSPKernel::LatencyTime() const { - return 0; -} - } // namespace blink
diff --git a/third_party/blink/renderer/platform/audio/audio_delay_dsp_kernel.h b/third_party/blink/renderer/platform/audio/audio_delay_dsp_kernel.h index d1961d79..5fd3a24 100644 --- a/third_party/blink/renderer/platform/audio/audio_delay_dsp_kernel.h +++ b/third_party/blink/renderer/platform/audio/audio_delay_dsp_kernel.h
@@ -32,27 +32,42 @@ namespace blink { -class PLATFORM_EXPORT AudioDelayDSPKernel : public AudioDSPKernel { +class PLATFORM_EXPORT AudioDelayDSPKernel { public: AudioDelayDSPKernel(double max_delay_time, float sample_rate, unsigned render_quantum_frames); - // Process the delay. Basically dispatches to either ProcessKRate or - // ProcessARate. - void Process(const float* source, - float* destination, - uint32_t frames_to_process) override; - - // Handles k-rate processing + // Handles k-rate processing. Call `SetDelayFrames()` or `SetDelayTime()` to + // set the delay before calling this function. void ProcessKRate(const float* source, float* destination, uint32_t frames_to_process); - // Handles a-rate processing + // Handles a-rate processing. Fill the return value of `DelayTimes()` with + // the delay value for each frame before calling this function. void ProcessARate(const float* source, float* destination, uint32_t frames_to_process); + + void Reset(); + + float MaxDelayTime() const { return max_delay_time_; } + + // Set the delay in frames for `ProcessKRate()` + void SetDelayFrames(double number_of_frames) { + desired_delay_frames_ = number_of_frames; + } + + // Set the delay in seconds for `ProcessKRate()` + void SetDelayTime(double seconds) { + desired_delay_frames_ = seconds * sample_rate_; + } + + // Fill the return value of this before calling `ProcessARate()` + float* DelayTimes() { return delay_times_.Data(); } + + protected: // Main processing loop for ProcessARate using scalar operations. Returns the // new write_index. int ProcessARateScalar(unsigned start, @@ -66,32 +81,19 @@ float* destination, uint32_t frames_to_process) const; - // Handle an NaN values in |delay_times|. Replace NaN with |max_time|. + // Handle NaN values in `delay_times`. Replace NaN with `max_time`. void HandleNaN(float* delay_times, uint32_t frames_to_process, float max_time); - void Reset() override; - - float MaxDelayTime() const { return max_delay_time_; } - - void SetDelayFrames(double number_of_frames) { - desired_delay_frames_ = number_of_frames; - } - - double TailTime() const override; - double LatencyTime() const override; - bool RequiresTailProcessing() const override; - - protected: AudioDelayDSPKernel(AudioDSPKernelProcessor*, size_t processing_size_in_frames); - virtual bool HasSampleAccurateValues(); - virtual void CalculateSampleAccurateValues(float* delay_times, - uint32_t frames_to_process); - virtual double DelayTime(float sample_rate); - virtual bool IsAudioRate(); + double DelayTime(float sample_rate); + + size_t BufferLengthForDelay(double delay_time, + double sample_rate, + unsigned render_quantum_frames) const; AudioFloatArray buffer_; @@ -99,8 +101,8 @@ // floats, so make this a float to keep everything consistent. float max_delay_time_; - int write_index_; - double desired_delay_frames_; + int write_index_ = 0; + double desired_delay_frames_ = 0; AudioFloatArray delay_times_; @@ -108,9 +110,7 @@ // needed. AudioFloatArray temp_buffer_; - size_t BufferLengthForDelay(double delay_time, - double sample_rate, - unsigned render_quantum_frames) const; + float sample_rate_; }; } // namespace blink
diff --git a/third_party/blink/renderer/platform/audio/cpu/arm/audio_delay_dsp_kernel_neon.cc b/third_party/blink/renderer/platform/audio/cpu/arm/audio_delay_dsp_kernel_neon.cc index e5b0a1a..34c544d 100644 --- a/third_party/blink/renderer/platform/audio/cpu/arm/audio_delay_dsp_kernel_neon.cc +++ b/third_party/blink/renderer/platform/audio/cpu/arm/audio_delay_dsp_kernel_neon.cc
@@ -55,7 +55,7 @@ const int buffer_length = buffer_.size(); const float* buffer = buffer_.Data(); - const float sample_rate = SampleRate(); + const float sample_rate = sample_rate_; const float* delay_times = delay_times_.Data(); int w_index = write_index_;
diff --git a/third_party/blink/renderer/platform/audio/cpu/x86/audio_delay_dsp_kernel_sse2.cc b/third_party/blink/renderer/platform/audio/cpu/x86/audio_delay_dsp_kernel_sse2.cc index 2bb714c..a8ca505c 100644 --- a/third_party/blink/renderer/platform/audio/cpu/x86/audio_delay_dsp_kernel_sse2.cc +++ b/third_party/blink/renderer/platform/audio/cpu/x86/audio_delay_dsp_kernel_sse2.cc
@@ -54,7 +54,7 @@ const int buffer_length = buffer_.size(); const float* buffer = buffer_.Data(); - const float sample_rate = SampleRate(); + const float sample_rate = sample_rate_; const float* delay_times = delay_times_.Data(); int w_index = write_index_;
diff --git a/third_party/blink/renderer/platform/audio/hrtf_panner.cc b/third_party/blink/renderer/platform/audio/hrtf_panner.cc index 363fcdd0..3402d14 100644 --- a/third_party/blink/renderer/platform/audio/hrtf_panner.cc +++ b/third_party/blink/renderer/platform/audio/hrtf_panner.cc
@@ -274,10 +274,10 @@ // First run through delay lines for inter-aural time difference. delay_line_l_.SetDelayFrames(frame_delay_l); delay_line_r_.SetDelayFrames(frame_delay_r); - delay_line_l_.Process(segment_source_l, segment_destination_l, - kFramesPerSegment); - delay_line_r_.Process(segment_source_r, segment_destination_r, - kFramesPerSegment); + delay_line_l_.ProcessKRate(segment_source_l, segment_destination_l, + kFramesPerSegment); + delay_line_r_.ProcessKRate(segment_source_r, segment_destination_r, + kFramesPerSegment); const bool needs_crossfading = crossfade_incr_;
diff --git a/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.cc b/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.cc index 49850c20..e48ef43 100644 --- a/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.cc +++ b/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.cc
@@ -25,6 +25,8 @@ #include "third_party/blink/renderer/platform/graphics/mailbox_texture_backing.h" #include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h" #include "third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" +#include "third_party/blink/renderer/platform/wtf/functional.h" #include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/gpu/GrDirectContext.h" #include "third_party/skia/include/gpu/ganesh/SkImageGanesh.h" @@ -69,6 +71,56 @@ std::move(context_task_runner), std::move(release_callback))); } +// static +scoped_refptr<AcceleratedStaticBitmapImage> +AcceleratedStaticBitmapImage::CreateFromExternalMailbox( + const gpu::MailboxHolder& mailbox_holder, + uint32_t usage, + const SkImageInfo& sk_image_info, + bool is_origin_top_left, + bool supports_display_compositing, + bool is_overlay_candidate, + base::OnceCallback<void(const gpu::SyncToken&)> external_callback) { + auto shared_gpu_context = blink::SharedGpuContext::ContextProviderWrapper(); + if (!shared_gpu_context) { + return nullptr; + } + auto* sii = shared_gpu_context->ContextProvider()->SharedImageInterface(); + if (!sii) { + return nullptr; + } + sii->AddReferenceToSharedImage(mailbox_holder.sync_token, + mailbox_holder.mailbox, usage); + auto release_token = sii->GenVerifiedSyncToken(); + // No need to keep the original image after the new reference has been added. + // Need to update the sync token, however. + std::move(external_callback).Run(release_token); + + auto release_callback = WTF::BindOnce( + [](base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider, + const gpu::Mailbox& mailbox, const gpu::SyncToken& sync_token, + bool is_lost) { + if (is_lost || !context_provider) { + return; + } + auto* sii = context_provider->ContextProvider()->SharedImageInterface(); + if (!sii) { + return; + } + sii->DestroySharedImage(sync_token, mailbox); + }, + shared_gpu_context, mailbox_holder.mailbox); + + return base::AdoptRef(new AcceleratedStaticBitmapImage( + mailbox_holder.mailbox, release_token, 0u, sk_image_info, + mailbox_holder.texture_target, is_origin_top_left, + supports_display_compositing, is_overlay_candidate, + ImageOrientationEnum::kDefault, shared_gpu_context, + base::PlatformThreadRef(), + ThreadScheduler::Current()->CleanupTaskRunner(), + std::move(release_callback))); +} + AcceleratedStaticBitmapImage::AcceleratedStaticBitmapImage( const gpu::Mailbox& mailbox, const gpu::SyncToken& sync_token, @@ -108,7 +160,7 @@ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); } -SkImageInfo AcceleratedStaticBitmapImage::GetSkImageInfoInternal() const { +SkImageInfo AcceleratedStaticBitmapImage::GetSkImageInfo() const { return sk_image_info_; } @@ -438,4 +490,11 @@ orientation_); } +uint32_t AcceleratedStaticBitmapImage::GetUsage() const { + return ContextProviderWrapper() + ->ContextProvider() + ->SharedImageInterface() + ->UsageForMailbox(mailbox_); +} + } // namespace blink
diff --git a/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h b/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h index bee0cfec..674932c 100644 --- a/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h +++ b/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h
@@ -68,6 +68,19 @@ bool supports_display_compositing, bool is_overlay_candidate); + // Creates an image wrapping an external mailbox. + // The mailbox may come from a different context, + // potentially from a different process. + // This takes ownership of the mailbox. + static scoped_refptr<AcceleratedStaticBitmapImage> CreateFromExternalMailbox( + const gpu::MailboxHolder& mailbox_holder, + uint32_t usage, + const SkImageInfo& sk_image_info, + bool is_origin_top_left, + bool supports_display_compositing, + bool is_overlay_candidate, + base::OnceCallback<void(const gpu::SyncToken&)> release_callback); + bool CurrentFrameKnownToBeOpaque() override; bool IsTextureBacked() const override { return true; } scoped_refptr<StaticBitmapImage> ConvertToColorSpace(sk_sp<SkColorSpace>, @@ -125,6 +138,10 @@ PaintImage PaintImageForCurrentFrame() override; + SkImageInfo GetSkImageInfo() const override; + + uint32_t GetUsage() const override; + private: struct ReleaseContext { scoped_refptr<MailboxRef> mailbox_ref; @@ -152,8 +169,6 @@ void CreateImageFromMailboxIfNeeded(); void InitializeTextureBacking(GLuint shared_image_texture_id); - SkImageInfo GetSkImageInfoInternal() const override; - const gpu::Mailbox mailbox_; const SkImageInfo sk_image_info_; const GLenum texture_target_;
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc index 2b79e06..0c2414f 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc +++ b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc
@@ -1190,6 +1190,8 @@ } if (layer.Chunks().size() == 1 && layer.FirstPaintChunk().size() == 1) { switch (layer.FirstDisplayItem().GetType()) { + case DisplayItem::kFixedAttachmentBackground: + return CompositingReason::kFixedAttachmentBackground; case DisplayItem::kCaret: return CompositingReason::kCaret; case DisplayItem::kScrollbarHorizontal:
diff --git a/third_party/blink/renderer/platform/graphics/compositing_reasons.cc b/third_party/blink/renderer/platform/graphics/compositing_reasons.cc index 71cea4cc..ad9c3c9 100644 --- a/third_party/blink/renderer/platform/graphics/compositing_reasons.cc +++ b/third_party/blink/renderer/platform/graphics/compositing_reasons.cc
@@ -90,6 +90,8 @@ {CompositingReason::kOverlap, "Overlaps other composited content."}, {CompositingReason::kBackfaceVisibilityHidden, "Has backface-visibility: hidden."}, + {CompositingReason::kFixedAttachmentBackground, + "Is an accelerated background-attachment:fixed background."}, {CompositingReason::kCaret, "Is a caret in an editor."}, {CompositingReason::kVideo, "Is an accelerated video."}, {CompositingReason::kCanvas,
diff --git a/third_party/blink/renderer/platform/graphics/compositing_reasons.h b/third_party/blink/renderer/platform/graphics/compositing_reasons.h index 14f883e..e54d520 100644 --- a/third_party/blink/renderer/platform/graphics/compositing_reasons.h +++ b/third_party/blink/renderer/platform/graphics/compositing_reasons.h
@@ -77,6 +77,7 @@ V(Overlap) \ /* These are based on the type of paint chunks and display items. */ \ V(BackfaceVisibilityHidden) \ + V(FixedAttachmentBackground) \ V(Caret) \ V(Video) \ V(Canvas) \
diff --git a/third_party/blink/renderer/platform/graphics/paint/display_item.cc b/third_party/blink/renderer/platform/graphics/paint/display_item.cc index 95fbfc6..c040edb 100644 --- a/third_party/blink/renderer/platform/graphics/paint/display_item.cc +++ b/third_party/blink/renderer/platform/graphics/paint/display_item.cc
@@ -116,6 +116,7 @@ static WTF::String SpecialDrawingTypeAsDebugString(DisplayItem::Type type) { switch (type) { DEBUG_STRING_CASE(BoxDecorationBackground); + DEBUG_STRING_CASE(FixedAttachmentBackground); DEBUG_STRING_CASE(Caret); DEBUG_STRING_CASE(CapsLockIndicator); DEBUG_STRING_CASE(ColumnRules);
diff --git a/third_party/blink/renderer/platform/graphics/paint/display_item.h b/third_party/blink/renderer/platform/graphics/paint/display_item.h index ffa2d48..afb9d28 100644 --- a/third_party/blink/renderer/platform/graphics/paint/display_item.h +++ b/third_party/blink/renderer/platform/graphics/paint/display_item.h
@@ -62,6 +62,7 @@ kDrawingPaintPhaseFirst = kDrawingFirst, kDrawingPaintPhaseLast = kDrawingFirst + kPaintPhaseMax, kBoxDecorationBackground, + kFixedAttachmentBackground, kCapsLockIndicator, kCaret, kColumnRules,
diff --git a/third_party/blink/renderer/platform/graphics/static_bitmap_image.cc b/third_party/blink/renderer/platform/graphics/static_bitmap_image.cc index 291c45844..0a575fd6 100644 --- a/third_party/blink/renderer/platform/graphics/static_bitmap_image.cc +++ b/third_party/blink/renderer/platform/graphics/static_bitmap_image.cc
@@ -37,7 +37,7 @@ } gfx::Size StaticBitmapImage::SizeWithConfig(SizeConfig config) const { - auto info = GetSkImageInfoInternal(); + auto info = GetSkImageInfo(); gfx::Size size(info.width(), info.height()); if (config.apply_orientation && orientation_.UsesWidthAsHeight()) size.Transpose();
diff --git a/third_party/blink/renderer/platform/graphics/static_bitmap_image.h b/third_party/blink/renderer/platform/graphics/static_bitmap_image.h index 03ac30f..814bfffeb 100644 --- a/third_party/blink/renderer/platform/graphics/static_bitmap_image.h +++ b/third_party/blink/renderer/platform/graphics/static_bitmap_image.h
@@ -95,13 +95,18 @@ return gpu::MailboxHolder(); } virtual void UpdateSyncToken(const gpu::SyncToken&) { NOTREACHED(); } + + // For gpu based images the Usage is a bitmap indicating set of API(s) and + // underlying gpu::SharedImage may be used with. + // The gpu::SharedImageInterface is using uint32_t directly. + virtual uint32_t GetUsage() const { + NOTREACHED(); + return 0; + } bool IsPremultiplied() const { - return GetSkImageInfoInternal().alphaType() == - SkAlphaType::kPremul_SkAlphaType; + return GetSkImageInfo().alphaType() == SkAlphaType::kPremul_SkAlphaType; } - SkColorInfo GetSkColorInfo() const { - return GetSkImageInfoInternal().colorInfo(); - } + SkColorInfo GetSkColorInfo() const { return GetSkImageInfo().colorInfo(); } // Methods have exactly the same implementation for all sub-classes bool OriginClean() const { return is_origin_clean_; } @@ -126,6 +131,9 @@ Vector<uint8_t> CopyImageData(const SkImageInfo& info, bool apply_orientation); + // Return the SkImageInfo of the internal representation of this image. + virtual SkImageInfo GetSkImageInfo() const = 0; + protected: // Helper for sub-classes void DrawHelper(cc::PaintCanvas*, @@ -135,9 +143,6 @@ const ImageDrawOptions&, const PaintImage&); - // Return the SkImageInfo of the internal representation of this image. - virtual SkImageInfo GetSkImageInfoInternal() const = 0; - // The image orientation is stored here because it is only available when the // static image is created and the underlying representations do not store // the information. The property is set at construction based on the source of
diff --git a/third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.cc b/third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.cc index 5c3cf5f8..4a99a3e3 100644 --- a/third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.cc +++ b/third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.cc
@@ -187,7 +187,7 @@ /*x=*/0, /*y=*/0); } -SkImageInfo UnacceleratedStaticBitmapImage::GetSkImageInfoInternal() const { +SkImageInfo UnacceleratedStaticBitmapImage::GetSkImageInfo() const { return paint_image_.GetSkImageInfo().makeWH(paint_image_.width(), paint_image_.height()); }
diff --git a/third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h b/third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h index 54325ae..f9d95ef 100644 --- a/third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h +++ b/third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h
@@ -45,10 +45,11 @@ bool CopyToResourceProvider(CanvasResourceProvider* resource_provider, const gfx::Rect& copy_rect) override; + SkImageInfo GetSkImageInfo() const override; + private: UnacceleratedStaticBitmapImage(sk_sp<SkImage>, ImageOrientation); UnacceleratedStaticBitmapImage(PaintImage, ImageOrientation); - SkImageInfo GetSkImageInfoInternal() const override; PaintImage paint_image_; THREAD_CHECKER(thread_checker_);
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index bb6d464..95731b68 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -603,6 +603,9 @@ base_feature: "none", }, { + name: "CompositeBackgroundAttachmentFixed", + }, + { name: "CompositeBGColorAnimation", public: true, status: "experimental", @@ -1630,8 +1633,8 @@ // `config`, `sandbox`, and `allow`). origin_trial_feature_name: "PrivacySandboxAdsAPIs", origin_trial_allows_third_party: true, - base_feature_status: "disabled", - copied_from_base_feature_if: "overridden", + base_feature_status: "enabled", + copied_from_base_feature_if: "enabled_or_overridden", }, { name: "FetchUploadStreaming", @@ -3035,6 +3038,11 @@ base_feature: "none", }, { + name: "SecurePaymentConfirmationAllowOneActivationlessShow", + public: true, + status: "test", + }, + { name: "SecurePaymentConfirmationDebug", base_feature: "none", public: true,
diff --git a/third_party/blink/tools/blinkpy/tool/commands/lint_wpt.py b/third_party/blink/tools/blinkpy/tool/commands/lint_wpt.py index e793603..e0b0e812 100644 --- a/third_party/blink/tools/blinkpy/tool/commands/lint_wpt.py +++ b/third_party/blink/tools/blinkpy/tool/commands/lint_wpt.py
@@ -365,7 +365,8 @@ def _manifest(self, repo_root: str) -> WPTManifest: wpt_dir = self._fs.normpath( self._fs.relpath(repo_root, self._finder.path_from_web_tests())) - return self._default_port.wpt_manifest(wpt_dir) + return self._default_port.wpt_manifest( + pathlib.Path(wpt_dir).as_posix()) def _is_dir_metadata(self, path: str) -> bool: return self._fs.basename(path) == '__dir__.ini'
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index e016fcf..d38433a 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -78,7 +78,8 @@ "prefix": "gpu", "platforms": ["Linux", "Mac", "Win", "Fuchsia"], "bases": [ "fast/canvas", - "external/wpt/mediacapture-record/MediaRecorder-canvas-media-source.https.html" ], + "external/wpt/mediacapture-record/MediaRecorder-canvas-media-source.https.html", + "external/wpt/webmessaging/postMessage_cross_domain_image_transfer_2d.sub.htm" ], "args": ["--enable-accelerated-2d-canvas"], "expires": "Jul 1, 2023" }, @@ -150,6 +151,26 @@ "expires": "Sep 1, 2023" }, { + "prefix": "composite-background-attachment-fixed", + "platforms": ["Linux"], + "bases": ["compositing/fixed-background-after-style-recalc.html", + "compositing/fixed-background-composited-html.html", + "compositing/fixed-background-negative-z-index-fixed.html", + "compositing/fixed-body-background-positioned.html", + "compositing/backgrounds", + "fast/backgrounds", + "paint/background", + "paint/invalidation/background", + "external/wpt/css/css-backgrounds", + "external/wpt/css/css-break/background-image-000.html", + "external/wpt/css/css-break/background-image-001.html", + "external/wpt/css/css-break/background-image-002.html", + "external/wpt/css/css-break/background-attachment-fixed.html"], + "args": ["--enable-features=CompositeBackgroundAttachmentFixed", + "--enable-prefer-compositing-to-lcd-text"], + "expires": "Aug 1, 2023" + }, + { "prefix": "attribution-reporting-debug-mode", "platforms": ["Linux", "Mac", "Win"], "bases": ["wpt_internal/attribution-reporting"], @@ -1116,7 +1137,8 @@ "prefix": "oopr-canvas2d", "platforms": ["Linux", "Mac", "Win"], "bases": [ "fast/canvas", - "external/wpt/mediacapture-record/MediaRecorder-canvas-media-source.https.html" ], + "external/wpt/mediacapture-record/MediaRecorder-canvas-media-source.https.html", + "external/wpt/webmessaging/postMessage_cross_domain_image_transfer_2d.sub.htm" ], "args": [ "--enable-features=CanvasOopRasterization", "--enable-accelerated-2d-canvas", "--enable-gpu-rasterization" ],
diff --git a/third_party/blink/web_tests/compositing/layer-creation/iframe-background-attachment-fixed.html b/third_party/blink/web_tests/compositing/layer-creation/iframe-background-attachment-fixed.html index 2cfcf15f..8805977 100644 --- a/third_party/blink/web_tests/compositing/layer-creation/iframe-background-attachment-fixed.html +++ b/third_party/blink/web_tests/compositing/layer-creation/iframe-background-attachment-fixed.html
@@ -1,14 +1,12 @@ <!DOCTYPE html> -<pre id="mainThreadScrollingReasons"></pre> - <iframe id="iframe" src="resources/background-attachment-fixed.html"></iframe> <div style="height: 2000px;"> </div> <script> -function scrollingLocationAndReasons(reasons) { - return reasons ? "scrolls on main: " + reasons : "scrolls on impl"; +function scrollingReasons(reasons) { + return reasons ? "scrolls on main thread, reasons: " + reasons : "scrolls on impl"; } if (window.internals) { @@ -16,13 +14,13 @@ internals.settings.setPreferCompositingToLCDTextEnabled(true); } -if (window.testRunner) - testRunner.dumpAsText(true); - -window.addEventListener('load', function() { - reasons = internals.mainThreadScrollingReasons(document); - text = "Main frame " + scrollingLocationAndReasons(reasons); - text += "\nThe iFrame scrolls on main thread, reasons: " + document.getElementById("iframe").contentDocument.getElementById("mainThreadScrollingReasons").innerText; - document.getElementById("mainThreadScrollingReasons").innerText = text; -}); +if (window.testRunner) { + testRunner.dumpAsText(true); + onload = () => { + var reasons = internals.mainThreadScrollingReasons(document); + text = "Main frame " + scrollingReasons(reasons); + text += "\nThe iFrame " + scrollingReasons(iframe.contentDocument.getElementById("mainThreadScrollingReasons").innerText); + testRunner.setCustomTextOutput(text); + }; +} </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/background-attachment-fixed-ref.html b/third_party/blink/web_tests/external/wpt/css/css-break/background-attachment-fixed-ref.html new file mode 100644 index 0000000..344c9d3 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-break/background-attachment-fixed-ref.html
@@ -0,0 +1,23 @@ +<!DOCTYPE html> +<style> +.blue { + position: absolute; + top: 0; + width: 40px; + height: 100px; + background: blue; +} +.green { + position: absolute; + top: 100px; + width: 40px; + height: 100px; + background: green; +} +</style> +<div class="blue" style="left: 30px; top: 30px; height: 70px"></div> +<div class="green" style="left: 30px"></div> +<div class="blue" style="left: 140px"></div> +<div class="green" style="left: 140px"></div> +<div class="blue" style="left: 250px"></div> +<div class="green" style="left: 250px; height: 70px"></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/background-attachment-fixed.html b/third_party/blink/web_tests/external/wpt/css/css-break/background-attachment-fixed.html new file mode 100644 index 0000000..00387322 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-break/background-attachment-fixed.html
@@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<link rel="help" href="https://www.w3.org/TR/css-break-3/#valdef-box-decoration-break-slice"> +<link rel="help" href="https://www.w3.org/TR/css-backgrounds-3/#background-image"> +<link rel="help" href="https://www.w3.org/TR/css-backgrounds-3/#background-attachment"> +<link rel="match" href="background-attachment-fixed-ref.html"> +<style> +body { + overflow: hidden; + margin: 0; +} +</style> +<div style="height: 300px"></div> +<div style="width: 320px; height: 200px; columns: 3; column-gap: 10px"> + <div style="height: 600px; + border: 20px solid transparent; + box-sizing: border-box; + padding: 10px; + background-size: 200px 200px; + background-image: linear-gradient(blue 50%, green 50%); + background-clip: content-box; + background-attachment: fixed"> + </div> +</div> +<div style="width: 2000px; height: 2000px"></div> +<script> +requestAnimationFrame(() => { + requestAnimationFrame(() => { + window.scrollTo(0, 300); + document.documentElement.classList.remove('reftest-wait'); + }); +}); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/density-size-correction/density-corrected-image-in-canvas.html.ini b/third_party/blink/web_tests/external/wpt/density-size-correction/density-corrected-image-in-canvas.html.ini index bcf5c9b..7740502 100644 --- a/third_party/blink/web_tests/external/wpt/density-size-correction/density-corrected-image-in-canvas.html.ini +++ b/third_party/blink/web_tests/external/wpt/density-size-correction/density-corrected-image-in-canvas.html.ini
@@ -1,4 +1,4 @@ [density-corrected-image-in-canvas.html] expected: - if (product == "content_shell") and (os == "mac") and (port == "mac13-arm64"): TIMEOUT if (product == "content_shell") and (os == "mac") and (port == "mac12-arm64"): TIMEOUT + if (product == "content_shell") and (os == "mac") and (port == "mac13-arm64"): TIMEOUT
diff --git a/third_party/blink/web_tests/external/wpt/webmessaging/postMessage_cross_domain_image_transfer_2d.sub.htm b/third_party/blink/web_tests/external/wpt/webmessaging/postMessage_cross_domain_image_transfer_2d.sub.htm new file mode 100644 index 0000000..4faf9792 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webmessaging/postMessage_cross_domain_image_transfer_2d.sub.htm
@@ -0,0 +1,34 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/get-host-info.sub.js"></script> +<body> +<script> +// Create a 2D canvas filled in solid gray. +var size = 4; +var sourceCanvas = document.createElement('canvas'); +sourceCanvas.width = sourceCanvas.height = size; +var ctx = sourceCanvas.getContext('2d'); +ctx.fillStyle = "gray"; +ctx.fillRect(0, 0, size, size); +const expectedPixels = "{\"0\":128,\"1\":128,\"2\":128,\"3\":255,\"4\":128,\"5\":128,\"6\":128,\"7\":255,\"8\":128,\"9\":128,\"10\":128,\"11\":255,\"12\":128,\"13\":128,\"14\":128,\"15\":255,\"16\":128,\"17\":128,\"18\":128,\"19\":255,\"20\":128,\"21\":128,\"22\":128,\"23\":255,\"24\":128,\"25\":128,\"26\":128,\"27\":255,\"28\":128,\"29\":128,\"30\":128,\"31\":255,\"32\":128,\"33\":128,\"34\":128,\"35\":255,\"36\":128,\"37\":128,\"38\":128,\"39\":255,\"40\":128,\"41\":128,\"42\":128,\"43\":255,\"44\":128,\"45\":128,\"46\":128,\"47\":255,\"48\":128,\"49\":128,\"50\":128,\"51\":255,\"52\":128,\"53\":128,\"54\":128,\"55\":255,\"56\":128,\"57\":128,\"58\":128,\"59\":255,\"60\":128,\"61\":128,\"62\":128,\"63\":255}"; + +const {ORIGIN, REMOTE_ORIGIN, HTTP_NOTSAMESITE_ORIGIN} = get_host_info(); +for (let origin of [ORIGIN, REMOTE_ORIGIN, HTTP_NOTSAMESITE_ORIGIN]) { + promise_test(async t => { + let imageBitmap = await createImageBitmap(sourceCanvas); + + let frame = document.createElement('iframe'); + frame.src = origin + '/webmessaging/support/cross-domain-image-receive.htm'; + document.body.appendChild(frame); + await new Promise(resolve => { frame.onload = e => resolve(); }); + + frame.contentWindow.postMessage({image: imageBitmap}, "*", [imageBitmap]); + let reply = await new Promise(resolve => { + window.addEventListener('message', e => resolve(e.data), {once: true}); + }); + assert_equals(reply, expectedPixels); + }, `sending 2D canvas ImageBitmap to ${origin}`); +} +</script> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/webmessaging/postMessage_cross_domain_image_transfer_webgl.sub.htm b/third_party/blink/web_tests/external/wpt/webmessaging/postMessage_cross_domain_image_transfer_webgl.sub.htm new file mode 100644 index 0000000..0c54589 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webmessaging/postMessage_cross_domain_image_transfer_webgl.sub.htm
@@ -0,0 +1,35 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/get-host-info.sub.js"></script> +<body> +<script> +// Create a 2D canvas filled in solid gray. +var size = 4; +var sourceCanvas = document.createElement('canvas'); +sourceCanvas.width = sourceCanvas.height = size; +var gl = sourceCanvas.getContext('webgl'); +gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); +gl.clearColor(0.5, 0.5, 0.5, 1.0); +gl.clear(gl.COLOR_BUFFER_BIT); +const expectedPixels = "{\"0\":128,\"1\":128,\"2\":128,\"3\":255,\"4\":128,\"5\":128,\"6\":128,\"7\":255,\"8\":128,\"9\":128,\"10\":128,\"11\":255,\"12\":128,\"13\":128,\"14\":128,\"15\":255,\"16\":128,\"17\":128,\"18\":128,\"19\":255,\"20\":128,\"21\":128,\"22\":128,\"23\":255,\"24\":128,\"25\":128,\"26\":128,\"27\":255,\"28\":128,\"29\":128,\"30\":128,\"31\":255,\"32\":128,\"33\":128,\"34\":128,\"35\":255,\"36\":128,\"37\":128,\"38\":128,\"39\":255,\"40\":128,\"41\":128,\"42\":128,\"43\":255,\"44\":128,\"45\":128,\"46\":128,\"47\":255,\"48\":128,\"49\":128,\"50\":128,\"51\":255,\"52\":128,\"53\":128,\"54\":128,\"55\":255,\"56\":128,\"57\":128,\"58\":128,\"59\":255,\"60\":128,\"61\":128,\"62\":128,\"63\":255}"; + +const {ORIGIN, REMOTE_ORIGIN, HTTP_NOTSAMESITE_ORIGIN} = get_host_info(); +for (let origin of [ORIGIN, REMOTE_ORIGIN, HTTP_NOTSAMESITE_ORIGIN]) { + promise_test(async t => { + let imageBitmap = await createImageBitmap(sourceCanvas); + + let frame = document.createElement('iframe'); + frame.src = origin + '/webmessaging/support/cross-domain-image-receive.htm'; + document.body.appendChild(frame); + await new Promise(resolve => { frame.onload = e => resolve(); }); + + frame.contentWindow.postMessage({image: imageBitmap}, "*", [imageBitmap]); + let reply = await new Promise(resolve => { + window.addEventListener('message', e => resolve(e.data), {once: true}); + }); + assert_equals(reply, expectedPixels); + }, `sending WebGL canvas ImageBitmap to ${origin}`); +} +</script> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/webmessaging/support/cross-domain-image-receive.htm b/third_party/blink/web_tests/external/wpt/webmessaging/support/cross-domain-image-receive.htm new file mode 100644 index 0000000..253b34b --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webmessaging/support/cross-domain-image-receive.htm
@@ -0,0 +1,25 @@ +<!DOCTYPE html> + +<html lang="en"> +<head> + <title>Cross-Domain image transfer test</title> +</head> +<script type="text/javascript" charset="utf-8"> + +function receiver(e) { + var dstCanvas = document.createElement('canvas'); + dstCanvas.width = e.data.image.width + dstCanvas.height = e.data.image.height + var dstCtx = dstCanvas.getContext('2d'); + dstCtx.drawImage(e.data.image, 0, 0) + var imgData = dstCtx.getImageData(0, 0, dstCanvas.height, dstCanvas.width); + + result = JSON.stringify(imgData.data); + e.source.postMessage(result, "*"); +} + +addEventListener('message', receiver, false); +</script> +<body> +</body> +</html>
diff --git a/third_party/blink/web_tests/fast/backgrounds/root-background-fixed-attachment-positioning.html b/third_party/blink/web_tests/fast/backgrounds/root-background-fixed-attachment-positioning.html index 60b7785..f3e7cc41 100644 --- a/third_party/blink/web_tests/fast/backgrounds/root-background-fixed-attachment-positioning.html +++ b/third_party/blink/web_tests/fast/backgrounds/root-background-fixed-attachment-positioning.html
@@ -1,4 +1,5 @@ <!DOCTYPE html> +<meta name="fuzzy" content="maxDifference=0-1;totalPixels=0-300"> <style> html { background: url('../../paint/invalidation/resources/grid.png');
diff --git a/third_party/blink/web_tests/paint/invalidation/background/background-attachment-fixed-scrolled-expected.txt b/third_party/blink/web_tests/paint/invalidation/background/background-attachment-fixed-scrolled-expected.txt new file mode 100644 index 0000000..2cf844b --- /dev/null +++ b/third_party/blink/web_tests/paint/invalidation/background/background-attachment-fixed-scrolled-expected.txt
@@ -0,0 +1,47 @@ +{ + "layers": [ + { + "name": "Scrolling background of LayoutNGView #document", + "bounds": [785, 1200], + "contentsOpaque": true, + "backgroundColor": "#FFFFFF", + "transform": 1 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV id='composited-background-attachment-fixed'", + "bounds": [500, 1000], + "invalidations": [ + [0, 0, 500, 1000] + ], + "transform": 2 + }, + { + "name": "VerticalScrollbar", + "position": [785, 0], + "bounds": [15, 600], + "contentsOpaque": true + } + ], + "transforms": [ + { + "id": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [0, -123, 0, 1] + ] + }, + { + "id": 2, + "parent": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [50, 200, 0, 1] + ] + } + ] +} +
diff --git a/third_party/blink/web_tests/paint/invalidation/background/background-attachment-fixed-scrolled.html b/third_party/blink/web_tests/paint/invalidation/background/background-attachment-fixed-scrolled.html index 71c8a1e..8edfc5cd 100644 --- a/third_party/blink/web_tests/paint/invalidation/background/background-attachment-fixed-scrolled.html +++ b/third_party/blink/web_tests/paint/invalidation/background/background-attachment-fixed-scrolled.html
@@ -18,10 +18,10 @@ The test verifies background-attachment:fixed gets invalidated after scroll even if they are composited. </div> <div id="composited-background-attachment-fixed"></div> -<script src="../../../resources/run-after-layout-and-paint.js"></script> +<script src="../resources/text-based-repaint.js"></script> <script> -document.body.offsetTop; -runAfterLayoutAndPaint(function() { - scrollTo(0, 123); -}, true); +onload = runRepaintAndPixelTest; +function repaintTest() { + scrollTo(0, 123); +} </script>
diff --git a/third_party/blink/web_tests/virtual/composite-background-attachment-fixed/README.md b/third_party/blink/web_tests/virtual/composite-background-attachment-fixed/README.md new file mode 100644 index 0000000..c01d6bc --- /dev/null +++ b/third_party/blink/web_tests/virtual/composite-background-attachment-fixed/README.md
@@ -0,0 +1,2 @@ +Run chosen web tests with --enable-features=CompositeBackgroundAttachmentFixed +and --enable-prefer-compositing-to-lcd-text.
diff --git a/third_party/blink/web_tests/virtual/composite-background-attachment-fixed/compositing/layer-creation/iframe-background-attachment-fixed-expected.txt b/third_party/blink/web_tests/virtual/composite-background-attachment-fixed/compositing/layer-creation/iframe-background-attachment-fixed-expected.txt new file mode 100644 index 0000000..f0c20b3bc --- /dev/null +++ b/third_party/blink/web_tests/virtual/composite-background-attachment-fixed/compositing/layer-creation/iframe-background-attachment-fixed-expected.txt
@@ -0,0 +1,2 @@ +Main frame scrolls on impl +The iFrame scrolls on impl
diff --git a/third_party/blink/web_tests/virtual/composite-background-attachment-fixed/paint/invalidation/background/background-attachment-fixed-scrolled-expected.txt b/third_party/blink/web_tests/virtual/composite-background-attachment-fixed/paint/invalidation/background/background-attachment-fixed-scrolled-expected.txt new file mode 100644 index 0000000..3999dae2 --- /dev/null +++ b/third_party/blink/web_tests/virtual/composite-background-attachment-fixed/paint/invalidation/background/background-attachment-fixed-scrolled-expected.txt
@@ -0,0 +1,49 @@ +{ + "layers": [ + { + "name": "Scrolling background of LayoutNGView #document", + "bounds": [785, 1200], + "contentsOpaque": true, + "backgroundColor": "#FFFFFF", + "transform": 1 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV id='composited-background-attachment-fixed'", + "bounds": [785, 600] + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV id='composited-background-attachment-fixed'", + "bounds": [500, 1000], + "drawsContent": false, + "transform": 2 + }, + { + "name": "VerticalScrollbar", + "position": [785, 0], + "bounds": [15, 600], + "contentsOpaque": true + } + ], + "transforms": [ + { + "id": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [0, -123, 0, 1] + ] + }, + { + "id": 2, + "parent": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [50, 200, 0, 1] + ] + } + ] +} +
diff --git a/third_party/blink/web_tests/webexposed/css-properties-as-js-properties-expected.txt b/third_party/blink/web_tests/webexposed/css-properties-as-js-properties-expected.txt index 4e63a97..e6a3496 100644 --- a/third_party/blink/web_tests/webexposed/css-properties-as-js-properties-expected.txt +++ b/third_party/blink/web_tests/webexposed/css-properties-as-js-properties-expected.txt
@@ -165,7 +165,6 @@ display dominantBaseline emptyCells -end fallback fill fillOpacity @@ -401,11 +400,9 @@ shapeRendering size sizeAdjust -source speak speakAs src -start stopColor stopOpacity stroke
diff --git a/third_party/blink/web_tests/wpt_internal/attribution-reporting/aggregatable-debug-report.sub.https.html b/third_party/blink/web_tests/wpt_internal/attribution-reporting/aggregatable-debug-report.sub.https.html index 8eaa031..92c1b782 100644 --- a/third_party/blink/web_tests/wpt_internal/attribution-reporting/aggregatable-debug-report.sub.https.html +++ b/third_party/blink/web_tests/wpt_internal/attribution-reporting/aggregatable-debug-report.sub.https.html
@@ -6,48 +6,47 @@ <script src="resources/helpers.js"></script> <script> attribution_reporting_promise_test(async t => { - const source = { - source_event_id: generateSourceEventId(), - destination: 'https://{{host}}', - aggregation_keys: { - campaignCounts: '0x159', - geoValue: '0x5', - }, - debug_key: '246', - }; - await registerAttributionSrc({ - source, - cookie: attributionDebugCookie, - }); - await waitForSourceToBeRegistered(source.source_event_id); + const expectedSourceDebugKey = '246'; + const expectedTriggerDebugKey = '357'; - const trigger_debug_key = '357'; - await registerAttributionSrc({ - trigger: { - debug_key: trigger_debug_key, - aggregatable_trigger_data: [ - { - key_piece: '0x400', - source_keys: ['campaignCounts'], + registerAttributionSrcByImg(createRedirectChain([ + { + cookie: attributionDebugCookie, + source: { + aggregation_keys: { + campaignCounts: '0x159', + geoValue: '0x5', }, - { - key_piece: '0xA80', - source_keys: ['geoValue', 'nonMatchingKey'], - } - ], - aggregatable_values: { - campaignCounts: 32768, - geoValue: 1664, + debug_key: expectedSourceDebugKey, + destination: 'https://{{host}}', }, }, - cookie: attributionDebugCookie, - }); + { + trigger: { + aggregatable_trigger_data: [ + { + key_piece: '0x400', + source_keys: ['campaignCounts'], + }, + { + key_piece: '0xA80', + source_keys: ['geoValue', 'nonMatchingKey'], + } + ], + aggregatable_values: { + campaignCounts: 32768, + geoValue: 1664, + }, + debug_key: expectedTriggerDebugKey, + }, + }, + ])); const payload = await pollAggregatableReports(); assert_equals(payload.reports.length, 1); const report = JSON.parse(payload.reports[0].body); - assert_equals(report.source_debug_key, source.debug_key); - assert_equals(report.trigger_debug_key, trigger_debug_key); + assert_equals(report.source_debug_key, expectedSourceDebugKey); + assert_equals(report.trigger_debug_key, expectedTriggerDebugKey); const shared_info = JSON.parse(report.shared_info); assert_own_property(shared_info, 'debug_mode'); assert_equals(shared_info.debug_mode, 'enabled'); @@ -57,8 +56,8 @@ const debugPayload = await pollAggregatableDebugReports(); assert_equals(debugPayload.reports.length, 1); const debugReport = JSON.parse(debugPayload.reports[0].body); - assert_equals(debugReport.source_debug_key, source.debug_key); - assert_equals(debugReport.trigger_debug_key, trigger_debug_key); + assert_equals(debugReport.source_debug_key, expectedSourceDebugKey); + assert_equals(debugReport.trigger_debug_key, expectedTriggerDebugKey); const debug_shared_info = JSON.parse(debugReport.shared_info); assert_own_property(debug_shared_info, 'debug_mode'); assert_equals(debug_shared_info.debug_mode, 'enabled');
diff --git a/third_party/blink/web_tests/wpt_internal/attribution-reporting/aggregatable-report-insufficient-budget.sub.https.html b/third_party/blink/web_tests/wpt_internal/attribution-reporting/aggregatable-report-insufficient-budget.sub.https.html index 04dab3a9..330657f 100644 --- a/third_party/blink/web_tests/wpt_internal/attribution-reporting/aggregatable-report-insufficient-budget.sub.https.html +++ b/third_party/blink/web_tests/wpt_internal/attribution-reporting/aggregatable-report-insufficient-budget.sub.https.html
@@ -10,19 +10,6 @@ attribution_reporting_promise_test(async t => { const host = 'https://{{host}}'; - const source = { - source_event_id: generateSourceEventId(), - destination: host, - aggregation_keys: { - campaignCounts: '0x159', - }, - }; - await registerAttributionSrc({ - source, - method: 'open', - }); - await waitForSourceToBeRegistered(source.source_event_id); - const trigger = { aggregatable_trigger_data: [{ key_piece: '0x400', @@ -34,9 +21,19 @@ debug_reporting: true, }; - await registerAttributionSrc({ - trigger, - }); + const expectedSourceEventId = generateSourceEventId(); + registerAttributionSrcByImg(createRedirectChain([ + { + source: { + aggregation_keys: { + campaignCounts: '0x159', + }, + destination: host, + source_event_id: expectedSourceEventId, + }, + }, + {trigger}, + ])); const payload = await pollAggregatableReports(); assert_equals(payload.reports.length, 1); @@ -46,11 +43,12 @@ assert_equals(shared_info.attribution_destination, host); trigger.aggregatable_values.campaignCounts = 1; - - await registerAttributionSrc({ - trigger, - cookie: attributionDebugCookie, - }); + registerAttributionSrcByImg(createRedirectChain([ + { + cookie: attributionDebugCookie, + trigger, + }, + ])); const debugPayload = await pollVerboseDebugReports(); assert_equals(debugPayload.reports.length, 1); @@ -60,7 +58,7 @@ assert_own_property(debugReport[0], 'body'); const debugReportBody = debugReport[0].body; assert_equals(debugReportBody.attribution_destination, host); - assert_equals(debugReportBody.source_event_id, source.source_event_id); + assert_equals(debugReportBody.source_event_id, expectedSourceEventId); assert_equals(debugReportBody.source_site, host); assert_not_own_property(debugReportBody, 'source_debug_key'); assert_not_own_property(debugReportBody, 'trigger_debug_key');
diff --git a/third_party/blink/web_tests/wpt_internal/attribution-reporting/aggregatable-report-no-contributions.sub.https.html b/third_party/blink/web_tests/wpt_internal/attribution-reporting/aggregatable-report-no-contributions.sub.https.html index 92affe3b..caba932a 100644 --- a/third_party/blink/web_tests/wpt_internal/attribution-reporting/aggregatable-report-no-contributions.sub.https.html +++ b/third_party/blink/web_tests/wpt_internal/attribution-reporting/aggregatable-report-no-contributions.sub.https.html
@@ -8,30 +8,32 @@ attribution_reporting_promise_test(async t => { const host = 'https://{{host}}'; - const source = { - source_event_id: generateSourceEventId(), - destination: host, - aggregation_keys: { - campaignCounts: '0x159', - }, - debug_key: '456', - }; - await registerAttributionSrc({ - source, - cookie: attributionDebugCookie, - }); - await waitForSourceToBeRegistered(source.source_event_id); + const expectedSourceEventId = generateSourceEventId(); + const expectedSourceDebugKey = '456'; + const expectedTriggerDebugKey = '654'; - await registerAttributionSrc({ - trigger : { - aggregatable_values: { - geoValue: 32768, + registerAttributionSrcByImg(createRedirectChain([ + { + cookie: attributionDebugCookie, + source: { + aggregation_keys: { + campaignCounts: '0x159', + }, + debug_key: expectedSourceDebugKey, + destination: host, + source_event_id: expectedSourceEventId, }, - debug_key: '654', - debug_reporting: true, }, - cookie: attributionDebugCookie, - }); + { + trigger : { + aggregatable_values: { + geoValue: 32768, + }, + debug_key: expectedTriggerDebugKey, + debug_reporting: true, + }, + }, + ])); const debugPayload = await pollVerboseDebugReports(); assert_equals(debugPayload.reports.length, 1); @@ -41,9 +43,9 @@ assert_own_property(debugReport[0], 'body'); const debugReportBody = debugReport[0].body; assert_equals(debugReportBody.attribution_destination, host); - assert_equals(debugReportBody.source_event_id, source.source_event_id); + assert_equals(debugReportBody.source_event_id, expectedSourceEventId); assert_equals(debugReportBody.source_site, host); - assert_equals(debugReportBody.source_debug_key, '456'); - assert_equals(debugReportBody.trigger_debug_key, '654'); + assert_equals(debugReportBody.source_debug_key, expectedSourceDebugKey); + assert_equals(debugReportBody.trigger_debug_key, expectedTriggerDebugKey); }, 'Aggregatable report is not created due to no contributions.'); </script>
diff --git a/third_party/blink/web_tests/wpt_internal/attribution-reporting/event-level-debug-report.sub.https.html b/third_party/blink/web_tests/wpt_internal/attribution-reporting/event-level-debug-report.sub.https.html index 43bd206..dcc9308 100644 --- a/third_party/blink/web_tests/wpt_internal/attribution-reporting/event-level-debug-report.sub.https.html +++ b/third_party/blink/web_tests/wpt_internal/attribution-reporting/event-level-debug-report.sub.https.html
@@ -6,36 +6,35 @@ <script src="resources/helpers.js"></script> <script> attribution_reporting_promise_test(async t => { - const source = { - source_event_id: generateSourceEventId(), - destination: 'https://{{host}}', - debug_key: '246', - }; - await registerAttributionSrc({ - source, - cookie: attributionDebugCookie, - }); - await waitForSourceToBeRegistered(source.source_event_id); + const expectedSourceDebugKey = '246'; + const expectedTriggerDebugKey = '357'; - const trigger_debug_key = '357'; - await registerAttributionSrc({ - trigger: { - event_trigger_data: [{}], - debug_key: trigger_debug_key, + registerAttributionSrcByImg(createRedirectChain([ + { + cookie: attributionDebugCookie, + source: { + debug_key: expectedSourceDebugKey, + destination: 'https://{{host}}', + }, }, - cookie: attributionDebugCookie, - }); + { + trigger: { + debug_key: expectedTriggerDebugKey, + event_trigger_data: [{}], + }, + }, + ])); const payload = await pollEventLevelReports(); assert_equals(payload.reports.length, 1); const report = JSON.parse(payload.reports[0].body); - assert_equals(report.source_debug_key, source.debug_key); - assert_equals(report.trigger_debug_key, trigger_debug_key); + assert_equals(report.source_debug_key, expectedSourceDebugKey); + assert_equals(report.trigger_debug_key, expectedTriggerDebugKey); const debugPayload = await pollEventLevelDebugReports(); assert_equals(debugPayload.reports.length, 1); const debugReport = JSON.parse(debugPayload.reports[0].body); - assert_equals(debugReport.source_debug_key, source.debug_key); - assert_equals(debugReport.trigger_debug_key, trigger_debug_key); + assert_equals(debugReport.source_debug_key, expectedSourceDebugKey); + assert_equals(debugReport.trigger_debug_key, expectedTriggerDebugKey); }, 'Debug report is received if source and trigger debug keys are set.'); </script>
diff --git a/third_party/blink/web_tests/wpt_internal/attribution-reporting/event-level-report-deduplication.sub.https.html b/third_party/blink/web_tests/wpt_internal/attribution-reporting/event-level-report-deduplication.sub.https.html index 7ef54e1..9afb41c 100644 --- a/third_party/blink/web_tests/wpt_internal/attribution-reporting/event-level-report-deduplication.sub.https.html +++ b/third_party/blink/web_tests/wpt_internal/attribution-reporting/event-level-report-deduplication.sub.https.html
@@ -10,42 +10,47 @@ attribution_reporting_promise_test(async t => { const host = 'https://{{host}}'; - const source = { - source_event_id: generateSourceEventId(), - destination: host, - }; - await registerAttributionSrc({ - source, - method: 'open', - }); - await waitForSourceToBeRegistered(source.source_event_id); + const expectedSourceEventId = generateSourceEventId(); + const expectedTriggerData = '1'; + const deduplicationKey = '666'; - await registerAttributionSrc({ - trigger: { - event_trigger_data: [{ - deduplication_key: '666', - trigger_data: '5', - }], + registerAttributionSrcByImg(createRedirectChain([ + { + source: { + destination: host, + source_event_id: expectedSourceEventId, + }, }, - }); + { + trigger: { + event_trigger_data: [{ + deduplication_key: deduplicationKey, + trigger_data: expectedTriggerData, + }], + }, + }, + ])); const payload = await pollEventLevelReports(); assert_equals(payload.reports.length, 1); const report = JSON.parse(payload.reports[0].body); - assert_equals(report.trigger_data, '5'); + assert_equals(report.trigger_data, expectedTriggerData); assert_equals(report.attribution_destination, host); - await registerAttributionSrc({ - trigger: { - event_trigger_data: [{ - deduplication_key: '666', - }], - debug_key: '789', - debug_reporting: true, + const expectedTriggerDebugKey = '789'; + registerAttributionSrcByImg(createRedirectChain([ + { + cookie: attributionDebugCookie, + trigger: { + debug_key: expectedTriggerDebugKey, + debug_reporting: true, + event_trigger_data: [{ + deduplication_key: deduplicationKey, + }], + }, }, - cookie: attributionDebugCookie, - }); + ])); const debugPayload = await pollVerboseDebugReports(); assert_equals(debugPayload.reports.length, 1); @@ -55,9 +60,9 @@ assert_own_property(debugReport[0], 'body'); const debugReportBody = debugReport[0].body; assert_equals(debugReportBody.attribution_destination, host); - assert_equals(debugReportBody.source_event_id, source.source_event_id); + assert_equals(debugReportBody.source_event_id, expectedSourceEventId); assert_equals(debugReportBody.source_site, host); - assert_equals(debugReportBody.trigger_debug_key, '789'); + assert_equals(debugReportBody.trigger_debug_key, expectedTriggerDebugKey); assert_not_own_property(debugReportBody, 'source_debug_key'); }, 'Event-level report is deduplicated.'); </script>
diff --git a/third_party/blink/web_tests/wpt_internal/attribution-reporting/multiple-event-level-attributions.sub.https.html b/third_party/blink/web_tests/wpt_internal/attribution-reporting/multiple-event-level-attributions.sub.https.html index 1d003ca5..810683a 100644 --- a/third_party/blink/web_tests/wpt_internal/attribution-reporting/multiple-event-level-attributions.sub.https.html +++ b/third_party/blink/web_tests/wpt_internal/attribution-reporting/multiple-event-level-attributions.sub.https.html
@@ -19,17 +19,11 @@ }); await waitForSourceToBeRegistered(source.source_event_id); - await Promise.all([ - registerAttributionSrc({trigger: { - event_trigger_data: [{trigger_data: '3'}], - }}), - registerAttributionSrc({trigger: { - event_trigger_data: [{trigger_data: '4'}], - }}), - registerAttributionSrc({trigger: { - event_trigger_data: [{trigger_data: '5'}], - }}), - ]); + registerAttributionSrcByImg(createRedirectChain([ + {trigger: {event_trigger_data: [{trigger_data: '3'}]}}, + {trigger: {event_trigger_data: [{trigger_data: '4'}]}}, + {trigger: {event_trigger_data: [{trigger_data: '5'}]}}, + ])); const reports = [];
diff --git a/third_party/blink/web_tests/wpt_internal/attribution-reporting/resources/helpers.js b/third_party/blink/web_tests/wpt_internal/attribution-reporting/resources/helpers.js index eef46e2..29914ca 100644 --- a/third_party/blink/web_tests/wpt_internal/attribution-reporting/resources/helpers.js +++ b/third_party/blink/web_tests/wpt_internal/attribution-reporting/resources/helpers.js
@@ -44,11 +44,15 @@ // , and ) in pipe values must be escaped with \ const encodeForPipe = urlString => urlString.replace(pipeHeaderPattern, '\\$&'); -const blankURLWithHeaders = (headers, origin) => { +const blankURLWithHeaders = (headers, origin, status) => { const url = blankURL(origin); const parts = headers.map(h => `header(${h.name},${encodeForPipe(h.value)})`); + if (status !== undefined) { + parts.push(`status(${encodeForPipe(status)})`); + } + if (parts.length > 0) { url.searchParams.set('pipe', parts.join('|')); } @@ -75,11 +79,9 @@ const crossOrigin = get_host_info().HTTPS_REMOTE_ORIGIN; const params = getFetchParams(crossOrigin); - return fetch(blankURLWithHeaders( - params.headers.concat(headers), - crossOrigin, - {credentials: params.credentials} - )); + return fetch( + blankURLWithHeaders(params.headers.concat(headers), crossOrigin), + {credentials: params.credentials}); } /** @@ -142,6 +144,49 @@ return crossOrigin === null ? location.origin : get_host_info().HTTPS_REMOTE_ORIGIN; }; +const createRedirectChain = (redirects) => { + let redirectTo; + + for (let i = redirects.length - 1; i >= 0; i--) { + const {source, trigger, cookie, reportingOrigin} = redirects[i]; + const headers = []; + + if (source) { + headers.push({ + name: 'Attribution-Reporting-Register-Source', + value: JSON.stringify(source), + }); + } + + if (trigger) { + headers.push({ + name: 'Attribution-Reporting-Register-Trigger', + value: JSON.stringify(trigger), + }); + } + + if (cookie) { + headers.push({name: 'Set-Cookie', value: cookie}); + } + + let status; + if (redirectTo) { + headers.push({name: 'Location', value: redirectTo.toString()}); + status = '302'; + } + + redirectTo = blankURLWithHeaders( + headers, reportingOrigin || getDefaultReportingOrigin(), status); + } + + return redirectTo; +}; + +const registerAttributionSrcByImg = (attributionSrc) => { + const element = document.createElement('img'); + element.attributionSrc = attributionSrc; +}; + const eligibleHeader = 'Attribution-Reporting-Eligible'; const registerAttributionSrc = async ({
diff --git a/third_party/blink/web_tests/wpt_internal/attribution-reporting/simple-aggregatable-report.sub.https.html b/third_party/blink/web_tests/wpt_internal/attribution-reporting/simple-aggregatable-report.sub.https.html index 59619e4..70bdf0f3 100644 --- a/third_party/blink/web_tests/wpt_internal/attribution-reporting/simple-aggregatable-report.sub.https.html +++ b/third_party/blink/web_tests/wpt_internal/attribution-reporting/simple-aggregatable-report.sub.https.html
@@ -9,42 +9,40 @@ <script src="resources/helpers.js"></script> <script> attribution_reporting_promise_test(async t => { - const source = { - source_event_id: generateSourceEventId(), - destination: 'https://{{host}}', - aggregation_keys: { - campaignCounts: '0x159', - geoValue: '0x5', - } - }; - const trigger = { - aggregatable_trigger_data: [ - { - key_piece: '0x400', - source_keys: ['campaignCounts'], + const host = 'https://{{host}}'; + + registerAttributionSrcByImg(createRedirectChain([ + { + cookie: 'foo=bar;Secure;HttpOnly;Path=/', + source: { + aggregation_keys: { + campaignCounts: '0x159', + geoValue: '0x5', + }, + destination: host, }, - { - key_piece: '0xA80', - source_keys: ['geoValue', 'nonMatchingKey'], - } - ], - aggregatable_values: { - campaignCounts: 32768, - geoValue: 1664, }, - }; + { + trigger: { + aggregatable_trigger_data: [ + { + key_piece: '0x400', + source_keys: ['campaignCounts'], + }, + { + key_piece: '0xA80', + source_keys: ['geoValue', 'nonMatchingKey'], + } + ], + aggregatable_values: { + campaignCounts: 32768, + geoValue: 1664, + }, + }, + }, + ])); - const reportingOrigin = getDefaultReportingOrigin(); - - await registerAttributionSrc({ - source, - cookie: 'foo=bar;Secure;HttpOnly;Path=/', - reportingOrigin - }); - await waitForSourceToBeRegistered(source.source_event_id); - await registerAttributionSrc({trigger, reportingOrigin}); - - const payload = await pollAggregatableReports(reportingOrigin); + const payload = await pollAggregatableReports(getDefaultReportingOrigin()); assert_equals(payload.reports.length, 1); const report = JSON.parse(payload.reports[0].body); const headers = payload.reports[0].headers; @@ -57,7 +55,7 @@ assert_own_property(shared_info, 'scheduled_report_time'); assert_own_property(shared_info, 'version'); assert_own_property(shared_info, 'attribution_destination'); - assert_equals(shared_info.attribution_destination, source.destination); + assert_equals(shared_info.attribution_destination, host); assert_not_own_property(report, 'source_debug_key'); assert_not_own_property(report, 'trigger_debug_key'); assert_own_property(report, 'aggregation_service_payloads');
diff --git a/third_party/blink/web_tests/wpt_internal/attribution-reporting/simple-event-level-report.sub.https.html b/third_party/blink/web_tests/wpt_internal/attribution-reporting/simple-event-level-report.sub.https.html index 038ba32..1b9819d 100644 --- a/third_party/blink/web_tests/wpt_internal/attribution-reporting/simple-event-level-report.sub.https.html +++ b/third_party/blink/web_tests/wpt_internal/attribution-reporting/simple-event-level-report.sub.https.html
@@ -13,19 +13,23 @@ const reportingOrigin = getDefaultReportingOrigin(); attribution_reporting_promise_test(async t => { - const source = { - source_event_id: generateSourceEventId(), - destination: 'https://{{host}}', - }; - await registerAttributionSrc({ - source, - cookie: 'foo=bar;Secure;HttpOnly;Path=/', - reportingOrigin, - }); - await waitForSourceToBeRegistered(source.source_event_id); + const host = 'https://{{host}}'; + const expectedSourceEventId = generateSourceEventId(); - const trigger = {event_trigger_data: [{trigger_data: '2'}]}; - await registerAttributionSrc({trigger, reportingOrigin}); + registerAttributionSrcByImg(createRedirectChain([ + { + cookie: 'foo=bar;Secure;HttpOnly;Path=/', + reportingOrigin, + source: { + destination: host, + source_event_id: expectedSourceEventId, + }, + }, + { + reportingOrigin, + trigger: {event_trigger_data: [{trigger_data: '2'}]}, + }, + ])); const payload = await pollEventLevelReports(reportingOrigin); assert_equals(payload.reports.length, 1); @@ -35,9 +39,9 @@ // The trigger data is sanitized to "0" because event sources are limited to 1 // bit. assert_equals(report.trigger_data, '0'); - assert_equals(report.source_event_id, source.source_event_id); + assert_equals(report.source_event_id, expectedSourceEventId); assert_equals(report.source_type, 'event'); - assert_equals(report.attribution_destination, source.destination); + assert_equals(report.attribution_destination, host); assert_between_inclusive(report.randomized_trigger_rate, 0.0, 1.0);
diff --git a/third_party/blink/web_tests/wpt_internal/attribution-reporting/simple-verbose-debug-report.sub.https.html b/third_party/blink/web_tests/wpt_internal/attribution-reporting/simple-verbose-debug-report.sub.https.html index 055330df..d41d006 100644 --- a/third_party/blink/web_tests/wpt_internal/attribution-reporting/simple-verbose-debug-report.sub.https.html +++ b/third_party/blink/web_tests/wpt_internal/attribution-reporting/simple-verbose-debug-report.sub.https.html
@@ -7,14 +7,18 @@ <script src="resources/helpers.js"></script> <script> attribution_reporting_promise_test(async t => { - await registerAttributionSrc({ - trigger: { - event_trigger_data: [{}], - debug_reporting: true, - debug_key: '456', + const expectedTriggerDebugKey = '456'; + + registerAttributionSrcByImg(createRedirectChain([ + { + cookie: attributionDebugCookie, + trigger: { + debug_reporting: true, + debug_key: expectedTriggerDebugKey, + event_trigger_data: [{}], + }, }, - cookie: attributionDebugCookie, - }); + ])); const payload = await pollVerboseDebugReports(); assert_equals(payload.reports.length, 1); @@ -23,6 +27,6 @@ assert_equals(report[0].type, 'trigger-no-matching-source'); assert_own_property(report[0], 'body'); assert_equals(report[0].body.attribution_destination, 'https://{{host}}'); - assert_equals(report[0].body.trigger_debug_key, '456'); + assert_equals(report[0].body.trigger_debug_key, expectedTriggerDebugKey); }, 'Verbose debug report is received.'); </script>
diff --git a/third_party/blink/web_tests/wpt_internal/attribution-reporting/source-priority.sub.https.html b/third_party/blink/web_tests/wpt_internal/attribution-reporting/source-priority.sub.https.html index 0fa76300..17eea40 100644 --- a/third_party/blink/web_tests/wpt_internal/attribution-reporting/source-priority.sub.https.html +++ b/third_party/blink/web_tests/wpt_internal/attribution-reporting/source-priority.sub.https.html
@@ -6,31 +6,36 @@ <script src="resources/helpers.js"></script> <script> attribution_reporting_promise_test(async t => { - const sources = [{ - source_event_id: generateSourceEventId(), - destination: 'https://{{host}}', - priority: '11', - }, - { - source_event_id: generateSourceEventId(), - destination: 'https://{{host}}', - priority: '13', - }, - { - source_event_id: generateSourceEventId(), - destination: 'https://{{host}}', - priority: '12', - }] - await Promise.all(sources.map(source => registerAttributionSrc({source}))); - await Promise.all(sources.map(source => waitForSourceToBeRegistered(source.source_event_id))); + const host = 'https://{{host}}'; - await registerAttributionSrc({trigger: { - event_trigger_data: [{}], - }}); + registerAttributionSrcByImg(createRedirectChain([ + { + source: { + destination: host, + priority: '11', + source_event_id: '6', + }, + }, + { + source: { + destination: host, + priority: '13', + source_event_id: '5', + }, + }, + { + source: { + destination: host, + priority: '12', + source_event_id: '4', + }, + }, + {trigger: {event_trigger_data: [{}]}}, + ])); const payload = await pollEventLevelReports(); assert_equals(payload.reports.length, 1); const report = JSON.parse(payload.reports[0].body); - assert_equals(report.source_event_id, sources[1].source_event_id); + assert_equals(report.source_event_id, '5'); }, 'Trigger is attributed to highest priority source.'); </script>
diff --git a/third_party/blink/web_tests/wpt_internal/attribution-reporting/top-level-filter-data-debug-report.sub.https.html b/third_party/blink/web_tests/wpt_internal/attribution-reporting/top-level-filter-data-debug-report.sub.https.html index 9bddc12..a86aadc7 100644 --- a/third_party/blink/web_tests/wpt_internal/attribution-reporting/top-level-filter-data-debug-report.sub.https.html +++ b/third_party/blink/web_tests/wpt_internal/attribution-reporting/top-level-filter-data-debug-report.sub.https.html
@@ -7,22 +7,26 @@ <script> attribution_reporting_promise_test(async t => { const host = 'https://{{host}}'; - const source = { - destination: host, - source_event_id: generateSourceEventId(), - filter_data: { a: ['b'] }, - }; - await registerAttributionSrc({ source }); - await waitForSourceToBeRegistered(source.source_event_id); - await registerAttributionSrc({ - trigger: { - event_trigger_data: [{}], - filters: {a: ['c']}, - debug_reporting: true, + const expectedSourceEventId = generateSourceEventId(); + + registerAttributionSrcByImg(createRedirectChain([ + { + source: { + destination: host, + filter_data: {a: ['b']}, + source_event_id: expectedSourceEventId, + }, }, - cookie: attributionDebugCookie, - }); + { + cookie: attributionDebugCookie, + trigger: { + debug_reporting: true, + event_trigger_data: [{}], + filters: {a: ['c']}, + }, + }, + ])); const payload = await pollVerboseDebugReports(); assert_equals(payload.reports.length, 1); @@ -32,7 +36,7 @@ assert_own_property(report[0], 'body'); const reportBody = report[0].body; assert_equals(reportBody.attribution_destination, host); - assert_equals(reportBody.source_event_id, source.source_event_id); + assert_equals(reportBody.source_event_id, expectedSourceEventId); assert_equals(reportBody.source_site, host); assert_not_own_property(reportBody, 'source_debug_key'); assert_not_own_property(reportBody, 'trigger_debug_key');
diff --git a/third_party/breakpad/scripts/gen_symbol_tools_packager.py b/third_party/breakpad/scripts/gen_symbol_tools_packager.py index d9d8993b..d0f5bf51 100755 --- a/third_party/breakpad/scripts/gen_symbol_tools_packager.py +++ b/third_party/breakpad/scripts/gen_symbol_tools_packager.py
@@ -12,6 +12,7 @@ system into `symbol_tools.zip` in the out directory. """ import argparse +import os import sys @@ -51,7 +52,8 @@ replacements = [ ("@ARCH@", args.a), ("@GO_SOURCES@", args.go_src), - ("@EXTRA@", args.extra) + ("@EXTRA@", args.extra), + ("@CWD@", os.getcwd()) ] for token, replacement in replacements: template = replace(template, token, replacement)
diff --git a/third_party/breakpad/scripts/package_symbol_tools.py.template b/third_party/breakpad/scripts/package_symbol_tools.py.template index 8c330e4..71be6df4 100755 --- a/third_party/breakpad/scripts/package_symbol_tools.py.template +++ b/third_party/breakpad/scripts/package_symbol_tools.py.template
@@ -31,6 +31,7 @@ def main(): arch = "@ARCH@" + os.chdir("@CWD@") if not build_upload_system_symbols(arch): return False subprocess.check_call([
diff --git a/third_party/freetype/README.chromium b/third_party/freetype/README.chromium index 0a6add6..5555cb96 100644 --- a/third_party/freetype/README.chromium +++ b/third_party/freetype/README.chromium
@@ -1,7 +1,7 @@ Name: FreeType URL: http://www.freetype.org/ -Version: VER-2-13-0-72-g8154d8e2b -Revision: 8154d8e2be329b1a0a145faae7d5fe0dd6aa7a7a +Version: VER-2-13-0-73-g9806414c1 +Revision: 9806414c15230d253d5219ea0dafeddb717307b1 CPEPrefix: cpe:/a:freetype:freetype:2.12.1 License: Custom license "inspired by the BSD, Artistic, and IJG (Independent JPEG Group) licenses"
diff --git a/third_party/googletest/BUILD.gn b/third_party/googletest/BUILD.gn index bb692983..5d7f6f9 100644 --- a/third_party/googletest/BUILD.gn +++ b/third_party/googletest/BUILD.gn
@@ -157,7 +157,7 @@ deps = [ ":gtest" ] } -# Do NOT depend on this directly. Use //testing/gmock:gmock_main instead. +# Do NOT depend on this directly. Use //testing/gmock instead. # See README.chromium for details. source_set("gmock") { testonly = true
diff --git a/third_party/leveldatabase/env_chromium.cc b/third_party/leveldatabase/env_chromium.cc index 9ba8cfd..5ea8cc9 100644 --- a/third_party/leveldatabase/env_chromium.cc +++ b/third_party/leveldatabase/env_chromium.cc
@@ -813,8 +813,9 @@ } result->clear(); - for (const auto& entry : entries_result.value()) + for (const auto& entry : entries_result.value()) { result->push_back(entry.BaseName().AsUTF8Unsafe()); + } return Status::OK(); } @@ -890,8 +891,7 @@ Status result; const base::FilePath path = base::FilePath::FromUTF8Unsafe(fname); Retrier retrier; - FileErrorOr<std::unique_ptr<storage::FilesystemProxy::FileLock>> lock_result = - base::unexpected(base::File::Error::FILE_ERROR_FAILED); + FileErrorOr<std::unique_ptr<storage::FilesystemProxy::FileLock>> lock_result; do { lock_result = filesystem_->LockFile(path); } while (!lock_result.has_value() && retrier.ShouldKeepTrying()); @@ -934,54 +934,52 @@ Status ChromiumEnv::NewLogger(const std::string& fname, leveldb::Logger** result) { + *result = nullptr; FilePath path = FilePath::FromUTF8Unsafe(fname); FileErrorOr<base::File> open_result = filesystem_->OpenFile( path, base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE); if (!open_result.has_value()) { - *result = nullptr; return MakeIOError(fname, "Unable to create log file", kNewLogger, open_result.error()); - } else { - *result = new leveldb::ChromiumLogger(std::move(open_result.value())); - return Status::OK(); } + *result = new leveldb::ChromiumLogger(std::move(open_result.value())); + return Status::OK(); } Status ChromiumEnv::NewSequentialFile(const std::string& fname, leveldb::SequentialFile** result) { + *result = nullptr; FilePath path = FilePath::FromUTF8Unsafe(fname); FileErrorOr<base::File> open_result = filesystem_->OpenFile( path, base::File::FLAG_OPEN | base::File::FLAG_READ); if (!open_result.has_value()) { - *result = nullptr; return MakeIOError(fname, "Unable to create sequential file", kNewSequentialFile, open_result.error()); - } else { - *result = new ChromiumSequentialFile(fname, std::move(open_result.value())); - return Status::OK(); } + *result = new ChromiumSequentialFile(fname, std::move(open_result.value())); + return Status::OK(); } Status ChromiumEnv::NewRandomAccessFile(const std::string& fname, leveldb::RandomAccessFile** result) { + *result = nullptr; base::FilePath file_path = FilePath::FromUTF8Unsafe(fname); FileErrorOr<base::File> open_result = filesystem_->OpenFile( file_path, base::File::FLAG_READ | base::File::FLAG_OPEN); - if (open_result.has_value()) { - base::File file = std::move(open_result.value()); - if (file_cache_) { - *result = new ChromiumEvictableRandomAccessFile( - std::move(file_path), std::move(file), filesystem_.get(), - file_cache_.get()); - } else { - *result = - new ChromiumRandomAccessFile(std::move(file_path), std::move(file)); - } - return Status::OK(); + if (!open_result.has_value()) { + return MakeIOError(fname, FileErrorString(open_result.error()), + kNewRandomAccessFile, open_result.error()); } - *result = nullptr; - return MakeIOError(fname, FileErrorString(open_result.error()), - kNewRandomAccessFile, open_result.error()); + base::File file = std::move(open_result.value()); + if (file_cache_) { + *result = new ChromiumEvictableRandomAccessFile( + std::move(file_path), std::move(file), filesystem_.get(), + file_cache_.get()); + } else { + *result = + new ChromiumRandomAccessFile(std::move(file_path), std::move(file)); + } + return Status::OK(); } Status ChromiumEnv::NewWritableFile(const std::string& fname, @@ -1001,11 +999,11 @@ Status ChromiumEnv::NewAppendableFile(const std::string& fname, leveldb::WritableFile** result) { + *result = nullptr; FilePath path = FilePath::FromUTF8Unsafe(fname); FileErrorOr<base::File> open_result = filesystem_->OpenFile( path, base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_APPEND); if (!open_result.has_value()) { - *result = nullptr; return MakeIOError(fname, "Unable to create appendable file", kNewAppendableFile, open_result.error()); }
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 8d59b58e..6f4480ae 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
@@ -621,6 +621,8 @@ summary="a mask to turn the maximize_restore button to zoom button"/> <entry name="center" value="64" summary="a customizable, center-aligned button"/> + <entry name="float" value="128" + summary="a button to float a window without maximize or restore"/> </enum> <request name="set_frame_buttons" since="1">
diff --git a/tools/accessibility/inspect/ax_dump_tree.cc b/tools/accessibility/inspect/ax_dump_tree.cc index 4d446f2..1f6f19b 100644 --- a/tools/accessibility/inspect/ax_dump_tree.cc +++ b/tools/accessibility/inspect/ax_dump_tree.cc
@@ -116,7 +116,7 @@ } auto server = - absl::make_unique<content::AXTreeServer>(*selector, *scenario, api); + std::make_unique<content::AXTreeServer>(*selector, *scenario, api); if (server->error) { return 1;
diff --git a/tools/binary_size/libsupersize/apkanalyzer.py b/tools/binary_size/libsupersize/apkanalyzer.py index 1c187ce2..d07657f 100644 --- a/tools/binary_size/libsupersize/apkanalyzer.py +++ b/tools/binary_size/libsupersize/apkanalyzer.py
@@ -345,7 +345,6 @@ symbols_bucket.sort(key=lambda s: s.full_name) return symbol_buckets - def _GenDexStringsUsedByClasses(dexfile, class_deobfuscation_map): """Emit strings used in code_items and associate them with classes. @@ -375,14 +374,12 @@ if not (name.startswith('L') and name.endswith(';')): num_bad_name += 1 return name - name = name[1:-1] + # Change "L{X};" to "{X}", and convert path name to class name. + name = name[1:-1].replace('/', '.') deobfuscated_name = class_deobfuscation_map.get(name, None) if deobfuscated_name is not None: name = deobfuscated_name num_deobfus_names += 1 - elif '/' in name: - # Has path: Assume not obfuscated, and convert to class name. - name = name.replace('/', '.') else: num_failed_deobfus += 1 return name
diff --git a/tools/gritsettings/resource_ids.spec b/tools/gritsettings/resource_ids.spec index 284c5f2..e929bcf 100644 --- a/tools/gritsettings/resource_ids.spec +++ b/tools/gritsettings/resource_ids.spec
@@ -258,7 +258,7 @@ "META": {"sizes": {"includes": [40]}}, "includes": [1740], }, - "<(SHARED_INTERMEDIATE_DIR)/chrome/browser/resources/nearby_share/nearby_share_dialog_resources.grd": { + "<(SHARED_INTERMEDIATE_DIR)/chrome/browser/resources/nearby_share/resources.grd": { "META": {"sizes": {"includes": [100]}}, "includes": [1760], },
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index c936d749..b5375e41 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -274,9 +274,10 @@ 'android-pie-arm64-rel-dev': 'android_release_bot_minimal_symbols_arm64_webview_monochrome_reclient', # These should be the same with 'Linux Builder'. + 'linux-local-ssd-rel-dev': 'gpu_tests_release_bot_do_typecheck_reclient', 'linux-rel-dev': 'gpu_tests_release_bot_do_typecheck_reclient', 'linux-rel-jammy-dev': 'gpu_tests_release_bot_do_typecheck_reclient', - 'linux-ssd-rel-dev': 'gpu_tests_release_bot_do_typecheck_reclient', + 'linux-remote-ssd-rel-dev': 'gpu_tests_release_bot_do_typecheck_reclient', # This should be the same with 'Mac Builder'. 'mac-arm-rel-dev': 'gpu_tests_release_bot_minimal_symbols_no_nacl_reclient', @@ -740,7 +741,9 @@ 'Linux Builder reclient staging': 'gpu_tests_release_bot_reclient', 'Linux Builder reclient staging untrusted': 'gpu_tests_release_bot_reclient', 'Linux Builder reclient test': 'gpu_tests_release_bot_reclient', + 'Linux Builder reclient test (unified uploads)': 'gpu_tests_release_bot_reclient', 'Linux Builder reclient test untrusted': 'gpu_tests_release_bot_reclient', + 'Linux Builder reclient test untrusted (unified uploads)': 'gpu_tests_release_bot_reclient', 'Mac Builder reclient staging': 'gpu_tests_release_bot_minimal_symbols_reclient', 'Mac Builder reclient staging untrusted': 'gpu_tests_release_bot_minimal_symbols_reclient', 'Mac Builder reclient test': 'gpu_tests_release_bot_minimal_symbols_reclient', @@ -970,24 +973,16 @@ 'lacros-arm-generic-chrome-skylab': 'chromeos_arm-generic_lacros_official_skylab', 'lacros-arm64-generic-chrome-skylab': 'chromeos_arm64-generic_lacros_official_skylab', 'linux-chrome': 'official_reclient', - 'linux-chrome-beta': 'official_reclient', - 'linux-chrome-stable': 'official_reclient', 'linux-chromeos-chrome': 'official_reclient_chromeos_include_unwind_tables', 'linux-chromeos-compile-chrome': 'official_reclient_chromeos_include_unwind_tables', 'linux-finch-smoke-chrome': 'official_reclient', 'mac-arm64-finch-smoke-chrome': 'official_reclient_mac_arm', 'mac-chrome': 'official_reclient_mac', - 'mac-chrome-beta': 'official_reclient_mac', - 'mac-chrome-stable': 'official_reclient_mac', 'win-branded-compile-rel': 'chrome_branded_reclient_minimal_symbols', 'win-celab-try-rel': 'official_celab_release_bot', 'win-chrome': 'official_reclient_x86', - 'win-chrome-beta': 'official_reclient_x86', - 'win-chrome-stable': 'official_reclient_x86', 'win-finch-smoke-chrome': 'official_reclient', 'win64-chrome': 'official_reclient_x64', - 'win64-chrome-beta': 'official_reclient_x64', - 'win64-chrome-stable': 'official_reclient_x64', }, 'tryserver.chrome.pgo': { @@ -1112,6 +1107,7 @@ 'chromeos-amd64-generic-dbg': 'chromeos_amd64-generic_dbg_reclient', 'chromeos-amd64-generic-lacros-dbg': 'chromeos_amd64-generic_lacros_dbg_reclient', 'chromeos-amd64-generic-rel': 'chromeos_amd64-generic_use_fake_dbus_clients_vm_optimized_dchecks_reclient', + 'chromeos-amd64-generic-rel-rts': 'chromeos_amd64-generic_use_fake_dbus_clients_vm_optimized_dchecks_reclient', 'chromeos-arm-generic-dbg': 'chromeos_arm-generic_dbg_try_reclient', 'chromeos-arm-generic-rel': 'chromeos_arm-generic_dcheck_always_on_reclient', 'chromeos-arm64-generic-rel': 'chromeos_arm64-generic_dchecks_reclient', @@ -1134,8 +1130,10 @@ 'linux-chromeos-dbg': 'chromeos_with_codecs_debug_bot_reclient', 'linux-chromeos-inverse-fieldtrials-fyi-rel': 'chromeos_with_codecs_release_trybot_invert_fieldtrials_reclient', 'linux-chromeos-rel': 'chromeos_with_codecs_release_trybot_code_coverage_reclient', + 'linux-chromeos-rel-rts': 'chromeos_with_codecs_release_trybot_code_coverage_reclient', 'linux-lacros-dbg': 'lacros_on_linux_debug_bot_reclient', 'linux-lacros-rel': 'lacros_on_linux_release_trybot_reclient', + 'linux-lacros-rel-rts': 'lacros_on_linux_release_trybot_reclient', }, 'tryserver.chromium.codesearch': {
diff --git a/tools/mb/mb_config_expectations/chromium.dev.json b/tools/mb/mb_config_expectations/chromium.dev.json index a66237c..0971beb 100644 --- a/tools/mb/mb_config_expectations/chromium.dev.json +++ b/tools/mb/mb_config_expectations/chromium.dev.json
@@ -15,6 +15,17 @@ "use_remoteexec": true } }, + "linux-local-ssd-rel-dev": { + "gn_args": { + "dcheck_always_on": false, + "devtools_skip_typecheck": false, + "ffmpeg_branding": "Chrome", + "is_component_build": false, + "is_debug": false, + "proprietary_codecs": true, + "use_remoteexec": true + } + }, "linux-rel-dev": { "gn_args": { "dcheck_always_on": false, @@ -37,7 +48,7 @@ "use_remoteexec": true } }, - "linux-ssd-rel-dev": { + "linux-remote-ssd-rel-dev": { "gn_args": { "dcheck_always_on": false, "devtools_skip_typecheck": false,
diff --git a/tools/mb/mb_config_expectations/chromium.reclient.fyi.json b/tools/mb/mb_config_expectations/chromium.reclient.fyi.json index 5f18e7a..d9c8fad 100644 --- a/tools/mb/mb_config_expectations/chromium.reclient.fyi.json +++ b/tools/mb/mb_config_expectations/chromium.reclient.fyi.json
@@ -87,6 +87,16 @@ "use_remoteexec": true } }, + "Linux Builder reclient test (unified uploads)": { + "gn_args": { + "dcheck_always_on": false, + "ffmpeg_branding": "Chrome", + "is_component_build": false, + "is_debug": false, + "proprietary_codecs": true, + "use_remoteexec": true + } + }, "Linux Builder reclient test untrusted": { "gn_args": { "dcheck_always_on": false, @@ -97,6 +107,16 @@ "use_remoteexec": true } }, + "Linux Builder reclient test untrusted (unified uploads)": { + "gn_args": { + "dcheck_always_on": false, + "ffmpeg_branding": "Chrome", + "is_component_build": false, + "is_debug": false, + "proprietary_codecs": true, + "use_remoteexec": true + } + }, "Mac Builder reclient staging": { "gn_args": { "dcheck_always_on": false,
diff --git a/tools/mb/mb_config_expectations/tryserver.chrome.json b/tools/mb/mb_config_expectations/tryserver.chrome.json index aa7ca9a1..34e520d 100644 --- a/tools/mb/mb_config_expectations/tryserver.chrome.json +++ b/tools/mb/mb_config_expectations/tryserver.chrome.json
@@ -368,20 +368,6 @@ "use_remoteexec": true } }, - "linux-chrome-beta": { - "gn_args": { - "is_chrome_branded": true, - "is_official_build": true, - "use_remoteexec": true - } - }, - "linux-chrome-stable": { - "gn_args": { - "is_chrome_branded": true, - "is_official_build": true, - "use_remoteexec": true - } - }, "linux-chromeos-chrome": { "gn_args": { "exclude_unwind_tables": false, @@ -426,22 +412,6 @@ "use_remoteexec": true } }, - "mac-chrome-beta": { - "gn_args": { - "ignore_missing_widevine_signing_cert": true, - "is_chrome_branded": true, - "is_official_build": true, - "use_remoteexec": true - } - }, - "mac-chrome-stable": { - "gn_args": { - "ignore_missing_widevine_signing_cert": true, - "is_chrome_branded": true, - "is_official_build": true, - "use_remoteexec": true - } - }, "win-branded-compile-rel": { "gn_args": { "dcheck_always_on": false, @@ -471,22 +441,6 @@ "use_remoteexec": true } }, - "win-chrome-beta": { - "gn_args": { - "is_chrome_branded": true, - "is_official_build": true, - "target_cpu": "x86", - "use_remoteexec": true - } - }, - "win-chrome-stable": { - "gn_args": { - "is_chrome_branded": true, - "is_official_build": true, - "target_cpu": "x86", - "use_remoteexec": true - } - }, "win-finch-smoke-chrome": { "gn_args": { "is_chrome_branded": true, @@ -501,21 +455,5 @@ "target_cpu": "x64", "use_remoteexec": true } - }, - "win64-chrome-beta": { - "gn_args": { - "is_chrome_branded": true, - "is_official_build": true, - "target_cpu": "x64", - "use_remoteexec": true - } - }, - "win64-chrome-stable": { - "gn_args": { - "is_chrome_branded": true, - "is_official_build": true, - "target_cpu": "x64", - "use_remoteexec": true - } } } \ 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 cc6a305..47bacb6 100644 --- a/tools/mb/mb_config_expectations/tryserver.chromium.chromiumos.json +++ b/tools/mb/mb_config_expectations/tryserver.chromium.chromiumos.json
@@ -46,6 +46,17 @@ "use_remoteexec": true } }, + "chromeos-amd64-generic-rel-rts": { + "args_file": "//build/args/chromeos/amd64-generic-vm.gni", + "gn_args": { + "also_build_lacros_chrome_for_architecture": "amd64", + "dcheck_always_on": true, + "is_chromeos_device": true, + "ozone_platform_headless": true, + "use_real_dbus_clients": false, + "use_remoteexec": true + } + }, "chromeos-arm-generic-dbg": { "args_file": "//build/args/chromeos/arm-generic.gni", "gn_args": { @@ -305,6 +316,24 @@ "use_remoteexec": true } }, + "linux-chromeos-rel-rts": { + "gn_args": { + "also_build_lacros_chrome": true, + "coverage_instrumentation_input_file": "//.code-coverage/files_to_instrument.txt", + "dcheck_always_on": true, + "enable_backup_ref_ptr_feature_flag": true, + "enable_dangling_raw_ptr_checks": true, + "enable_dangling_raw_ptr_feature_flag": true, + "ffmpeg_branding": "ChromeOS", + "is_component_build": false, + "is_debug": false, + "proprietary_codecs": true, + "symbol_level": 0, + "target_os": "chromeos", + "use_clang_coverage": true, + "use_remoteexec": true + } + }, "linux-lacros-dbg": { "gn_args": { "also_build_ash_chrome": true, @@ -327,5 +356,17 @@ "target_os": "chromeos", "use_remoteexec": true } + }, + "linux-lacros-rel-rts": { + "gn_args": { + "also_build_ash_chrome": true, + "chromeos_is_browser_only": true, + "dcheck_always_on": true, + "is_component_build": false, + "is_debug": false, + "symbol_level": 0, + "target_os": "chromeos", + "use_remoteexec": true + } } } \ No newline at end of file
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 1a0ca38..99dcad4 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -42146,6 +42146,7 @@ <int value="4544" label="TextWrapBalance"/> <int value="4545" label="TextWrapBalanceFail"/> <int value="4546" label="AttributionReportingCrossAppWeb"/> + <int value="4547" label="SecurePaymentConfirmationActivationlessShow"/> </enum> <enum name="FeaturePolicyAllowlistType"> @@ -53565,15 +53566,6 @@ <int value="12" label="AccessibilityExtraExtraExtraLarge"/> </enum> -<enum name="IOSContentSuggestionsActionType"> - <int value="0" label="Most Visited Tiles"/> - <int value="1" label="Shortcuts"/> - <int value="2" label="Return to Recent Tab tile"/> - <int value="3" label="Feed Card"/> - <int value="4" label="Fake Omnibox"/> - <int value="5" label="Trending Queries"/> -</enum> - <enum name="iOSCredentialIdentityStoreErrorForReporting"> <int value="0" label="Unknown Error"/> <int value="1" label="Internal Error"/> @@ -53747,6 +53739,14 @@ <int value="2" label="Chrome on Mac"/> </enum> +<enum name="IOSHomeActionType"> + <int value="0" label="Most Visited Tiles"/> + <int value="1" label="Shortcuts"/> + <int value="2" label="Return to Recent Tab tile"/> + <int value="3" label="Feed Card"/> + <int value="4" label="Fake Omnibox"/> +</enum> + <enum name="IOSInspectConsoleAction"> <int value="0" label="Start Logging"/> <int value="1" label="Stop Logging"/> @@ -80226,6 +80226,19 @@ <int value="3" label="Federated match"/> </enum> +<enum name="PasswordManagerShortcutInteractions"> + <int value="0" label="Import dialog opened from the three-dot menu."/> + <int value="1" label="Import dialog opened from the empty passwords list."/> + <int value="2" label="Import flow canceled before the file selection."/> +</enum> + +<enum name="PasswordManagerShortcutMetric"> + <int value="0" label="User clicked Add shortcut from the UI."/> + <int value="1" label="Shortcut was successfully installed."/> + <int value="2" + label="User switched profile in the standalone password manager app."/> +</enum> + <enum name="PasswordManagerShowEmptyUsername"> <int value="0" label="Non-empty username"/> <int value="1" label="Empty username"/> @@ -80624,6 +80637,13 @@ <int value="0" label="Import dialog opened from the three-dot menu."/> <int value="1" label="Import dialog opened from the empty passwords list."/> <int value="2" label="Import flow canceled before the file selection."/> + <int value="3" label="UPM: Store picker dialog opened."/> + <int value="4" label="UPM: Select file launched."/> + <int value="5" label="UPM: View passwords clicked after successful import."/> + <int value="6" label="Conflicts: Dialog canceled."/> + <int value="7" label="Conflicts: Re-auth failed."/> + <int value="8" label="Conflicts: Skip button clicked."/> + <int value="9" label="Conflicts: Replace button clicked."/> </enum> <enum name="PasswordStoreAndroidBackendAPIError"> @@ -113096,6 +113116,7 @@ <int value="55" label="Trigger Lacros data migration"/> <int value="56" label="Menu opened"/> <int value="57" label="Visited Chrome Web Store via extensions sub menu."/> + <int value="58" label="Password Manager"/> </enum> <enum name="WrongConfigurationMetric">
diff --git a/tools/metrics/histograms/metadata/histogram_suffixes_list.xml b/tools/metrics/histograms/metadata/histogram_suffixes_list.xml index 38d07e2..2365fb34 100644 --- a/tools/metrics/histograms/metadata/histogram_suffixes_list.xml +++ b/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
@@ -6033,6 +6033,7 @@ <suffix name="OpenBookmark" label=""/> <suffix name="OpenInChrome" label=""/> <suffix name="OpenRecentTab" label=""/> + <suffix name="PasswordManager" label=""/> <suffix name="Paste" label=""/> <suffix name="PinToStartScreen" label=""/> <suffix name="Print" label=""/>
diff --git a/tools/metrics/histograms/metadata/ios/histograms.xml b/tools/metrics/histograms/metadata/ios/histograms.xml index 8407568a..8450c27 100644 --- a/tools/metrics/histograms/metadata/ios/histograms.xml +++ b/tools/metrics/histograms/metadata/ios/histograms.xml
@@ -231,24 +231,6 @@ </summary> </histogram> -<histogram name="IOS.ContentSuggestions.ActionOnNTP" - enum="IOSContentSuggestionsActionType" expires_after="2023-10-08"> - <owner>thegreenfrog@chromium.org</owner> - <owner>bling-team@google.com</owner> - <summary> - When the user taps on a Content Suggestions Module on the NTP Surface. - </summary> -</histogram> - -<histogram name="IOS.ContentSuggestions.ActionOnStartSurface" - enum="IOSContentSuggestionsActionType" expires_after="2023-10-08"> - <owner>thegreenfrog@chromium.org</owner> - <owner>bling-team@google.com</owner> - <summary> - When the user taps on a Content Suggestions Module on the Start Surface. - </summary> -</histogram> - <histogram name="IOS.CredentialExtension.ConsentVerifiedCount" units="count" expires_after="2023-08-13"> <owner>ginnyhuang@chromium.org</owner> @@ -989,6 +971,25 @@ </summary> </histogram> +<histogram name="IOS.Home.ActionOnNTP" enum="IOSHomeActionType" + expires_after="2023-10-08"> + <owner>thegreenfrog@chromium.org</owner> + <owner>bling-team@google.com</owner> + <summary> + This histogram is logged whenever a Home action is taken on the NTP. + </summary> +</histogram> + +<histogram name="IOS.Home.ActionOnStartSurface" enum="IOSHomeActionType" + expires_after="2023-10-08"> + <owner>thegreenfrog@chromium.org</owner> + <owner>bling-team@google.com</owner> + <summary> + This histogram is logged whenever a Home action is taken on the Start + surface. + </summary> +</histogram> + <histogram name="IOS.InactiveTabs.Settings.Threshold" enum="InactiveTabsThresholdSettingType" expires_after="2023-10-19"> <owner>alionadangla@chromium.org</owner> @@ -1919,7 +1920,7 @@ </histogram> <histogram name="IOS.ReconcileEULAPref" enum="Boolean" - expires_after="2023-04-27"> + expires_after="2024-04-24"> <owner>olivierrobin@google.com</owner> <owner>rohitrao@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/notifications/histograms.xml b/tools/metrics/histograms/metadata/notifications/histograms.xml index d22dc5d..67e3e1f 100644 --- a/tools/metrics/histograms/metadata/notifications/histograms.xml +++ b/tools/metrics/histograms/metadata/notifications/histograms.xml
@@ -505,6 +505,9 @@ <histogram name="Notifications.macOS.Delivered.{Style}" enum="BooleanSuccess" expires_after="M96"> + <obsolete> + Obsoleted April 2023. Histogram was removed after expiration. + </obsolete> <owner>knollr@chromium.org</owner> <owner>peter@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/password/histograms.xml b/tools/metrics/histograms/metadata/password/histograms.xml index 7d4afab..1ff273b 100644 --- a/tools/metrics/histograms/metadata/password/histograms.xml +++ b/tools/metrics/histograms/metadata/password/histograms.xml
@@ -1741,6 +1741,18 @@ </token> </histogram> +<histogram name="PasswordManager.Import.PerFile.ConflictsResolved" + units="saved credentials" expires_after="2023-09-30"> + <owner>eliaskh@chromium.org</owner> + <owner>natiahlyi@google.com</owner> + <summary> + Records number of passwords that were resolved in Passwords Import - + Conflict resolution. Basically the number of conflicting passwords that were + selected to be imported. Recorded during the passwords import process + triggered from settings, after the user clicks on the Repalce button. + </summary> +</histogram> + <histogram name="PasswordManager.Import.PerFile.Notes.{Type}" units="units" expires_after="2023-09-15"> <owner>eliaskh@chromium.org</owner> @@ -1886,7 +1898,7 @@ </summary> </histogram> -<histogram name="PasswordManager.IsPasswordProtected" enum="Boolean" +<histogram name="PasswordManager.IsPasswordProtected2" enum="Boolean" expires_after="2024-03-01"> <owner>skrakowi@chromium.org</owner> <owner>chrome-counter-abuse-alerts@google.com</owner> @@ -3358,6 +3370,17 @@ </summary> </histogram> +<histogram name="PasswordManager.ShortcutMetric" + enum="PasswordManagerShortcutMetric" expires_after="2023-10-15"> + <owner>vasilii@chromium.org</owner> + <owner>vsemeniuk@google.com</owner> + <summary> + Records the user actions related to password manager shortcut. Recorded + before showing install prompt, after successful installation, or when user + switched profile inside a shortcut. + </summary> +</histogram> + <histogram name="PasswordManager.SingleUsername.PasswordFormHadUsernameField" enum="PasswordFormHadUsernameField" expires_after="2023-11-28"> <owner>kolos@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/stability/histograms.xml b/tools/metrics/histograms/metadata/stability/histograms.xml index ba1d9728a..a764259 100644 --- a/tools/metrics/histograms/metadata/stability/histograms.xml +++ b/tools/metrics/histograms/metadata/stability/histograms.xml
@@ -512,7 +512,7 @@ </histogram> <histogram name="Stability.iOS.UTE.MobileSessionOOMShutdownHint" - enum="OOMShutdownHint" expires_after="2023-04-27"> + enum="OOMShutdownHint" expires_after="2024-04-24"> <owner>olivierrobin@chromium.org</owner> <owner>sdefresne@chromium.org</owner> <summary>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index cd2afac..00b98ac 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -5,24 +5,24 @@ "full_remote_path": "perfetto-luci-artifacts/adbbb6c78e3a86c5e87b0338d9e42eb6b4ddbf4d/linux-arm64/trace_processor_shell" }, "win": { - "hash": "cc6d19a6fb0c99669fb25b6706c0bc86f1556fc2", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/5667b7e9bbc8c1c3bc403cde47ce1460e3f624f9/trace_processor_shell.exe" + "hash": "963dfb9e6dde58df884a2210c7dac4d74c36d3e8", + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/5437caf87b2d6711ead7eef50c762fd1114e7ef9/trace_processor_shell.exe" }, "linux_arm": { "hash": "1d229abc94dea54ab4bb4327e78e18f942d08bf9", "full_remote_path": "perfetto-luci-artifacts/adbbb6c78e3a86c5e87b0338d9e42eb6b4ddbf4d/linux-arm/trace_processor_shell" }, "mac": { - "hash": "6df87806b47586b1b71d9aff54a271b835f609d6", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/df2191d9cee86c9ccdbaf7e33e7c2b4827e40631/trace_processor_shell" + "hash": "b05dc5f4284bdb5c41c23ed084a16e64343d7389", + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/934a4a6572827e1e911fa214556906e6520f23bf/trace_processor_shell" }, "mac_arm64": { "hash": "7a4026b8718994145a52586fdec6e9447573345a", "full_remote_path": "perfetto-luci-artifacts/adbbb6c78e3a86c5e87b0338d9e42eb6b4ddbf4d/mac-arm64/trace_processor_shell" }, "linux": { - "hash": "f72f66b242c5dffb0e5baa99e890652f1e01b820", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/5667b7e9bbc8c1c3bc403cde47ce1460e3f624f9/trace_processor_shell" + "hash": "dd8ace566651e1a986bfa4e57191d24817fe549c", + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/5437caf87b2d6711ead7eef50c762fd1114e7ef9/trace_processor_shell" } }, "power_profile.sql": {
diff --git a/ui/accessibility/ax_node.cc b/ui/accessibility/ax_node.cc index 7085cc6..316c7b6 100644 --- a/ui/accessibility/ax_node.cc +++ b/ui/accessibility/ax_node.cc
@@ -1751,6 +1751,7 @@ case ax::mojom::Role::kTabList: return item_role == ax::mojom::Role::kTab; case ax::mojom::Role::kTree: + case ax::mojom::Role::kTreeItem: return item_role == ax::mojom::Role::kTreeItem; case ax::mojom::Role::kListBox: return item_role == ax::mojom::Role::kListBoxOption;
diff --git a/ui/accessibility/ax_node_unittest.cc b/ui/accessibility/ax_node_unittest.cc index bc39008..b593a53 100644 --- a/ui/accessibility/ax_node_unittest.cc +++ b/ui/accessibility/ax_node_unittest.cc
@@ -993,4 +993,57 @@ EXPECT_EQ(tree.GetFromId(6)->GetSetSize(), 2); } +TEST(AXNodeTest, TreeItemAsTreeItemParentPosInSetSetSize) { + TestAXTreeUpdate update(std::string(R"HTML( + ++1 kRootWebArea + ++++2 kTree + ++++++3 kTreeItem intAttribute=kPosInSet,1 intAttribute=kSetSize,2 + ++++++++4 kTreeItem intAttribute=kPosInSet,1 intAttribute=kSetSize,6 + ++++++++5 kTreeItem intAttribute=kPosInSet,2 intAttribute=kSetSize,6 + ++++++6 kTreeItem intAttribute=kPosInSet,2 intAttribute=kSetSize,2 + ++++++++7 kTreeItem intAttribute=kPosInSet,3 intAttribute=kSetSize,6 + )HTML")); + + AXTree tree(update); + + EXPECT_EQ(tree.GetFromId(3)->GetPosInSet(), 1); + EXPECT_EQ(tree.GetFromId(3)->GetSetSize(), 2); + + EXPECT_EQ(tree.GetFromId(4)->GetPosInSet(), 1); + EXPECT_EQ(tree.GetFromId(4)->GetSetSize(), 6); + + EXPECT_EQ(tree.GetFromId(5)->GetPosInSet(), 2); + EXPECT_EQ(tree.GetFromId(5)->GetSetSize(), 6); + + EXPECT_EQ(tree.GetFromId(6)->GetPosInSet(), 2); + EXPECT_EQ(tree.GetFromId(6)->GetSetSize(), 2); + + EXPECT_EQ(tree.GetFromId(7)->GetPosInSet(), 3); + EXPECT_EQ(tree.GetFromId(7)->GetSetSize(), 6); +} + +TEST(AXNodeTest, GroupAsTreeItemParentPosInSetSetSize) { + TestAXTreeUpdate update(std::string(R"HTML( + ++1 kRootWebArea + ++++2 kTree + ++++++3 kGroup + ++++++++4 kTreeItem intAttribute=kPosInSet,1 intAttribute=kSetSize,6 + ++++++++5 kTreeItem intAttribute=kPosInSet,2 intAttribute=kSetSize,6 + ++++++6 kTreeItem + ++++++++7 kGroup + ++++++++++8 kTreeItem intAttribute=kPosInSet,1 intAttribute=kSetSize,6 + )HTML")); + + AXTree tree(update); + + EXPECT_EQ(tree.GetFromId(4)->GetPosInSet(), 1); + EXPECT_EQ(tree.GetFromId(4)->GetSetSize(), 6); + + EXPECT_EQ(tree.GetFromId(5)->GetPosInSet(), 2); + EXPECT_EQ(tree.GetFromId(5)->GetSetSize(), 6); + + EXPECT_EQ(tree.GetFromId(8)->GetPosInSet(), 1); + EXPECT_EQ(tree.GetFromId(8)->GetSetSize(), 6); +} + } // namespace ui
diff --git a/ui/accessibility/mojom/ax_action_data_mojom_traits.cc b/ui/accessibility/mojom/ax_action_data_mojom_traits.cc index 22a5c6c..148f25f 100644 --- a/ui/accessibility/mojom/ax_action_data_mojom_traits.cc +++ b/ui/accessibility/mojom/ax_action_data_mojom_traits.cc
@@ -10,12 +10,21 @@ bool StructTraits<ax::mojom::AXActionDataDataView, ui::AXActionData>::Read( ax::mojom::AXActionDataDataView data, ui::AXActionData* out) { - if (!data.ReadAction(&out->action)) + if (!data.ReadAction(&out->action)) { return false; - if (!data.ReadTargetTreeId(&out->target_tree_id)) + } + if (out->action == ax::mojom::Action::kNone) { + // This might happen with version skew: an action that doesn't + // have a mapping is converted to the default value, kNone. In this case + // we cannot process the action properly. return false; - if (!data.ReadSourceExtensionId(&out->source_extension_id)) + } + if (!data.ReadTargetTreeId(&out->target_tree_id)) { return false; + } + if (!data.ReadSourceExtensionId(&out->source_extension_id)) { + return false; + } out->target_node_id = data.target_node_id(); out->request_id = data.request_id(); out->flags = data.flags();
diff --git a/ui/accessibility/mojom/ax_action_data_mojom_traits.h b/ui/accessibility/mojom/ax_action_data_mojom_traits.h index 02d75a52..ad997e5 100644 --- a/ui/accessibility/mojom/ax_action_data_mojom_traits.h +++ b/ui/accessibility/mojom/ax_action_data_mojom_traits.h
@@ -65,6 +65,9 @@ return a.scroll_behavior; } + // Returns false if `data` could not be read into `out`, which may occur if + // `data` was created using newer versions of enums than `out` supports, + // or if some other value cannot be read. static bool Read(ax::mojom::AXActionDataDataView data, ui::AXActionData* out); };
diff --git a/ui/ozone/platform/wayland/host/wayland_toplevel_window.cc b/ui/ozone/platform/wayland/host/wayland_toplevel_window.cc index ec40983..218366b 100644 --- a/ui/ozone/platform/wayland/host/wayland_toplevel_window.cc +++ b/ui/ozone/platform/wayland/host/wayland_toplevel_window.cc
@@ -385,6 +385,11 @@ return screen_coordinates_enabled_; } +bool WaylandToplevelWindow::SupportsConfigureMinimizedState() const { + return shell_toplevel_ && shell_toplevel_->IsSupportedOnAuraToplevel( + ZAURA_TOPLEVEL_STATE_MINIMIZED_SINCE_VERSION); +} + void WaylandToplevelWindow::UpdateWindowScale(bool update_bounds) { auto old_scale = applied_state().window_scale; WaylandWindow::UpdateWindowScale(update_bounds); @@ -412,8 +417,7 @@ // Store the old state to propagte state changes if Wayland decides to change // the state to something else. PlatformWindowState old_state = state_; - if ((!IsSupportedOnAuraSurface( - ZAURA_TOPLEVEL_STATE_MINIMIZED_SINCE_VERSION) && + if ((!SupportsConfigureMinimizedState() && state_ == PlatformWindowState::kMinimized && !window_states.is_activated) || window_states.is_minimized) { @@ -775,7 +779,8 @@ void WaylandToplevelWindow::ShowSnapPreview( WaylandWindowSnapDirection snap_direction, bool allow_haptic_feedback) { - if (IsSupportedOnAuraSurface(ZAURA_TOPLEVEL_INTENT_TO_SNAP_SINCE_VERSION)) { + if (shell_toplevel_ && shell_toplevel_->IsSupportedOnAuraToplevel( + ZAURA_TOPLEVEL_INTENT_TO_SNAP_SINCE_VERSION)) { shell_toplevel_->ShowSnapPreview(snap_direction, allow_haptic_feedback); return; } @@ -803,26 +808,20 @@ void WaylandToplevelWindow::CommitSnap( WaylandWindowSnapDirection snap_direction, float snap_ratio) { - if (shell_toplevel_ && shell_toplevel_->IsSupportedOnAuraToplevel( - ZAURA_TOPLEVEL_UNSET_SNAP_SINCE_VERSION)) { + // If aura_toplevel does not support `WaylandWindowSnapDirection::kNone` let + // it fallthrough to `zaura_surface_unset_snap()`. + const bool use_shell_toplevel = + shell_toplevel_ && + (shell_toplevel_->IsSupportedOnAuraToplevel( + ZAURA_TOPLEVEL_UNSET_SNAP_SINCE_VERSION) || + (snap_direction != WaylandWindowSnapDirection::kNone && + shell_toplevel_->IsSupportedOnAuraToplevel( + ZAURA_TOPLEVEL_SET_SNAP_PRIMARY_SINCE_VERSION))); + if (use_shell_toplevel) { shell_toplevel_->CommitSnap(snap_direction, snap_ratio); return; } - if (shell_toplevel_ && shell_toplevel_->IsSupportedOnAuraToplevel( - ZAURA_TOPLEVEL_SET_SNAP_PRIMARY_SINCE_VERSION)) { - switch (snap_direction) { - case WaylandWindowSnapDirection::kNone: - // Toplevel does not support `WaylandWindowSnapDirection::kNone` yet. - // Let it fallthrough to `zaura_surface_unset_snap()`. - break; - case WaylandWindowSnapDirection::kPrimary: - case WaylandWindowSnapDirection::kSecondary: - shell_toplevel_->CommitSnap(snap_direction, snap_ratio); - return; - } - } - if (IsSupportedOnAuraSurface(ZAURA_SURFACE_UNSET_SNAP_SINCE_VERSION)) { switch (snap_direction) { case WaylandWindowSnapDirection::kPrimary:
diff --git a/ui/ozone/platform/wayland/host/wayland_toplevel_window.h b/ui/ozone/platform/wayland/host/wayland_toplevel_window.h index d7edcb2..9e136e3 100644 --- a/ui/ozone/platform/wayland/host/wayland_toplevel_window.h +++ b/ui/ozone/platform/wayland/host/wayland_toplevel_window.h
@@ -83,6 +83,7 @@ bool IsActive() const override; void SetWindowGeometry(gfx::Size size_dip) override; bool IsScreenCoordinatesEnabled() const override; + bool SupportsConfigureMinimizedState() const override; void ShowTooltip(const std::u16string& text, const gfx::Point& position, const PlatformWindowTooltipTrigger trigger,
diff --git a/ui/ozone/platform/wayland/host/wayland_window.cc b/ui/ozone/platform/wayland/host/wayland_window.cc index a199117..3fa3351 100644 --- a/ui/ozone/platform/wayland/host/wayland_window.cc +++ b/ui/ozone/platform/wayland/host/wayland_window.cc
@@ -329,6 +329,10 @@ std::move(subsurfaces_to_overlays))); } +bool WaylandWindow::SupportsConfigureMinimizedState() const { + return false; +} + void WaylandWindow::SetAuraSurface(zaura_surface* aura_surface) { DCHECK(connection()->zaura_shell()); DCHECK_NE(aura_surface_.get(), aura_surface);
diff --git a/ui/ozone/platform/wayland/host/wayland_window.h b/ui/ozone/platform/wayland/host/wayland_window.h index 3186b74..01bfa9d 100644 --- a/ui/ozone/platform/wayland/host/wayland_window.h +++ b/ui/ozone/platform/wayland/host/wayland_window.h
@@ -332,6 +332,9 @@ // Returns true if the window's bounds is in screen coordinates. virtual bool IsScreenCoordinatesEnabled() const; + // Returns true if this window's configure state supports the minimized state. + virtual bool SupportsConfigureMinimizedState() const; + scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner() { return ui_task_runner_; }
diff --git a/ui/ozone/platform/wayland/host/wayland_window_unittest.cc b/ui/ozone/platform/wayland/host/wayland_window_unittest.cc index 79c23ce2..6e6c08f 100644 --- a/ui/ozone/platform/wayland/host/wayland_window_unittest.cc +++ b/ui/ozone/platform/wayland/host/wayland_window_unittest.cc
@@ -904,8 +904,7 @@ window_->HandleSurfaceConfigure(3); EXPECT_EQ(PlatformWindowState::kMinimized, window_->GetPlatformWindowState()); - if (window_->IsSupportedOnAuraSurface( - ZAURA_TOPLEVEL_STATE_MINIMIZED_SINCE_VERSION)) { + if (window_->SupportsConfigureMinimizedState()) { // If the minimized state is supported via the zaura extension, while // minimized a restore event from the server should return the window to the // normal state.